A Permissions-Policy Header Not Set finding means the response does not contain a Permissions-Policy header defining which origins may use selected browser features. Permissions Policy is the successor to the older Feature Policy mechanism and can restrict capabilities in the top-level document and embedded frames.
Permissions Policy is not a universal “turn it on and you are secure” header. It is a feature-governance mechanism that lets a site restrict browser capabilities such as geolocation, camera, microphone, fullscreen, and newer APIs. Because support and individual directives vary by browser, a good policy starts from the features your application actually uses rather than from a copied mega-list.
What Does “Permissions-Policy Header Not Set” Mean?
Scanner meaning
OWASP ZAP alert 10063-1 is a passive, beta, low-risk finding. It reports that eligible responses do not define a Permissions-Policy header.
Security meaning
Without an explicit policy, each browser feature falls back to its specification-defined default allowlist. A Permissions Policy can reduce unnecessary browser capability, especially for embedded third-party content, but absence alone does not prove an exploitable vulnerability.
How Scanners Detect This Finding
Permissions-Policy checks are typically passive and may be marked beta or low severity because the appropriate policy depends heavily on application features and browser support. ZAP also has a related finding for the deprecated Feature-Policy header, so migration can produce a different alert even after a team adds a modern policy.
Scanner output should therefore start a feature inventory rather than a copy-and-paste exercise. Determine which capabilities the page and its embedded frames actually need, then construct the narrowest tested policy that preserves those user journeys.
Practical Security Scenario
Consider a customer account page that never uses camera, microphone, or geolocation but embeds several third-party frames. Without an explicit policy, browser defaults and frame permissions determine what those documents may request. A restrictive Permissions Policy can remove entire categories of capability that the page does not need.
On a video-support page, the opposite is true: disabling camera and microphone globally would break the core function. The secure design is not “deny every feature,” but “deny by default where practical and grant only the minimum capability to the pages and origins that require it.”
Where This Control Should Be Applied
Permissions Policy is most useful on browser documents with embedded content or access to powerful web features. API-only services receive little direct benefit because the policy is enforced by the browser against document features rather than by the API server as an authorization mechanism.
Segment policies by application area when necessary. A static marketing site, conferencing page, geolocation-based store locator, and administrative console can share an origin while legitimately needing different browser capabilities. Route-specific policies often provide better least privilege than one broad site-wide header.
Why an Explicit Permissions Policy Helps
Modern browsers expose powerful features to web applications: camera, microphone, geolocation, display capture, fullscreen, autoplay, sensors, and more. User permission prompts remain important, but Permissions Policy lets the site define whether a feature is available to a document or embedded frame in the first place.
This is useful for least privilege. A marketing page with no need for geolocation or camera can explicitly disable them, while a video-support page can allow camera and microphone only where required.
The policy is not uniformly supported for every directive in every browser, so production design should use compatibility data and functional testing. It should be treated as a hardening layer rather than a universal authorization system.
How Permissions-Policy Allowlists Work
(): Disables a feature for the relevant policy scope.(self): Allows the feature for the current origin.*: Allows all origins and should be used only when that broad access is intentional.- Explicit origins: Specific origins can be added to an allowlist when a trusted embedded service needs the feature.
<iframe allow>: Frame-level allow attributes work together with the page-wide policy; an iframe cannot grant itself capability beyond the parent policy.- Legacy Feature-Policy: The old name and syntax changed. Do not assume a legacy Feature-Policy header is equivalent to a current Permissions-Policy deployment.
Related Ammune guides: HTTP security header not detected, API authorization vs authentication, and OWASP API8:2023 Security Misconfiguration.
A Restrictive Example
A site that does not use camera or microphone and only uses geolocation on its own origin could start with:
Permissions-Policy: camera=(), microphone=(), geolocation=(self), fullscreen=(self)Common Remediation Mistakes
- Copying an enormous “deny everything” policy without testing maps, conferencing, payments, SSO, media, or embedded support tools.
- Using the old Feature-Policy syntax under the new header name.
- Assuming a Permissions-Policy header alone replaces user permission prompts or application authorization.
- Forgetting iframe
allowrequirements for legitimate embedded experiences. - Using
*broadly just to silence scanner findings. - Failing to test browser compatibility for newer or experimental directives.
How to Build a Safe Permissions Policy
1. Inventory browser features and embedded content. Identify camera, microphone, geolocation, fullscreen, autoplay, payment, clipboard, display, AI/browser APIs, and cross-origin iframes that are part of legitimate user journeys.
2. Check each directive’s default behavior. Permissions Policy directives do not all share the same default allowlist. Review the specific directive and browser support before deciding whether an explicit restriction changes behavior.
3. Restrict sensitive features deliberately. Use the narrowest allowlist that supports the application—for example geolocation=() when geolocation should never be used, or a small trusted origin list when it is required.
4. Coordinate with iframe allow attributes. A parent response policy and an iframe’s allow attribute interact. Ensure embedded providers receive only the capabilities they need and test nested-frame behavior rather than configuring the top-level page alone.
5. Roll out with compatibility monitoring. Use supported reporting/observation mechanisms where practical, monitor client errors, remove the deprecated Feature-Policy header, and re-run the scanner after the final response is verified.
Configuration Examples
Permissions Policy can be centralized at an edge layer when every route has the same feature model, but many applications need route- or page-specific policy because only selected areas use camera, microphone, payment, or cross-origin iframes. Keep the policy readable and tied to documented product requirements.
NGINX
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(self)" always;Apache
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(self)"Application
Set different policies per route when application sections have different feature needs. A conferencing page and a static account page should not require the same capabilities.How to Test the Fix
- Open the application’s major user journeys and confirm that required features still function after the policy is applied.
- Inspect the final response for a syntactically valid Permissions-Policy header.
- Test embedded iframes because parent policy and iframe allow attributes interact.
- Use browser console and policy-reporting features where supported to identify blocked capabilities.
- Re-run ZAP and also check for the related “Deprecated Feature Policy Header Set” finding if the legacy header remains.
Test the policy in the browsers and embedded integrations your users actually run. Confirm that denied features fail in the intended contexts, allowed features still work, and cross-origin iframes have both a compatible response policy and appropriate allow attributes.
How to Think About Severity
ZAP rates 10063-1 as Low and the rule is currently beta. Missing Permissions Policy is best treated as attack-surface hardening, not as evidence that a browser permission has already been abused. The value is in reducing functionality that application code or third-party frames do not need.
Prioritize explicit restrictions for sensitive features and untrusted embedding scenarios. At the same time, avoid policies that are broader than your browser support model can reliably enforce; server-side authorization and user permission prompts remain essential controls.
How Ammune Fits
Permissions Policy limits selected browser capabilities. Ammune covers the server-side API surface those browser features may call into, providing discovery, traffic analysis, sensitive-data visibility, and runtime detection of abnormal behavior.
For example, blocking a third-party iframe from using geolocation is useful browser hardening, but the geolocation or account APIs behind the application must still enforce authentication, authorization, rate controls, and appropriate data exposure independently.
Production Remediation Checklist
- Inventory browser features used by each major application area.
- Review the default allowlist and browser support for every directive you plan to set.
- Block unnecessary sensitive capabilities with explicit empty allowlists where appropriate.
- Use explicit trusted origins for features required by cross-origin content.
- Coordinate the response policy with iframe
allowattributes. - Remove or migrate the deprecated
Feature-Policyheader. - Test camera, microphone, geolocation, fullscreen, payment, and other relevant workflows.
- Verify behavior in representative Chromium, Firefox, Safari, and managed enterprise clients where applicable.
- Monitor policy violations or client errors during rollout.
- Re-run ZAP and document intentional exceptions by route.
Frequently Asked Questions
Is Permissions-Policy the same as Feature-Policy?
Permissions Policy is the successor to Feature Policy, but the header name and syntax changed. Legacy examples should be reviewed before reuse.
Should I disable every feature?
Disable features the application does not need, but do not cargo-cult a deny list. Validate each directive against real browser functionality and embedded integrations.
Does Permissions-Policy stop a user from granting camera permission?
It can prevent the feature from being available to a document even before or in addition to user permission handling, depending on the feature and browser.
Is Permissions-Policy fully supported everywhere?
No. MDN currently marks the overall header as limited/experimental for some features, so compatibility testing is important.
What is the ZAP alert ID?
Permissions Policy Header Not Set is ZAP alert 10063-1.
Primary References
Reduce Browser Capability and API Attack Surface
Permissions Policy limits unnecessary browser features. Ammune helps reduce risk at the API boundary with discovery, behavioral visibility, sensitive-data analysis, and runtime protection.
