Permissions-Policy
Usage
The Permissions-Policy response header restricts which browser features are allowed in the current frame. Each policy pairs a feature directive with an allowlist defining which Origins access the feature.
Permissions-Policy: <directive>=<allowlist>
Directives
The directive name identifies the browser feature to control. A non-exhaustive list of standardized directives:
Allowlist values
The
Example
In the following example, the server indicates the geolocation feature shall be disabled in all contexts.
Permissions-Policy: geolocation=()
In the following example, the server indicates the encrypted-media feature shall be disabled for all Origins except for report.example.re.
Permissions-Policy: encrypted-media=("https://report.example.re")
In the following example, the server indicates the microphone feature shall be disabled for all Origins except itself and those with origin example.re.
Permissions-Policy: microphone=(self "https://example.re")
Blocking unload handlers to improve bfcache eligibility. This prevents third-party scripts and extensions from registering unload events degrading back-forward navigation performance.
Permissions-Policy: unload=()
Troubleshooting
Permissions-Policy violations appear silently in most cases, with the blocked feature returning a denied state or throwing an error without a visible browser prompt.
Feature blocked in an iframe due to missing allow attribute. Even when the parent page permits a feature, embedded iframes need an explicit allow attribute to access the feature. Add the attribute to the iframe tag:
Geolocation, camera, or microphone not working after setting the policy. A policy like Permissions-Policy: geolocation=() disables the feature for all origins, including the page itself. To allow the feature on the same origin only, use geolocation=(self). To allow a specific embedded origin as well, use geolocation=(self “https://maps.example.re”). The browser never prompts the user for a feature the policy has already denied.
Wildcard * not working for all features. Some features do not support the * allowlist value and are restricted to explicit origin lists. When * has no effect, specify each allowed origin individually. Check the browser console for warnings about unrecognized or unsupported allowlist values.
Migrating from Feature-Policy to Permissions-Policy. The legacy Feature-Policy header uses a different syntax: Feature-Policy: geolocation ‘self’ vs. Permissions-Policy: geolocation=(self). Browsers that support Permissions-Policy ignore Feature-Policy when both headers are present. Update the header name and convert the syntax: replace spaces with =, wrap origin lists in parentheses, and drop the single quotes around self and none (use () instead of ‘none’).
Debugging with document.featurePolicy.allowsFeature(). In Chromium-based browsers, open the DevTools Console and run document.featurePolicy.allowsFeature(‘camera’) to check whether a feature is allowed in the current context. This returns true or false. For iframe contexts, pass the origin as a second argument: document.featurePolicy.allowsFeature(‘camera’, ‘https://embed.example.re’). Firefox uses document.permissionsPolicy instead of document.featurePolicy.