Capability Delegation

Draft Community Group Report,

This version:
https://wicg.github.io/capability-delegation/spec.html
Issue Tracking:
GitHub
Editor:
(Google Canada)

Abstract

Transferring the ability to use restricted APIs to another window.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

This section is non-normative.

This specification defines a mechanism through which a script can delegate its ability to call a restricted API to another browsing context it trusts. The focus here is a dynamic delegation mechanism that exposes the delegated capability to the target browsing context in a time-constrained manner.

1.1. What is capability delegation?

Many capabilities in the Web are usable from JS in restricted manners. For example:

Capability delegation means allowing a frame to dynamically relinquish its ability to call a restricted API and transfer the ability to another (sub)frame it can trust. The word "dynamic" here means the effect of the delegation lasts for a limited time as defined by the capability being delegated. This is different from static (load-time) exposure of a capability to a browsing context through iframe allow attribute where the capability becomes exposed to a subframe in a time-unconstrained manner.

1.2. Initiating a delegation vs using a capability

Capability delegation needs two distinct steps to be effective. The first step is "initiation" where one browsing context notifies another browsing context about a specific capability being delegated. After initiation, the second (i.e. the receiver) browsing context would "use" the delegated capability, which typically means calling a capability-defined method. While the capability delegation specification here does not define the API interface used in the second step, it redefines the API’s internal behavior.

Because of this, this specification consists of two distinct parts: defining an API for the initiation step, and then defining delegated behavior for one specific "user" API. For the second part, this specification focuses on behavior changes needed in Payment Request API, which would serve as a guide for similar changes in any other APIs that would utilize capability delegation in future.

1.3. Transient availability

Both the steps mentioned above are time-constrained in nature. The initiation step is activation consuming, so the step is allowed only after a recent user activation. After successful completion of this step, the delegated API becomes available for use for a few seconds (to be precise, the same limit as activation expiry unless the limit is defined otherwise by the specification of the delegated API.

2. Examples

When a site wants to delegate the capability to call [payment-request] show() from a subframe after a mouse click, it will post a message to the subframe with an additional option to specify the delegated capability:
  window.onclick = () => {
    targetWindow.postMessage('a_message', {delegate: "payment"});
  };

Upon receiving the message, the subframe would be able to use show() even though the frame hasn’t received a user activation:

  window.onmessage = () => {
    const payRequest = new PaymentRequest(...);
    const payResponse = await payRequest.show();
    ...
  }

3. Initiating capability delegation

When a browsing context wants to delegate a capability to another browsing context, it posts a message to the second browsing context with an extra WindowPostMessageOptions called delegate specifying the capability. The value of this option MUST be a feature-identifier. The option MUST be ignored if the value does not correspond to any features supported by the user agent.

A list of possible feature-identifier values appears here.

3.1. Monkey-patch to HTML spec

The WindowPostMessageOptions IDL definition will include an additional field as follows:

  DOMString delegate = "";

In the algorithm for window post message, the following step:

  1. Let transfer be options["transfer"].

will be followed by two additional steps as follows:

  1. Let delegate be options["delegate"].

  2. If delegate is not null, then:

    1. If targetWindow has transient activation, then consume user activation in targetWindow.

    2. Otherwise, let delegate be null.

4. Tracking delegated capability

Capabilities delegated to a browsing context will be tracked using a map named Window.DELEGATED_CAPABILITY_TIMESTAMPS. Each time a capability is delegated to a Window, an entry will be added in DELEGATED_CAPABILITY_TIMESTAMPS with a key equal to the feature-identifier representing the capability, and a value equal to current DOMHighResTimeStamp. If the map already has an entry for the same key, the existing value will be updated to current DOMHighResTimeStamp.

4.1. Monkey-patch to HTML spec

Right before the algorithm for window post message, a new paragraph will be inserted, as follow:

For the purpose of tracking capabilities delegated to a browsing context, each Window has a map called DELEGATED_CAPABILITY_TIMESTAMPS from feature-identifier to DOMHighResTimeStamp. The map is initialized with an empty map.

In the algorithm for window post message, two additional sub-steps will be added to current Step 8. The first additional sub-step will be inserted after the following sub-step:

  1. Queue a global task ...

    1. Let origin be the serialization of incumbentSettings’s origin.

as follows:

  1. Queue a global task ... (unchanged)

    1. Let delegate be options["delegate"].

The second additional sub-step will be inserted after the following sub-step:

  1. Queue a global task ...

    1. Let newPorts be a new frozen array consisting of ...

as follows:

  1. Queue a global task ... (unchanged)

    1. Let newPorts be a new frozen array consisting of ... (unchanged except for numbering)

    2. If delegate is not null, AND the user agent supports delegating delegate, then set DELEGATED_CAPABILITY_TIMESTAMPS[delegate] to current high resolution time.

5. Defining delegated capability behavior

Any capability that defines a delegated behavior uses the corresponding entry in Window.DELEGATED_CAPABILITY_TIMESTAMPS in a manner appropriate for the capability. Below is the spec change needed for one particular capability.

5.1. Monkey-patch to Payment Request spec

In the algorithm for show(), the following steps will be replaced to implement the delegated behavior:

The two steps:

  1. If the relevant global object of request does not have transient activation, return a promise rejected with with a "NotAllowedError" DOMException.

  2. Consume user activation of the relevant global object.

will be replaced by the following three steps:

  1. If the relevant global object of request does not have transient activation, AND the timestamp DELEGATED_CAPABILITY_TIMESTAMPS["payment"] in the relevant global object is either undefined or expired, then return a promise rejected with with a "NotAllowedError" DOMException.

  2. If the relevant global object of request does not have transient activation, then clear the map entry DELEGATED_CAPABILITY_TIMESTAMPS["payment"].

  3. Otherwise, consume user activation of the relevant global object.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[HR-TIME-2]
Ilya Grigorik. High Resolution Time Level 2. 21 November 2019. REC. URL: https://www.w3.org/TR/hr-time-2/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PAYMENT-REQUEST]
Marcos Caceres; et al. Payment Request API. 3 December 2020. CR. URL: https://www.w3.org/TR/payment-request/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119

Informative References

[FULLSCREEN]
Philip Jägenstedt. Fullscreen API Standard. Living Standard. URL: https://fullscreen.spec.whatwg.org/