CentralCSP
FeaturesBuildersPermissions-Policy

Builder decision rules

The rules the Permissions-Policy builder follows to turn feature reports into grants, flag noise and third-party scripts, and write the header value.

Last update:

The Permissions-Policy builder suggests every grant from rules you can check. Knowing them tells you when to trust a default and when to overrule it.

From a report to a grant

The builder reads two report types. Each report names a feature and who asked for it, and the builder turns that into the grant that would allow it:

Browser reportedSuggested grant
A Permissions-Policy violation: one of your pages used the featureself
A potential-permissions-policy-violation: an iframe from another origin asked for the feature in its allow attributeThe frame's origin, such as "https://pay.example.com", flagged From frame
A potential violation from a frame with no origin (a relative src or a srcdoc frame), or from your own originself

The builder grants origins, not full URLs. A frame from https://pay.example.com/checkout?step=2 becomes a grant to https://pay.example.com.

Both report types can be forged by anyone who knows your endpoint. A feature name the header grammar does not allow, or a frame src that is not a plain http or https origin, never becomes a row, so it cannot reach a generated header.

Frames and potential violations

An iframe asks for a feature in its allow attribute. The browser reports that request as a potential violation, which the Permissions Policy reports page shows in its Potential view:

product.html
<iframe src="https://video.example.com/embed/42" allow="fullscreen; autoplay"></iframe>

This frame produces one row under fullscreen and one under autoplay, both for https://video.example.com. Delegating a feature takes both halves: the header grants it to the frame's origin, and the iframe keeps naming it in allow. For the header and attribute model, refer to the iframe allow attribute. When you grant a feature to a frame origin, the deploy step shows Frames need their allow attribute too as a reminder.

Third-party scripts

For a feature your own pages used, the reports name the script that made each call. The builder sorts each script into one of three groups: your own code (served from your website's origin), another origin's script, or a browser extension.

When every call came from another origin's script or an extension, the self row is flagged Third-party script and starts rejected. Granting the feature to self would hand it to that script too, because a script runs with the permissions of the page that loads it. When at least one call came from your own code, the row starts granted.

Noise

Noise is a reported row that your site does not need. The builder flags a row as noise in either of these cases:

  • It has fewer than 10 reports in the period.
  • Every call behind it came from a browser extension, which runs on the visitor's machine, not on your site.

The details panel also notes when only one browser reported a row while your site sees several, but that signal never makes a row noise on its own. Only Chromium browsers send these reports, so most sites see a single browser.

Noise starts rejected, but it is only a default. A rarely used page, such as a yearly campaign, can report a feature fewer than 10 times and still need it. Check the Noise filter before you deploy.

Starting presets

Browsers never report the Permissions-Policy a page was served with, so the builder cannot detect the policy you send today. It starts from one of these:

Starting policyValue
Deny every listed feature (default)Every feature of the catalog set to ()
Payment page baselinepayment=(self) and publickey-credentials-get=(self), every other catalog feature set to ()
Allow camera and microphonecamera=(self), microphone=(self), and fullscreen=(self), every other catalog feature set to ()
Your own policyThe value you paste, up to 16,384 characters

A grant from the starting policy stays granted, even when the reports flag it. The review then adds what your site was reported using.

When you paste your own policy

The builder reads the value as a Permissions-Policy header value, without the header name:

  • Every feature it sets is kept, including features outside the catalog.
  • In each allowlist, it keeps self, src, *, and plain http or https origins, and drops anything else.
  • It drops parameters such as report-to, and ignores a member that is not feature=allowlist.
  • A catalog feature your policy does not set keeps the browser default, unless the reports or your decisions add it.

A pasted policy lives only in the open page. After a reload, the builder falls back to Deny every listed feature.

Feature catalog

The builder lists 25 features, the ones broadly shipped and meaningful to lock down. The presets set all of them, so the header denies every one you do not grant:

FeatureWhat it lets a page do
accelerometerRead the motion sensor behind tilt and shake gestures
autoplayStart video and audio without the visitor pressing play
browsing-topicsShare the interests the browser inferred from the visitor's history with ad scripts (the Topics API)
cameraUse the device's camera, once the visitor allows it
clipboard-readRead what the visitor copied to the clipboard
clipboard-writeWrite to the clipboard, as a Copy button does
display-captureCapture the screen or a window, as screen sharing does
encrypted-mediaPlay DRM-protected video or audio through Encrypted Media Extensions
fullscreenShow an element full screen, such as a video player or a gallery
gamepadRead game controllers
geolocationRead the visitor's location, once they allow it
gyroscopeRead the device's orientation sensor
idle-detectionDetect when the visitor is idle or has locked the screen
local-fontsList and use the fonts installed on the visitor's device
magnetometerRead the device's compass sensor
microphoneUse the device's microphone, once the visitor allows it
midiTalk to MIDI devices such as music keyboards
paymentOpen the browser's own checkout sheet (the Payment Request API)
picture-in-picturePlay a video in a floating window above other apps
publickey-credentials-getSign the visitor in with a passkey or a security key
screen-wake-lockKeep the screen on, such as while a boarding pass is shown
serialTalk to serial devices plugged into the computer
storage-accessLet embedded third-party content ask for access to its own cookies
usbTalk to USB devices plugged into the computer
xr-spatial-trackingRun virtual and augmented reality sessions (WebXR)

A reported feature outside the catalog gets its own group in the review table too, after the catalog features. It ends up in the header either granted or as ().

How the header is written

The builder writes the policy as one comma-separated line:

  • Features come in catalog order, then any other feature in alphabetical order, so the header reads the same from any start.
  • A feature with nothing granted is written (), which denies it everywhere, including in frames.
  • self comes first in an allowlist, then each origin in double quotes.
  • A feature granted to * is written * alone, whatever else it lists.
  • No report-to parameter is written. The reports go to the default endpoint of the Reporting-Endpoints header, which the builder declares next to centralcsp.

For example, a policy that grants payment to your pages and to a payment frame, and denies the rest, reads like this, shortened here to five features:

Permissions-Policy-Report-Only: accelerometer=(), autoplay=(), browsing-topics=(), camera=(), payment=(self "https://pay.example.com")

The real header lists every catalog feature. For the full example, refer to Get started.

Periods and limits

The builder reads up to the last 30 days of reports. A website that sends a very large volume of reports is limited to 7 days at a time.

On such a website, the Period step says This website sends a lot of reports, so the builder reads only its last 7 days, and the 14 days and 30 days options are hidden. If a period holds more reports than the builder can read in time, the page shows This period holds too many reports to analyze in time. Pick a shorter period. Pick fewer days and continue.

The API applies the same rules. The Build a recommended Permissions-Policy endpoint defaults to the last 7 days and covers up to 30. Without a starting policy, it starts from Deny every listed feature. Each user can call it 10 times per minute. Refer to the API reference.

Next steps

On this page