Permissions-Policy: what the header does and how to set it
Without a Permissions-Policy, embedded frames inherit access to camera, microphone and geolocation. squirrel reads the header once per site.
What Permissions-Policy is
Permissions-Policy is a response header that lists which browser features the page and anything it embeds may use. Each entry names a feature and an allowlist of origins, so camera=() disables the camera entirely and geolocation=(self) limits it to your own origin.
It matters most on pages that embed third-party frames. A cross-origin frame gets no camera, microphone or geolocation access unless you delegate it, and the header is where you decide which features are available to delegate at all. The header was called Feature-Policy until 2020 and the old name still parses in some browsers, with a different syntax.
What squirrel checks
The rule reads the response headers of the first crawled page and emits a single check named permissions-policy:
- Skipped when the crawl produced no pages. Message:
No pages to check. - Pass when a
Permissions-Policyheader is present, whatever it contains. Message:Permissions-Policy header present, with the first 100 characters of the policy as the value. - Info when only the legacy
Feature-Policyheader is present. Message:Using deprecated Feature-Policy header, withMigrate to Permissions-Policyas the value. - Info when neither header is present. Message:
No Permissions-Policy header, withConsider restricting browser featuresas the value.
The policy is not parsed and individual directives are not validated. Severity is info and the weight is 2, the lowest in the Security category.
How to fix it
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Set it on HTML responses. Empty parentheses disable a feature for the document and every frame inside it. Name your own origin, as in geolocation=(self), for the features the page genuinely uses. Delegating a feature to an embedded partner takes two steps: list their origin in the header and add a matching allow attribute on the iframe.
| Rule ID | security/permissions-policy |
| Category | Security |
| Scope | Site-wide |
| Severity | info |
| Weight | 2/10 |
Enable / disable
Disable this rule
[rules]
disable = ["security/permissions-policy"]Disable all Security rules
[rules]
disable = ["security/*"]Enable only this rule
[rules]
enable = ["security/permissions-policy"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- security/csp: which origins may load code, as opposed to which features that code may reach.
- security/x-frame-options: who may embed you, the mirror of what you embed.
- security/third-party-cookies: an inventory of the frames and scripts a policy would apply to.
- security/referrer-policy: the other privacy-facing response header.
Security findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Security section of the report. The header your server sent is reported once for the site. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.