Skip to main content

Permissions-Policy.

Security Headers & TLS Config

Blocks third-party scripts from accessing camera, microphone, geolocation

What does this check test?

The `Permissions-Policy` header (formerly `Feature-Policy`) allows you to control which browser features and APIs can be used on your site and by embedded content. You can selectively enable or disable access to powerful features like camera, microphone, geolocation, payment, fullscreen, autoplay, and many more. Each feature can be allowed for `self` (your origin only), specific origins, all origins (`*`), or completely disabled (`()`).

Why does it matter?

Third-party scripts and iframes embedded on your site can silently access browser APIs like the camera, microphone, or geolocation without your knowledge. A compromised or malicious ad script could activate a user's microphone, request their location, or trigger payment dialogs. Permissions-Policy lets you enforce that only your own code can access sensitive APIs, limiting the capabilities of embedded third-party content. It also serves as documentation of your site's intended feature usage.

Who is affected?

Sites that embed third-party scripts (analytics, ads, chat widgets, social media embeds) benefit the most from Permissions-Policy. E-commerce sites should restrict payment API access to their own origin. Media sites should control camera/microphone access. Even sites that don't use these APIs should explicitly disable them to prevent abuse by injected scripts. The header is particularly important for sites that prioritize user privacy.

Where does this apply?

Set the `Permissions-Policy` header on all HTML page responses from your web server, CDN, or application middleware. The policy applies to the page and all embedded content (iframes, scripts). For iframes, you can also use the `allow` attribute for per-frame overrides, but the HTTP header provides the broadest protection.

How to fix it

Start by disabling features you do not use and restricting the rest to your own origin:
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(self), usb=(), magnetometer=(), gyroscope=(), fullscreen=(self)

Nginx

nginx
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(self)" always;

Node.js / Express

js
app.use((req, res, next) => {
  res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=(), payment=(self)');
  next();
});

Django

python
# settings.py — with django-permissions-policy
PERMISSIONS_POLICY = {
    'camera': [],
    'microphone': [],
    'geolocation': [],
    'payment': ['self'],
}

Flask

python
@app.after_request
def set_headers(response):
    response.headers['Permissions-Policy'] = 'camera=(), microphone=(), geolocation=(), payment=(self)'
    return response

Next.js

js
module.exports = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [{
        key: 'Permissions-Policy',
        value: 'camera=(), microphone=(), geolocation=(), payment=(self)'
      }]
    }];
  }
};

Spring Boot

java
http.headers().permissionsPolicy(
    policy -> policy.policy("camera=(), microphone=(), geolocation=(), payment=(self)")
);
Review the full list of controllable features on MDN and disable any you do not actively need.

References

AppVet checks Permissions-Policy automatically

Run a free security scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.

Run Audit