├── .github └── workflows │ └── auto-publish.yml ├── .gitignore ├── .pr-preview.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── document-policy.redirect.html ├── features.md ├── index.bs ├── integration.md ├── permissions-policy-client-hints.md ├── permissions-policy-explainer.md ├── policies ├── README.md ├── animations.md ├── decoding-image-default-sync.md ├── document-write.md ├── focus-without-user-activation.md ├── font-display-late-swap.md ├── loading-frame-default-eager.md ├── loading-image-default-eager.md ├── optimized-images.md ├── resources │ ├── image-compression-disabled.png │ ├── image-compression-enabled.png │ ├── legacy-image-formats-disabled.png │ ├── legacy-image-formats-enabled.png │ ├── max-ds-img-disabled0.png │ ├── max-ds-img-disabled1.png │ ├── max-ds-img-disabled2.png │ ├── max-ds-img-enabled0.png │ ├── max-ds-img-enabled1.png │ ├── max-ds-img-enabled2.png │ ├── unoptimized-disabled.png │ ├── unoptimized-enabled.png │ ├── unsized-media-disabled1.png │ ├── unsized-media-disabled2.png │ ├── unsized-media-enabled1.png │ ├── unsized-media-enabled2.png │ └── unsized-media-example0.png ├── unsized-media.md └── vertical_scroll.md ├── reporting.md ├── sandbox.md ├── security-privacy-questionnaire-document-policies.md ├── security-privacy-questionnaire-introspection.md ├── security-privacy-questionnaire-reporting.md ├── security-privacy-questionnaire-sandbox.md ├── security-privacy-questionnaire.md ├── tidyconfig.txt └── w3c.json /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: {} 4 | push: 5 | branches: [main] 6 | jobs: 7 | main: 8 | name: Build, Validate and Deploy 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: w3c/spec-prod@v2 13 | with: 14 | GH_PAGES_BRANCH: gh-pages 15 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 16 | W3C_WG_DECISION_URL: https://lists.w3.org/Archives/Public/public-webappsec/2015Mar/0170.html 17 | W3C_BUILD_OVERRIDE: | 18 | Status: WD 19 | shortname: permissions-policy 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | index.html 2 | deploy_key 3 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.bs", 3 | "type": "bikeshed" 4 | } 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Web Platform Incubator Community Group 2 | 3 | This repository is being used for work in the Web Platform Incubator Community Group, governed by the [W3C Community License 4 | Agreement (CLA)](http://www.w3.org/community/about/agreements/cla/). To contribute, you must join 5 | the CG. 6 | 7 | If you are not the sole contributor to a contribution (pull request), please identify all 8 | contributors in the pull request's body or in subsequent comments. 9 | 10 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 11 | 12 | ``` 13 | +@github_username 14 | ``` 15 | 16 | If you added a contributor by mistake, you can remove them in a comment with: 17 | 18 | ``` 19 | -@github_username 20 | ``` 21 | 22 | If you are making a pull request on behalf of someone else but you had no part in designing the 23 | feature, you can remove yourself with the above syntax. 24 | 25 | # Tests 26 | 27 | For normative changes, a corresponding 28 | [web-platform-tests](https://github.com/web-platform-tests/wpt) PR is highly appreciated. Typically, 29 | both PRs will be merged at the same time. Note that a test change that contradicts the spec should 30 | not be merged before the corresponding spec change. If testing is not practical, please explain why 31 | and if appropriate [file a web-platform-tests issue](https://github.com/web-platform-tests/wpt/issues/new) 32 | to follow up later. Add the `type:untestable` or `type:missing-coverage` label as appropriate. 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All Reports in this Repository are licensed by Contributors under the 2 | [W3C Software and Document 3 | License](http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document). Contributions to 4 | Specifications are made under the [W3C CLA](https://www.w3.org/community/about/agreements/cla/). 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Permissions Policy (previously named Feature Policy) 2 | 3 | A web platform API which gives a website the ability to allow and deny the use of browser features in its own frame, and in iframes that it embeds. Examples of [features](https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md) that could be controlled by permissions policy include: 4 | 5 | - getUserMedia (Camera, Microphone, and Speaker-selection) 6 | - Fullscreen 7 | - Geolocation 8 | - MIDI 9 | - Payments 10 | - Synchronous XHR 11 | - ... 12 | 13 | See also: [how to integrate a web platform feature with permissions policy](https://github.com/w3c/webappsec-permissions-policy/blob/master/integration.md). 14 | 15 | The Permissions Policy spec is hosted on this repo, at https://w3c.github.io/webappsec-permissions-policy/ 16 | 17 | For more explanation, use cases, examples, etc., please refer to [the explainer document](https://github.com/w3c/webappsec-permissions-policy/blob/master/permissions-policy-explainer.md). 18 | 19 | ## Where is Document Policy? 20 | 21 | Document Policy, which was previously hosted here, has been moved to WICG; it can be found at https://github.com/WICG/document-policy/. 22 | 23 | 24 | Questions, suggestions? Please open an issue or send a pull request! 25 | -------------------------------------------------------------------------------- /document-policy.redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Document Policy has moved 4 |

The Document Policy spec, previously hosted at this URL, has moved to WICG. 5 | It can now be found at https://wicg.github.io/document-policy/. 6 | The repository is here 7 | 8 |

This page will automatically redirect to the new location in a few seconds. 9 | -------------------------------------------------------------------------------- /features.md: -------------------------------------------------------------------------------- 1 | # Policy Controlled Features 2 | 3 | This document lists policy-controlled features being implemented in browsers. It 4 | is broken into sections based on the standardization state of each feature. The 5 | names used here should be consistent between browsers implementing a particular 6 | feature, but there is no requirement that all browsers implement any single 7 | feature. 8 | 9 | The exact definition of the behaviour controlled by each feature belongs in the 10 | spec which defines the feature. Those are linked where available. 11 | 12 | ## Standardized Features 13 | 14 | These features have been declared in a published version of the respective 15 | specification. 16 | 17 | | Feature name | Spec link(s) | Browser Support | 18 | | ------------ | ------------ | --------------- | 19 | | `accelerometer` | [Generic Sensor API][generic-sensor] | [Chrome 66](https://www.chromestatus.com/feature/5758486868656128) | 20 | | `ambient-light-sensor` | [Generic Sensor API][generic-sensor] | Behind a flag in Chrome[7](#fn7) | 21 | | `attribution-reporting` | [Attribution Reporting API][attribution-reporting] | [Chrome 115](https://chromestatus.com/feature/6412002824028160) | 22 | | `autoplay` | [HTML][html] | [Chrome 64](https://www.chromestatus.com/feature/5100524789563392) | 23 | | `battery` | [Battery Status API][battery-status] | Status "[Open](https://bugs.chromium.org/p/chromium/issues/detail?id=1007264)" in Chrome | 24 | | `bluetooth` | [Web Bluetooth][bluetooth] | [Chrome 104](https://chromestatus.com/feature/6439287120723968) | 25 | | `camera` | [Media Capture][media-capture] | [Chrome 64](https://www.chromestatus.com/feature/5023919287304192) | 26 | | `ch-ua` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 27 | | `ch-ua-arch` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 28 | | `ch-ua-bitness` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 29 | | `ch-ua-full-version` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 30 | | `ch-ua-full-version-list` | [User-Agent Client Hints][client-hints] | Behind a flag in Chrome[8](#fn8) | 31 | | `ch-ua-high-entropy-values` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 32 | | `ch-ua-mobile` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 33 | | `ch-ua-model` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 34 | | `ch-ua-platform` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 35 | | `ch-ua-platform-version` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 36 | | `ch-ua-wow64` | [User-Agent Client Hints][client-hints] | [Chrome 89](https://chromestatus.com/feature/5995832180473856) | 37 | | `compute-pressure` | [Compute Pressure API][compute-pressure] | [Chrome 125](https://chromestatus.com/feature/5597608644968448) | 38 | | `cross-origin-isolated` | [HTML][html] | Experimental in Chrome 85 | 39 | | `direct-sockets` | [Direct Sockets API][direct-sockets] | | Status "[Started](https://chromestatus.com/feature/6398297361088512)" in Chrome | 40 | | `display-capture` | [Media Capture: Screen Share][media-capture-screen-share] | [Chrome 94](https://chromestatus.com/feature/5144822362931200) | 41 | | `encrypted-media` | [Encrypted Media Extensions][encrypted-media] | [Chrome 64](https://www.chromestatus.com/feature/5023919287304192) | 42 | | `execution-while-not-rendered` | [Page Lifecycle][page-lifecycle] | Behind a flag in Chrome[1](#fn1) | 43 | | `execution-while-out-of-viewport` | [Page Lifecycle][page-lifecycle] | Behind a flag in Chrome[1](#fn1) | 44 | | `fullscreen` | [Fullscreen API][fullscreen] | [Chrome 62](https://www.chromestatus.com/feature/5094837900541952) | 45 | | `geolocation` | [Geolocation API][geolocation] | [Chrome 64](https://www.chromestatus.com/feature/5023919287304192) | 46 | | `gyroscope` |[Generic Sensor API][generic-sensor] | [Chrome 66](https://www.chromestatus.com/feature/5758486868656128) | 47 | | `hid` | [WebHID API][webhid] | [Chrome 89](https://chromestatus.com/feature/5172464636133376) | 48 | | `identity-credentials-get` | [Federated Credential Management API][fedcm] | [Chrome 110](https://chromestatus.com/feature/5162418615877632) | 49 | | `idle-detection` | [Idle Detection API][idle-detection] | [Chrome 94](https://chromestatus.com/feature/4590256452009984) | 50 | | `keyboard-map` | [Keyboard API][keyboard] | [Chrome 97](https://www.chromestatus.com/feature/5657965899022336) | 51 | | `magnetometer` |[Generic Sensor API][generic-sensor] | [Chrome 66](https://www.chromestatus.com/feature/5758486868656128) | 52 | | `mediasession` | [Media Session API][mediasession] | | 53 | | `microphone` |[Media Capture][media-capture] | [Chrome 64](https://www.chromestatus.com/feature/5023919287304192) | 54 | | `midi` | [Web MIDI][web-midi] | [Chrome 64](https://www.chromestatus.com/feature/5023919287304192) | 55 | | `navigation-override` | [CSS Spatial Navigation][navigation-override] | | 56 | | `otp-credentials` | [WebOTP API][otp-credentials] | [Chrome 84](https://chromestatus.com/feature/5873577578463232) | 57 | | `payment` | [Payment Request API][payment-request] | Chrome 60 | 58 | | `picture-in-picture` | [Picture-in-Picture][pip] | [Chrome 71](https://chromestatus.com/feature/5729206566649856) | 59 | | `publickey-credentials-get` | [Web Authentication API][publickey-credentials-get] | [Chrome 84](https://bugs.chromium.org/p/chromium/issues/detail?id=993007) | 60 | | `screen-wake-lock` | [Wake Lock API][wake-lock] | [Chrome 84](https://www.chromestatus.com/feature/4636879949398016) | 61 | | `serial` | [Web Serial API][web-serial] | [Chrome 89](https://chromestatus.com/feature/6577673212002304) | 62 | | `sync-xhr` | [XMLHttpRequest][xhr] | [Chrome 65](https://www.chromestatus.com/feature/5154875084111872) | 63 | | `storage-access` | [Storage Access][storage-access] | [Chrome 115](https://chromestatus.com/feature/5612590694662144) | 64 | | `usb` | [WebUSB][webusb] | Chrome 60 | 65 | | `web-share` | [Web Share API][web-share] | Chrome 86 | 66 | | `window-management`[5](#fn5) | [Window Management API][window-management] | [Chrome 111](https://chromestatus.com/feature/5146352391028736) | 67 | | `xr-spatial-tracking`[2](#fn2) | [WebXR Device API][xr] | [Available as a Chrome Origin Trial](https://developers.chrome.com/origintrials/#/trials/active) | 68 | 69 | ## Proposed Features 70 | 71 | These features have been proposed, but the definitions have not yet been 72 | integrated into their respective specs. 73 | 74 | | Feature name | Spec/PR link(s) | Browser Support | 75 | | ------------ | --------------- | --------------- | 76 | | `clipboard-read` | https://github.com/w3c/clipboard-apis/pull/120 | Chrome 86 | 77 | | `clipboard-write` | https://github.com/w3c/clipboard-apis/pull/120 | Chrome 86 | 78 | | `deferred-fetch` |https://github.com/whatwg/fetch/pull/1647 | | 79 | | `gamepad` | https://github.com/w3c/gamepad/pull/112 | | 80 | | `shared-autofill` | https://github.com/schwering/shared-autofill | | 81 | | `speaker-selection` | https://github.com/w3c/mediacapture-output/pull/96 | | 82 | 83 | ## Experimental Features 84 | 85 | These features generally have an explainer only, but may be available for 86 | experimentation by web developers. 87 | 88 | | Feature name | Link(s) | Browser Support | 89 | | ------------ | ------- | --------------- | 90 | | `all-screens-capture` | [Capture all screens API](https://screen-share.github.io/capture-all-screens/#feature-policy-integration) | In [Origin Trial](https://chromestatus.com/feature/6284029979525120) | 91 | | `browsing-topics` | [Explainer](https://github.com/jkarlin/topics/) | Status "[Started](https://bugs.chromium.org/p/chromium/issues/detail?id=1294456)" in Chrome | 92 | | `captured-surface-control` | [Captured Surface Control API][capture-surface-control] | In [Origin Trial](https://chromestatus.com/feature/5092615678066688) | 93 | | `conversion-measurement ` | [Explainer](https://github.com/WICG/conversion-measurement-api#publisher-controls-for-impression-declaration) | Experimental in Chrome[3](#fn3) | 94 | | `digital-credentials-get` | [Explainer](https://wicg.github.io/digital-credentials/) | Behind a flag in Chrome[6](#fn6) 95 | | `focus-without-user-activation` | [focus-without-user-activation.md](policies/focus-without-user-activation.md) | Status "[Open](https://bugs.chromium.org/p/chromium/issues/detail?id=965495)" in Chrome | 96 | | `join-ad-interest-group` | [Protected Audience (formerly FLEDGE)][protected-audience] | Behind a flag in Chrome[4](#fn4) | 97 | | `local-fonts` | [Local Font Access API][local-fonts] and [Explainer](https://github.com/WICG/local-font-access/blob/main/README.md) | [Experimental in Chrome](https://chromestatus.com/feature/6234451761692672) | 98 | | `run-ad-auction` | [Protected Audience (formerly FLEDGE)][protected-audience] | Behind a flag in Chrome[4](#fn4) | 99 | | `smart-card` | [Draft Spec](https://wicg.github.io/web-smart-card/#permissions-policy) and [Explainer](https://github.com/WICG/web-smart-card#readme) | [Prototyping in Chrome](https://chromestatus.com/feature/6411735804674048) | 100 | | `sync-script` | | Behind a flag in Chrome[1](#fn1) | 101 | | `trust-token-redemption` | [Explainer](https://github.com/WICG/trust-token-api) | In [Origin Trial](https://developers.chrome.com/origintrials/#/view_trial/2479231594867458049) in Chrome 84-87 | 102 | | `unload` | [Explainer](https://github.com/fergald/docs/blob/master/explainers/permissions-policy-unload.md) | Status "[Started](https://crbug.com/1324111) in Chrome | 103 | | `vertical-scroll` | [vertical\_scroll.md](policies/vertical_scroll.md) | Behind a flag in Chrome[1](#fn1) | 104 | 105 | ## Retired Features 106 | 107 | These features were once standardized or proposed, but their specification 108 | and/or implementations have been removed. 109 | 110 | | Feature name | Spec link(s) | Browser Support | 111 | | ------------ | ------------ | --------------- | 112 | | `document-domain` | [HTML][html] | Formerly in Chrome, behind a flag | 113 | | `window-placement` | [Window Management API][window-management] | Formerly in Chrome, changed to `window-management`[5](#fn5) | 114 | 115 | ## Notes 116 | 117 | [1]: To enable these, use the Chrome command line flag 118 | `--enable-blink-features=ExperimentalProductivityFeatures`. 119 | 120 | [2]: Implemented in Chrome as `vr` prior to Chrome 79. 121 | 122 | [3]: To enable this, use the Chrome command line flag 123 | `--enable-blink-features=ConversionMeasurement`. 124 | 125 | [4]: To enable this, use the Chrome command line flag 126 | `--enable-features=AdInterestGroupAPI,InterestGroupStorage,Fledge`. 127 | 128 | [5]: Implemented in [Chrome 100](https://chromestatus.com/feature/5252960583942144) as `window-placement`; 129 | changed in [Chrome 111](https://chromestatus.com/feature/5146352391028736) to `window-management`. 130 | 131 | [6]: To enable this, use the Chrome command line flag 132 | `--enable-features=WebIdentityDigitalCredentials`. 133 | 134 | [7]: To enable this, use the Chrome command line flag 135 | `--enable-features=SensorExtraClasses`. 136 | 137 | [8]: To enable this, user the Chrome command line flag 138 | `--enable-features=ClientHintUAHighEntropyValuesPermissionPolicy`. 139 | 140 | [attribution-reporting]: https://wicg.github.io/attribution-reporting-api/#permission-policy-integration 141 | [battery-status]: https://w3c.github.io/battery/#permissions-policy-integration 142 | [bluetooth]: https://webbluetoothcg.github.io/web-bluetooth/#permissions-policy 143 | [capture-surface-control]: https://screen-share.github.io/captured-surface-control 144 | [compute-pressure]: https://www.w3.org/TR/compute-pressure/#policy-control 145 | [client-hints]: https://wicg.github.io/ua-client-hints/ 146 | [direct-sockets]: https://wicg.github.io/direct-sockets/#permissions-policy 147 | [encrypted-media]: https://w3c.github.io/encrypted-media/#permissions-policy-integration 148 | [protected-audience]: https://wicg.github.io/turtledove/#permissions-policy-integration 149 | [fedcm]: https://fedidcg.github.io/FedCM/#permissions-policy-integration 150 | [fullscreen]: https://fullscreen.spec.whatwg.org/#permissions-policy-integration 151 | [generic-sensor]: https://www.w3.org/TR/generic-sensor/#feature-policy 152 | [geolocation]: https://w3c.github.io/geolocation-api/#permissions-policy 153 | [html]: https://html.spec.whatwg.org/multipage/infrastructure.html#policy-controlled-features 154 | [idle-detection]: https://wicg.github.io/idle-detection/#api-permissions-policy 155 | [keyboard]: https://wicg.github.io/keyboard-map/#permissions-policy 156 | [local-fonts]: https://wicg.github.io/local-font-access/#permissions-policy 157 | [media-capture]: https://w3c.github.io/mediacapture-main/#permissions-policy-integration 158 | [media-capture-screen-share]: https://w3c.github.io/mediacapture-screen-share/#permissions-policy-integration 159 | [mediasession]: https://w3c.github.io/mediasession/#permissions-policy 160 | [navigation-override]: https://drafts.csswg.org/css-nav-1/#policy-feature 161 | [otp-credentials]: https://wicg.github.io/web-otp/#otp-credentials-feature 162 | [page-lifecycle]: https://wicg.github.io/page-lifecycle/#feature-policies 163 | [payment-request]: https://www.w3.org/TR/payment-request/#permissions-policy 164 | [pip]: https://wicg.github.io/picture-in-picture/#feature-policy 165 | [publickey-credentials-get]: https://w3c.github.io/webauthn/#sctn-permissions-policy 166 | [storage-access]: https://privacycg.github.io/storage-access/#permissions-policy-integration 167 | [wake-lock]: https://w3c.github.io/screen-wake-lock/#policy-control 168 | [web-midi]: https://webaudio.github.io/web-midi-api/#permissions-policy-integration 169 | [web-serial]: https://wicg.github.io/serial/#permissions-policy 170 | [web-share]: https://w3c.github.io/web-share/#permissions-policy 171 | [webhid]: https://wicg.github.io/webhid/#permissions-policy 172 | [webusb]: https://wicg.github.io/webusb/#permissions-policy 173 | [window-management]: https://w3c.github.io/window-management/#api-permission-policy-integration 174 | [xhr]: https://xhr.spec.whatwg.org/#feature-policy-integration 175 | [xr]: https://immersive-web.github.io/webxr/#permissions-policy 176 | -------------------------------------------------------------------------------- /integration.md: -------------------------------------------------------------------------------- 1 | # Defining Policy-Controlled Features 2 | 3 | This guide is for authors of other standards who want to use Permissions Policy 4 | as a mechanism for enabling and disabling their features. It's a collection of 5 | principles and guidelines (more than actual rules) for coming up with sensible 6 | defaults, whether the feature in question is a long standing feature on the 7 | web, or something brand new. 8 | 9 | ## Referencing the Permissions Policy spec 10 | 11 | There is no central registry for policy-controlled features. Feature authors who 12 | wish to allow Permissions Policy to control their features on the web can do so 13 | by referencing the Permissions Policy specification. 14 | 15 | The following example shows how a feature could be declared as a 16 | policy-controlled feature: 17 | 18 | > Example: 19 | > 20 | >### Section N: Permissions Policy Integration 21 | > The Sample API defines a [*policy-controlled feature*](https://w3c.github.io/webappsec-permissions-policy/#policy-controlled-feature) 22 | > identified by the string "`sample`". Its [default allowlist](https://w3c.github.io/webappsec-permissions-policy/#default-allowlist) 23 | > is `'self'` \[[PERMISSIONS-POLICY](https://w3c.github.io/webappsec-permissions-policy/)\]. 24 | 25 | The specification can then refer to this feature, and test whether it is enabled 26 | or not in a specific document, with text similar to this: 27 | 28 | > Example: 29 | > 30 | > If [this](https://webidl.spec.whatwg.org/#this)'s [relevant global object](https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global)'s [associated Document](https://html.spec.whatwg.org/multipage/window-object.html#concept-document-window) 31 | > is not [allowed to use](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#allowed-to-use) 32 | > the `sample` feature, then throw a `SecurityError` 33 | > [DOMException](https://heycam.github.io/webidl/#dfn-DOMException) and abort these steps. 34 | 35 | (This is an example only. The actual behavior of any algorithm when a 36 | policy-controlled feature is disabled is left up to the specification which 37 | defines that feature.) 38 | 39 | ## Choosing a default allowlist 40 | 41 | As described in the 42 | [spec](https://w3c.github.io/webappsec-permissions-policy/#default-allowlists), the default 43 | allowlist chosen affects how the feature behaves when there are no declared 44 | policies present. As a rough guide: 45 | 46 | * Features which have already been widely available on the web platform, but 47 | which Permissions Policy can now disable selectively, should use `*`. This 48 | ensures that the majority of documents on the web, as well as documents which 49 | are framed without their knowledge, will continue to behave as expected by 50 | their original authors. 51 | * New powerful features are often specified such that they are available in 52 | top-level browsing contexts only, and are not available in cross-origin child 53 | frames, for security. These kinds of features should use a default allowlist of 54 | `'self'` to provide this behaviour. In this case, Permissions Policy also grants 55 | site authors the ability to selectively enable the feature in other origins, 56 | but the default behaviour is to disable it. 57 | 58 | ## Considerations for behavior when disallowed 59 | 60 | It is important for feature authors to carefully consider the mechanism by 61 | which their feature is disabled when disallowed in a document, for ease of 62 | developer feature detection, as well as for compatibility with existing web 63 | content. 64 | 65 | Existing web platform features which already have some mechanism for reporting 66 | errors, or signalling that the user chose not to grant permission, should use 67 | those existing mechanisms when disabled. 68 | 69 | New features should attempt to fail in a way which allows authors to detect 70 | that the feature is disabled. 71 | 72 | > Example: 73 | > 74 | > The fullscreen API has existed on the web for some time, and is being 75 | > implemented as a policy-controlled feature. Developers have always had to 76 | > contend with the fact that fullscreen may not be allowed, and the API has a 77 | > method of signalling that. 78 | > 79 | > As a policy-controlled feature, the fullscreen API can specify that when 80 | > disabled, `document.fullscreenEnabled` must return `false`, and 81 | > `Element.requestFullscreen()` must fire a `fullscreenerror` event, and return 82 | > a promise which rejects with a `TypeError` exception. 83 | 84 | If an existing feature has no mechanism for reporting failure, or has never been 85 | allowed to fail in the past, then it may be dangerous to turn it into a 86 | policy-controlled feature, where it may start to fail on pages that were always 87 | able to assume that it would not. 88 | 89 | In this case, features may be better defined using [Document Policy](https://wicg.github.io/document-policy/), 90 | as that mechanism requires an explicit opt-in by any embedded document for which 91 | that policy is required. 92 | 93 | > Example: 94 | > 95 | > The `document.write` API has existed on the web since roughly the dawn of 96 | > JavaScript, and has no failure modes. 97 | > 98 | > One means of disallowing this feature via Permissions Policy would be to declare that 99 | > any calls to `document.write()` will silently fail. However, this would mean that 100 | > if a page contained a script like this: 101 | > 102 | > 103 | > 104 | > 105 | > ... 106 | > 107 | > then an attacker could embed that page in a frame with the `document.write` 108 | > feature disabled, and bypass the critical security script. 109 | > 110 | > To avoid this, a better way to disable it would be to define the availability of 111 | > `document.write()` as a configuration point using document policy. Then the use of 112 | > `document.write()` in a document which disables it can fire a `SecurityError` 113 | > exception on the `document` object. If a document which is to be embedded in a frame 114 | > which requires the policy does not conform to that required policy, it is simply not 115 | > loaded. (See the document policy explainer and spec for details). 116 | -------------------------------------------------------------------------------- /permissions-policy-client-hints.md: -------------------------------------------------------------------------------- 1 | # Permissions Policy and Client Hints 2 | 3 | ## Background 4 | 5 | [Client Hints](https://wicg.github.io/client-hints-infrastructure/) are a 6 | mechanism for the browser to provide information to an origin server about the 7 | browser's configuration and capabilities, to allow the server to select 8 | appropriate responses based on that configuration. See 9 | [here](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/client-hints) 10 | for more information and background on Client Hints specifically. 11 | 12 | Client Hints do represent an opportunity for increased fingerprinting surface, 13 | as they expose information about the user's browser, language preferences, 14 | network conditions, and other potentially identifying information. As such, it 15 | is important that the information not be simply made available to all documents 16 | and resources. 17 | 18 | [Permissions Policy](https://w3c.github.io/webappsec-permissions-policy/) is a 19 | way to control what features are available in documents, providing a method of 20 | delegation of powerful features to subframes. 21 | 22 | ## Relationship between Permissions Policy and Client Hints 23 | 24 | Every client hint is represented in Permissions Policy as a policy-controlled 25 | feature. The feature, which is always enabled for top-level documents, 26 | represents the ability to receive the hint in a subframe. 27 | 28 | There are two broad classes of hints defined: High-entropy and Low-entropy. High 29 | entropy hints contain a greater amount of potententially identifying information 30 | about the user, and are not intended for automatic distribution to cross-origin 31 | resources. Low entropy hints contain information about the browser which is 32 | expected to be consistent across large groups of users (browser name, or major 33 | version, for instance) and is much less useful for identifying individual users. 34 | 35 | High-entropy hints are backed by features with a default allowlist of `self`. 36 | Low-entropy hints are backed by features with a default allowlist of `*`. 37 | 38 | Example high-entropy hints (and their corresponding features): 39 | * DPR (`ch-dpr`) 40 | * UA-Arch (`ch-ua-arch`) 41 | 42 | Example low-entropy hints (and their corresponding features): 43 | * Save-Data (`ch-save-data`) 44 | * UA (`ch-ua`) 45 | 46 | ## How delegation works 47 | 48 | In top-level documents, hints are requested with the Accept-CH HTTP response 49 | header 50 | ([reference](https://tools.ietf.org/html/draft-ietf-httpbis-client-hints-15)). 51 | 52 | Permissions Policy cannot be used to change the hints received by the top-level 53 | document, as the `Permissions-Policy` response header cannot be sent before the 54 | hints (which are request headers) are received. However, it can be used to 55 | control where those hints are sent after that. 56 | 57 | ### Delegation to embedded documents 58 | 59 | Any document which receives hints may choose to delegate those hints to other 60 | documents which it embeds inside of an ` 117 |
118 | 119 | ``` 120 | 121 | The request for the document in the first frame will be sent with the 122 | low-entropy hints (UA, UA-Mobile and Save-Data) and the single received 123 | high-entropy hint (DPR). 124 | 125 | The request for the document in the second frame will only be sent with the 126 | low-entropy hints. 127 | 128 | ### Example 2: Adding additional hints with markup 129 | 130 | Resource: https://example.com/ 131 | 132 | Response headers: 133 | ```http 134 | Accept-CH: DPR 135 | ``` 136 | 137 | Markup: 138 | ```html 139 | 140 | ``` 141 | 142 | The request for the document in the frame will be sent with the low-entropy 143 | hints (UA, UA-Mobile and Save-Data) and the DPR high-entropy hint. The UA-Arch 144 | hint cannot be sent, as it was not received by the parent document. 145 | 146 | ### Example 3: Restricting hints from same-origin frames 147 | 148 | Resource: https://example.com/ 149 | 150 | Response headers: 151 | ```http 152 | Accept-CH: DPR 153 | ``` 154 | 155 | Markup: 156 | ```html 157 | 158 | ``` 159 | 160 | The request for the document in the frame will only be sent with two low-entropy 161 | hints: UA and UA-Mobile. Both the low-entropy Save-Data hint and the 162 | high-entropy DPR hint have been excluded by policy. 163 | 164 | ### Example 4: Restricting hints after navigation 165 | 166 | Resource: https://example.com/ 167 | 168 | Response headers: 169 | ```http 170 | Accept-CH: DPR 171 | ``` 172 | 173 | Markup: 174 | ```html 175 | 176 | ``` 177 | 178 | Resource: https://example.com/page2.html 179 | 180 | Markup: 181 | ```html 182 | External link 183 | ``` 184 | 185 | The initial request for the document in the frame (`page2,html`) will be sent 186 | with the low-entropy hints, as well as DPR. However, if the frame is navigated 187 | away from the `https://example.com` origin, requests for other documents will 188 | only be sent with the UA and UA-Mobile hints. The Save-Data hint will be 189 | excluded because of the policy in the `allow` attribute, and the DPR hint will 190 | be excluded because it is a high-entropy hint, and is not sent to a third-party 191 | origin unless specifically delegated. 192 | 193 | ### Example 5: Restricting delegation with response headers 194 | 195 | Resource: https://example.com/ 196 | 197 | Response Headers: 198 | ```http 199 | Accept-CH: DPR 200 | Permissions-Policy: ch-dpr=(self "https://external.example") 201 | ``` 202 | 203 | Markup: 204 | ```html 205 | 206 |
207 | 208 | ``` 209 | 210 | In this example, a `Permissions-Policy` response header has been used to set the 211 | list of origins which can be sent the DPR hint. 212 | 213 | The request for the document in the first frame will be sent with the 214 | low-entropy hints and the DPR high-entropy hint, as it is present in the header 215 | allowlist. 216 | 217 | The request for the document in the second frame will only be sent with the 218 | low-entropy hints. The DPR hint cannot be sent to that origin, as it was not 219 | present in the header allowlist. 220 | 221 | ### Example 6: Default behaviour of hints for subresources 222 | 223 | Resource: https://example.com/ 224 | 225 | Response headers: 226 | ```http 227 | Accept-CH: DPR 228 | ``` 229 | 230 | Markup: 231 | ```html 232 | 233 |
234 | 235 | ``` 236 | 237 | The request for the first image will be sent with the 238 | low-entropy hints (UA, UA-Mobile and Save-Data) and the single received 239 | high-entropy hint (DPR). 240 | 241 | The request for the second image will only be sent with the low-entropy hints. 242 | 243 | ### Example 7: Adding additional hints with response headers 244 | 245 | Resource: https://example.com/ 246 | 247 | Response headers: 248 | ```http 249 | Accept-CH: DPR 250 | Permissions-Policy: ch-dpr=(self "https://external.example") 251 | ``` 252 | Markup: 253 | ```html 254 | 255 |
256 | 257 | ``` 258 | 259 | In this example, a `Permissions-Policy` response header has been used to set the 260 | list of origins which can be sent the DPR hint. 261 | 262 | The request for the first image will be sent with the low-entropy hints and the 263 | DPR high-entropy hint, as it is present in the header allowlist. 264 | 265 | The request for the second image will only be sent with the low-entropy hints. 266 | The DPR hint cannot be sent to that origin, either in a subresource request, as 267 | shownhere, or in a subframe, as in the example above, as it was not present in 268 | the header allowlist. 269 | -------------------------------------------------------------------------------- /permissions-policy-explainer.md: -------------------------------------------------------------------------------- 1 | # Permissions Policy Explainer 2 | 3 | Permissions Policy is a web platform API which gives a website the ability to 4 | allow or block the use of browser features in its own frame or in iframes that 5 | it embeds. It operates on the principle that top-level documents should 6 | generally have access to the web's powerful features (often at the discretion of 7 | the user, who needs to grant permission), but that embedded content should not 8 | have such access automatically. A document which embeds another document should 9 | be able to declare which features it trusts that embedded content to use. 10 | 11 | Examples of features that can be controlled by Permissions Policy include: 12 | * Battery status 13 | * Client Hints 14 | * Encrypted-media decoding 15 | * Fullscreen 16 | * Geolocation 17 | * Picture-in-picture 18 | * Sensors: Accelerometer, Ambient Light Sensor, Gyroscope, Magnetometer 19 | * User media: Camera, Microphone 20 | * Video Autoplay 21 | * Web Payment Request 22 | * WebMIDI 23 | * WebUSB 24 | * WebXR 25 | 26 | 27 | ## Wait, isn't this Feature Policy? 28 | 29 | Yes, this API was previously known as Feature Policy, and was shipped as such in 30 | Google Chrome since 2016. 31 | 32 | There have been several changes to the API since it shipped as Feature Policy. 33 | If you're already familiar with Feature Policy, feel free to skip to the 34 | ["Big Changes"](#appendix-big-changes-since-this-was-called-feature-policy) 35 | section below. 36 | 37 | 38 | ## A bit of history 39 | 40 | The ideas for Permissions Policy, and Feature Policy before it, came out of 41 | several needs that arose in the web platform space: 42 | 43 | * It became apparent that some features are better off disabled by default in 44 | iframes, especially those hosting content from a different origin than their 45 | containing page. However, there may be legitimate cases where such behavior is 46 | desirable, and web applications should be able to (explicitly) delegate 47 | permission to such frames. Different features have historically handled this in 48 | very different ways: some features have had dedicated iframe attributes for 49 | allowing their use; others have been declared usable only by the top-level 50 | document, or have been usable everywhere except in sandboxed iframes. 51 | 52 | * Similarly, folks working on permissions have seen a need to disable sensitive 53 | features like geolocation by default in iframes, to reduce the chance of users 54 | being confused or tricked into giving embedded websites access. See [FP + 55 | Permissions](https://docs.google.com/document/d/1iMIpTUJWzrW-_TqL9IBkxRwbFUto7P7Dn1oXVok7h5U/edit) 56 | for more details on the relationship between this document and permissions. 57 | 58 | * Ideas for mitigations against XSS attacks were also being discussed. For 59 | example, if a website knows it never uses the Bluetooth API, it can mitigate 60 | against XSS attacks by telling the browser that it should never expose the 61 | Bluetooth API to its frame and/or its descendants - i.e. developers want to 62 | draw a security perimeter for their applications. 63 | 64 | * From a performance perspective, there is demand from site owners to specify a 65 | contract about use, or lack of thereof, of certain features both within their 66 | own context and for embedded contexts, which may affect performance and UX of 67 | the embedder - e.g. disable use of synchronous scripts and XHRs, etc. This 68 | contact of use may also be used, for example, to enable certain types of "fast 69 | path" optimizations in the browser, or to assert a promise about conformance 70 | with some requirements set by other embedders - e.g. various social networks, 71 | search engines, and so on. 72 | 73 | Feature Policy grew out of the ideas and aims to address the above needs 74 | via a single and unified interface. 75 | 76 | Since then, Feature Policy has split into two related APIs to cover the widely 77 | different use cases: Permissions Policy to handle the control of powerful 78 | features and permissions, even in the presence of XSS; and [Document Policy](https://github.com/wicg/document-policy/blob/main/document-policy-explainer.md), 79 | to handle performance optimizations and other kinds of configurable APIs. 80 | 81 | ## How is a Policy Specified? 82 | 83 | Permissions Policy can be thought of conceptually as a way to control delegation 84 | of powerful features to subframes. It operates on allowed lists of origins for 85 | each feature, where a "feature" is a well-defined token that maps to and 86 | controls some web platform API - e.g. “geolocation” is a feature name for the 87 | Geolocation API, and a policy of “`geolocation https://foo.com https://bar.com`” 88 | indicates that geolocation is enabled for foo.com and bar.com. 89 | 90 | Any frames a website embeds that aren’t of a listed origin will have that 91 | feature disabled - e.g. with above policy a frame containing https://baz.com/ 92 | would have the Geolocation API disabled. If the website's own origin doesn’t 93 | appear in the allowlist, the feature will be disabled for itself too. And, 94 | finally, if no policy is specified by a website for a particular feature, then 95 | a default allowlist will be used for that feature. 96 | 97 | The primary way of delegating access to powerful features is through the `allow` 98 | attribute of the iframe element. By default, powerful features are allow in the 99 | top-level document, and its same-origin frames, but blocked in cross-origin 100 | frames. The `allow` attribute can be used to set this policy on a frame-by-frame 101 | basis: 102 | 103 | ```html 104 | 105 | ``` 106 | 107 | Similar to sandbox flags, this attribute only takes effect at the point an 108 | iframe is loaded. If it is changed, the iframe must be reloaded to enforce the 109 | new policy. 110 | 111 | By default, features specified in the `allow` attribute are allowed only as long 112 | as the origin of the document in the frame matches the iframe's `src` attribute, 113 | and will not be granted if it navigates away from that origin, but that can be 114 | changed by appending an allowed list of origins to the feature: 115 | 116 | ```html 117 | 118 | ``` 119 | Secondly, the `Permissions-Policy` HTTP response header can be used to restrict 120 | the list of origins which could potentially be granted access through the 121 | `allow` attribute. By default, for most features this list is `*`, which means 122 | that an iframe element could name any origin in its `allow` attribute, and have 123 | access granted to a document in that frame. Restricting this list through the 124 | header means that even if an iframe specifies an origin, if the origin is not 125 | allowed by the header, the feature will not be given to the framed document. 126 | 127 | As an example, a policy may be specified in the HTTP “Permissions-Policy” header 128 | like this (which is formatted for ease of reading): 129 | 130 | ```http 131 | Permissions-Policy: 132 | geolocation=(self "https://foo.com"), 133 | camera=(), 134 | fullscreen=* 135 | ``` 136 | 137 | In this example, “`self`” will resolve to the origin that specifies the policy; 138 | “`*`” will resolve to the set of all origins; and the empty list of origins 139 | indicates that the feature should be disabled for all frames. 140 | 141 | This policy indicates that geolocation permission can only be granted to 142 | same-origin frames and to frames hosting documents from foo.com. Camera access 143 | is disabled for *all* documents, including this one, and full screen mode can 144 | potentially be granted to any frame (although it is not granted by default; the 145 | `allow` attribute must still be used on individual frames). 146 | 147 | ## How are Features Disabled? 148 | 149 | The way that disabled features behave varies from feature-to-feature. 150 | Permission-like features, such as geolocation, already fail sensibly and return 151 | error values when the permission to use it is missing. When such a feature is 152 | disabled by Permissions Policy, it would be equivalent to a denied permission and 153 | would exercise a similar code path (perhaps returning a different error code). 154 | 155 | In other cases, the feature may fail silently, be removed from the global 156 | object altogether or fail in some other way that makes the most sense for that 157 | API - i.e. we’ll consider and choose the best strategy on a case by case basis. 158 | 159 | ## Permissions Policy and the Permissions API 160 | 161 | One of the goals of Permissions Policy is to give control to embedders over how 162 | permissions are enabled/disabled in iframes. There are open questions around 163 | the relationship between Permissions Policy, Permission Delegation and the 164 | Permissions API which need to be worked out. A separate document, "[Feature Policy 165 | and Permissions](https://docs.google.com/document/d/1iMIpTUJWzrW-_TqL9IBkxRwbFUto7P7Dn1oXVok7h5U/edit#heading=h.ciuptq8j47e6)", 166 | describes some of these questions in more detail. 167 | 168 | ## Permissions Policy and the Reporting API 169 | 170 | Permissions Policy integrates with the Reporting API, so that you can get reports 171 | from users when a policy is violated in their browser, or respond to violations 172 | in JavaScript. See the separate explainer, [Permissions Policy Reporting](reporting.md), for 173 | details. 174 | 175 | ## Inspecting the Current Policy 176 | 177 | Permissions Policy provides a JavaScript interface to query the policy which is 178 | active in the current document. You can use it to tell whether specific 179 | features are enabled or not, or whether they would be enabled by iframes 180 | (depending on the content loaded into that iframe). See [Policy Introspection 181 | from Scripts](https://w3c.github.io/webappsec-feature-policy/#introspection) in 182 | the specification for more details. 183 | 184 | ## Examples 185 | 186 | The first set of examples deals with permission features. The `geolocation` 187 | permission, which grants access to the user's physical location, is used as an 188 | example, but any other permission should work in an analogous way. 189 | 190 | ### Example 1 - Using the default policy 191 | 192 | In this scenario, example.com embeds an advertisement from ad.com. Being the 193 | top-level document, example.com has the ability to request permission to access 194 | the user's location, but this ability is not granted to ad.com. 195 | 196 | If ad.com attempts to access the user's location, it will receive a "permission 197 | denied" error, exactly as if the user denied permission to the site. 198 | 199 | example.com: 200 | ```html 201 | 202 | ``` 203 | 204 | ### Example 2 - Enable geolocation in a cross-origin frame 205 | 206 | In this scenario, example.com embeds two frames, one hosting an ad from ad.com, 207 | and the other hosting a navigation widget from maps.example.com. example.com 208 | wants to allow maps.example.com to use the geolocation feature, but still does 209 | not want to grant that access to ad.com. 210 | 211 | example.com can use the iframe `allow` attribute to delegate access to the frame 212 | containing the navigation widget, which will allow that document to request the 213 | user's location, The ad.com frame is still unable to even make the request. 214 | 215 | example.com: 216 | ```html 217 | 218 | 219 | ``` 220 | 221 | Note that `allow="geolocation"` here is actually shorthand for 222 | `allow="geolocation 'src'"`, where `'src'` is a special token which will expand 223 | into the origin which the iframe tag names, usually in its `src` attribute. 224 | https://maps.example.com, in this case. 225 | 226 | ### Example 3 - Cascading disable 227 | 228 | Here, example.com embeds an advertisement from bad-ad.com. It does not grant 229 | that frame access to geolocation, the ad then embeds a frame of its own, and 230 | attempts to grant that frame access. This will also be blocked by permissions 231 | policy, as a frame which is not allowed a specific feature cannot grant that 232 | feature to any of its subframes. 233 | 234 | example.com: 235 | ```html 236 | 237 | ``` 238 | 239 | bad-ad.com: 240 | ```html 241 | 242 | ``` 243 | 244 | 245 | ### Example 4 - Policy only directly affects child frame 246 | 247 | In this example, a trusted subframe *is* able to delegate access to a feature to 248 | one of its subframes. Example.com embeds a widget from game.com, granting it 249 | geolocation access. Game.com then embeds another document from 250 | resources.game.com, and allows it access to geolocation as well. This succeeds, 251 | even though example.com didn’t explicitly allow it. This may seem 252 | counter-intuitive but it accurately reflects the trust relationship that is 253 | expressed in the policy: example.com trusts game.com to use geolocation and so 254 | game.com must be trusted to responsibly delegate access further. 255 | 256 | example.com: 257 | ```html 258 | 259 | ``` 260 | 261 | game.com: 262 | ```html 263 | 264 | ``` 265 | 266 | ### Example 5 - Restrict delegation with an HTTP header 267 | 268 | To tighten things down, example.com wants to ensure that it can only grant 269 | location access to a small set of sites, even if someone manages to create an 270 | iframe on example.com and can set its `allow` attribute. 271 | 272 | It can do this with the `Permissions-Policy` header, which sets the origins that 273 | can potentially be granted access to features; 274 | 275 | example.com: 276 | ```http 277 | Permissions-Policy: geolocation=(self "https://game.com" "https://map.example.com") 278 | ``` 279 | 280 | ```html 281 | 282 | 283 | ``` 284 | 285 | Since the header has been set, the first iframe will be allowed to request the 286 | user's location, while the second will be blocked. 287 | 288 | Note that `self` here is a special token which will be expanded to the origin of 289 | the document serving this header -- in this case, https://example.com. 290 | 291 | ### Example 6 - Disable a feature entirely with an HTTP header 292 | 293 | In this scenario, example.com knows that it never uses geolocation, and wants 294 | to ensure that everything it embeds does not either, even if somehow an iframe 295 | with an allow attribute can be inserted into its documents that would otherwise 296 | grant that. The empty allowlist ensures that the feature is disabled in all 297 | contexts everywhere. 298 | 299 | example.com: 300 | ```http 301 | Permissions-Policy: geolocation=() 302 | ``` 303 | 304 | ### Example 7 - Iframe navigations 305 | 306 | The allow attribute can specify a list of origins as well. Any document which is 307 | loaded into that frame from one of those origins can have access to the feature 308 | delegated to it (as long as it's not blocked by the header, as in the examples 309 | above). If the frame navigates to any other origin, the feature will be blocked. 310 | 311 | In this scenario, example.com embeds game.com and ad.com. example.com specifies 312 | with the `allow` attribute that geolocation is allowed for game.com and 313 | new-game.com only. However the game.com iframe then navigates itself to 314 | other-game.com. other-game.com will not have access since it’s not specified in 315 | the policy. Subsequently the same iframe navigates to new-game.com which is 316 | allowed access. 317 | 318 | 319 | example.com: 320 | ```html 321 | 322 | 323 | ``` 324 | 325 | ## Appendix: Big changes since this was called Feature Policy 326 | 327 | Permissions Policy works largely exactly the way that Feature Policy did before 328 | it. However, there are a number of cosmetic and logical differences: 329 | 330 | ### New header 331 | 332 | The biggest visible change is that the `Feature-Policy` header is now spelled 333 | `Permissions-Policy`, and its value is a [Structured Field Value](https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html). 334 | (Technically, it's a structured Dictionary, whose names are the feature names, 335 | and values are either items or inner lists, but see the spec for all of the 336 | details there.) 337 | 338 | A policy which would previously have been expressed as: 339 | 340 | ```http 341 | Feature-Policy: fullscreen 'self' https://example.com https://another.example.com; 342 | geolocation *; camera 'none' 343 | ``` 344 | 345 | would now look like: 346 | 347 | ```http 348 | Permissions-Policy: fullscreen=(self "https://example.com" "https://another.example.com"), 349 | geolocation=*, camera=() 350 | ``` 351 | 352 | * `self` and `*` are tokens, and don't need to be quoted. 353 | * Origins are strings, and *do* need double quotes. 354 | * Allow lists are normally enclosed in parentheses, but those can be omitted 355 | if there is only a single element. 356 | * Decalarations are separated by `,` rather than `;`. 357 | 358 | ### Header and allow attribute combine differently 359 | 360 | The second big change is that the header can now be used to restrict where the 361 | document is allowed to delegate features to. Previously, if an origin was 362 | specified in either the `Feature-Policy` header **OR** an iframe `allow` 363 | attribute, then a feature would be granted to a document in that frame. Now, the 364 | origin must be mentioned in both the `Permissions-Policy` header **AND** the 365 | `allow` attribute. 366 | 367 | To make this work with existing uses, where just the `allow` attribute is used, 368 | without any header, the header's default implied value is generally `*`, and the 369 | `allow` attribute's default value is `self` for permissions-style features. 370 | -------------------------------------------------------------------------------- /policies/README.md: -------------------------------------------------------------------------------- 1 | Policy proposals 2 | ================ 3 | 4 | This directory holds a collection of non-normative proposals for 5 | policy-controlled features. They're all written explainer-style, rather than 6 | being specs in their own right. 7 | 8 | These should be taken as "ideas people are considering building out", and 9 | comments on all are wholeheartedly encouraged. 10 | 11 | Nothing in this directory should be construed as having any kind of effect on 12 | the core Feature Policy specification. Features here, whether implemented or 13 | not, should be built on top of that framework. 14 | 15 | For details on policies in the [seamless web talk](https://youtu.be/Wi_PhaFdjlo) at Google I/O 2018, please see: 16 | - [Optimized images](https://github.com/WICG/feature-policy/blob/master/policies/optimized-images.md), which includes: 17 | - Modern formats 18 | - No downscaling 19 | - Fully compressed 20 | - [Unsized media](https://github.com/WICG/feature-policy/blob/master/policies/unsized-media.md) 21 | - [Fast animations](https://github.com/WICG/feature-policy/blob/master/policies/animations.md) 22 | - [Limiting resource sizes](https://github.com/WICG/transfer-size/blob/master/README.md) 23 | 24 | The following policies can be enabled via the `experimental-productivity-features` flag in Chrome dev channel: 25 | - Unsized media 26 | - Modern formats 27 | - No downscaling 28 | - Fast animations 29 | -------------------------------------------------------------------------------- /policies/animations.md: -------------------------------------------------------------------------------- 1 | Allow Layout Animations Policy 2 | =========== 3 | 4 | The 'layout-animations' policy-controlled feature can be used in a document or frame to 5 | restrict the set of CSS properties which can be animated. This feature is proposed to 6 | ensure certain types of animations which *may* lead to layout and potentially heavy CPU 7 | load are blocked. 8 | 9 | What does that mean? 10 | ------------ 11 | 12 | In order to produce animations on the web, developers declare transitions of style 13 | in either CSS (e.g., `@keyframes` and `animation`) or JavaScript (e.g., `element.animate()`). 14 | In principal, these transitions can be used to animate just about any CSS property 15 | (backgrounds, sizes, margins, fonts, borders, positions amongst many other). 16 | 17 | In order to support such animations, the browser has to constantly update the values for 18 | all of these properties, and then calculate all their effects on the page; ideally, this has 19 | to has to be done sixty times per second. 20 | 21 | When properties affecting size or position are changed in an animation, many other 22 | elements on the page to have to be moved around constantly (*layout and re-layout*), and 23 | browsers can struggle to keep up. When that happens, the result is a potentially stuttering 24 | animation and a poorly performing and non-responsive web page; sometimes even the entire *machine* 25 | slows down, as the animation consumes all available CPU cycles. 26 | 27 | To avoid this scenario developers should use animations carefully and limit the usage to 28 | the animations which are not CPU intensive. One approach to motivate this practice is to 29 | limit the usage of animations that *can* cause expensive CPU work - such as *layout* -- 30 | on the page. This can be done by blocking layout-inducing animations. 31 | 32 | How is an animation blocked? 33 | ------------ 34 | 35 | Blocking an animation should be as non-intrusive as possible to avoid breaking current 36 | web pages that rely on animations. Essentially, when an animations is blocked it should 37 | still: 38 | - Fire all the animation related events (`animationstart`, `animationinterval`, `animationend`), 39 | - `transitionend` should fire as expected, 40 | - The intial and final style state should be respected. 41 | 42 | Some CSS properties are interpolable -- that is, there is a way for the 43 | browser to calculate a smooth transition from one value to another. This applies 44 | to most properties that have numeric values (lengths, sizes, etc.) as well as 45 | things like colors, paths and matrices. 46 | 47 | 48 | When properties are not interpolable -- there is no such thing as an 49 | intermediate state -- and such properties are "animated" by simply jumping 50 | from the initial to the final value at some point during the animation. 51 | 52 | The proposed method for blocking animations is similar to the concept of 53 | [discrete animations](https://drafts.csswg.org/web-animations-1/#discrete) 54 | (for noninterpolable animations) with 55 | [linear timing function](https://drafts.csswg.org/css-easing-1/#linear-timing-function-section): 56 | the animation involves a single jump at the midpoint of the animation interval. 57 | 58 | A potential solution: `layout-animations` policy-controlled feature 59 | ------------ 60 | 61 | With 'layout-animations' feature, developers are equipped with a switch to 62 | disable animations that *can* cause expensive layout work. This involves properties 63 | such as `top`, `width`, `max-height`, etc. 64 | 65 | With that feature available, a page could declare that it only uses animations that 66 | do not lead to layout, by delivering an HTTP header like this: 67 | 68 | ```http 69 | Feature-Policy: layout-animations 'none' 70 | ``` 71 | 72 | or it could do the same for a particular `iframe` element in the page: 73 | 74 | ```html 75 | 76 | ``` 77 | If a particular site needs to use all style properties for animations, 78 | then it can be granted the ability to do that, while still blocking 79 | animations from other sites: 80 | 81 | ```html 82 | 83 | ``` 84 | 85 | Future work based on `layout-animations`: 86 | ------------ 87 | 88 | To allow browsers room to innovate in this space, and grant developers the ability 89 | to make the final decision about the tradeoffs in their choice of enabled animations, 90 | a generic more syntactic `animation` feauture can be proposed based on list values. 91 | The developers can then choose the set of properties that should be allowed to run 92 | on their site. 93 | 94 | In practice, that would look something like this: 95 | 96 | ```html 97 | 98 | ``` 99 | 100 | That would apply a policy in which just those three properties can be animated 101 | (as well as any sub-properties, such as `border-top-color`). 102 | 103 | Feature policies combine in subframes, so if that frame embedded another, with 104 | the syntax: 105 | 106 | ```html 107 | 108 | ``` 109 | then the child frame would be allowed to animate just the `transform` property. 110 | 111 | First Steps in Implementing the Feautre 112 | ------------- 113 | As mentioned above, the policy will affect animated properties that cause layout; the actual list of such properties might be long and should be extracted from [CSS spec](https://drafts.csswg.org/). To implement a *first version of the policy*, the following animations should be included in `layout-animations`: 114 | ``` 115 | bottom, height, left, right, top, width 116 | ``` 117 | These properties are used quite often and on Chrome, they contribute to [almost](https://www.chromestatus.com/metrics/css/animated) 11.7% of total animation use cases. From the same data it can be inferred that (ignoring some non-layout and irrelevant properties such as `transform`, `visibility`, etc.), the overal share of such animations is as high as 34%; hence the justification for inclusion of these properties in the v1 of the policy. 118 | -------------------------------------------------------------------------------- /policies/decoding-image-default-sync.md: -------------------------------------------------------------------------------- 1 | decoding-image-default-sync Policy 2 | =========== 3 | 4 | The `decoding-image-default-sync` policy-controlled feature can be used for a main frame or a nested ` 48 | ``` 49 | which regards all the ``s with `decoding="auto"` or ``s that do not set the `decoding` attribute (hence default to `auto`) 50 | to be asynchronously decoded. 51 | 52 | The Extra Mile 53 | ----------- 54 | In general the feature could allow an expanded set of enforcement policies with the use of 55 | [parametric features](https://github.com/WICG/feature-policy/issues/163). Under a generalized `decoding-image` policy, 56 | the following potential values could be supported (in the order of permissiveness): 57 | * `default`: the policy does not affect the behavior of the `decoding` attribute, 58 | * `default-sync-off`: all the `decoding="auto"` attributes (and those not set for a ``) are regarded as `async`, 59 | * `sync-off`: all the `decoding="sync"` and `decoding="auto"` (and unset ``s) are interpretted as `decoding="async"` ( 60 | _could lead to a violation report_ if the `decoding` attribute for an `` is set to `sync`). 61 | -------------------------------------------------------------------------------- /policies/document-write.md: -------------------------------------------------------------------------------- 1 | # Document Stream Insertion Policy (Dynamic Mark-up) 2 | 3 | ## Objective 4 | The API around document stream modification ([dynamic mark-up insertion](https://www.w3.org/TR/2011/WD-html5-author-20110705/apis-in-html-documents.html#dynamic-markup-insertion)), i.e., `document.write`, `document.writeln`, `document.open` and `document.close` 5 | are anti-pattern, parser-blocking JavaScript API. The objective of the proposed feature is to limit the usage of this API in websites. 6 | 7 | ## Solution 8 | 9 | Introduce a new feature policy, namely, `document-write` to control the access to the mentioned API. When the feature is disabled for a specific origin in a frame, any usage of such API will be ignored and might 10 | lead to a DOMException[1](#notes). 11 | 12 | ## Usage 13 | The feature can be set through the HTTP headers in the response. For instance 14 | 15 | ``` 16 | Feature-Policy: document-write 'none' 17 | ``` 18 | 19 | which would disable the feature for all same and cross origin content. The feature can also be set for a given ` 24 | ``` 25 | would limit the usage of stream insertion API to only "www.google.com" origins using HTTPS protocol. 26 | 27 | ## Open Problems 28 | 29 | The main open problem with this feature is cross-site isolation breakage. The feature provides an embedder website with the 30 | power to arbitrarily turn off usage of some javascript APIs in an embedded site. If the embedded site relies on loading 31 | important security related contents through the disabled API[2](#notes), then the security of the embedded site 32 | might become compromised. Therefore, to avoid exposing sites which 33 | 34 | * allow being embedded in other websites, 35 | * rely on `document.write` for adding important scripts, 36 | 37 | to such attacks, the behavior of the feature for same-origin vs cross-origin might be different. The safest approach would be 38 | to either allow usage of such API when the content is cross-origin, or, disallow it by unloading the frame. This would remove 39 | the security concerns related to cross-site isolation. 40 | 41 | A more forgiving approach would only unload the frame if 42 | * The frame is cross-origin, 43 | * The site does not use `document-write` in its `Feature-Policy` header. 44 | 45 | In other words, if a site is familiar with the feature then it is reasonable to assume that they have considered the 46 | consequences of `document-write`. 47 | 48 | #### Notes 49 | 50 | 1: The _most_ correct behavior is not known yet. For now, Chrome's implementation behind the flag simply throws exception 51 | on API usage (for both same and cross origin). But this is not the final implementation. 52 | 53 | 2: An embedded website might rely on important `