Permissions Policy

Your pages can see the camera. Do they need to?

Every page you serve can ask for the camera, the microphone, location, payment handlers and more — and so can every third-party frame you embed. Permissions Policy declares which of those your site actually uses and switches off the rest, with the browser reporting anything that tries.

What's at Stake

Capability your site never uses is still capability an attacker inherits.

A browser hands every document a large set of powerful features by default. Most sites use almost none of them, but the permission to ask is granted all the same — to your own pages, and to every cross-origin frame they embed. Injected script inherits that same surface. Narrowing it costs nothing in functionality if you were not using the feature, and removes an entire category of thing a compromise could attempt.

Default Permissive

Features are available whether you use them or not

Camera, microphone, geolocation, payment handlers, USB, serial and more are reachable from any page unless you say otherwise. Nothing prompts you to narrow that list, so most sites carry the full surface indefinitely without ever deciding to.

Inherited by Frames

Embedded content inherits what you didn't restrict

Third-party iframes operate inside the permissions your page grants them. A widget, an advert or an embedded player can reach for features you never intended it to have, and the request goes to your visitor carrying your site's name.

Credential Surface

Authentication APIs are reachable too

The same open default applies to credential APIs. A cross-origin frame able to invoke WebAuthn from inside your page is a meaningful risk on any site where a passkey ceremony carries weight — and it is a permission, so it can be withdrawn.

What Permissions Policy Does

Declare what you use. Switch off the rest.

One response header lists the features your site is permitted to use and who may use them. Report URI collects the violation reports, so you can see what your pages and their frames actually reach for before you enforce anything.

Feature Control

Per-feature allowlists, down to the origin

Each directive takes the form feature=(allowlist). An empty list switches the feature off for your page and every frame inside it; (self) keeps it for your own origin; naming an origin grants it to a specific third party and nobody else. You describe the shape of your site once and the browser enforces it on every request.

Build a policy with our free tool →
Violation Reporting

Find out who was reaching for what

When something requests a feature your policy does not permit, the browser reports it — naming the feature, the frame that asked, and the page it happened on. That is frequently the first time a team discovers an embedded widget has been quietly requesting location or camera access on their site.

Learn more about the Reporting API →
Safe Rollout

Report-only first, so a tight policy stays a decision

Send Permissions-Policy-Report-Only and the browser evaluates your policy and reports against it without withdrawing anything. You can write the restrictive policy you actually want on day one, watch what it would have affected, and enforce once the reports agree with your understanding of the site.

Learn more about protecting passkey ceremonies →
Get Started

Switch off what you never used. See who was asking.

One header. No code. Violation reports start arriving from your first visitor.

30-day free trial  ·  One header  ·  No code  ·  Cancel anytime

Detection

Reading an allowlist

The syntax is compact and the behaviour follows from it. Knowing how a directive reads is most of knowing what your policy will do.

Directive What it means
camera=() Switched off for your page and every frame inside it
microphone=(self) Available to your own origin only, denied to embedded content
geolocation=(self "https://example.com") Your origin plus one named third party, and nobody else
Permissions-Policy-Report-Only The policy is evaluated and reported, but nothing is withdrawn
Permissions-Policy The policy is enforced and violations are still reported
Feature-Policy The predecessor header this specification replaced

A feature you never listed keeps its browser default, so a policy is a list of decisions rather than an exhaustive inventory you have to complete before shipping.

Architecture

One response header. No code. No crawlers.

Permissions Policy is a browser standard and the reporting is built in beside it. The browser evaluates your policy on every page load and reports over the Reporting API, so what you learn describes the frames your real visitors were served rather than the ones a crawler happened to reach.

Start in report-only and nothing is withdrawn. One header is the entire deployment, and our free builder will write it for you.

Minimal setup — report-only, nothing withdrawn
Permissions-Policy-Report-Only: camera=(), microphone=(),
  geolocation=()

Reports travel over the Reporting API, so you will also need a Report-To group pointing at your Report URI endpoint — the exact header is on your Setup page. To enforce later, send the same directives as Permissions-Policy.

No code added to your pages

No crawler simulating page loads

Report-only mode withdraws nothing while you evaluate

Your site's performance is unaffected

Sees what embedded third parties request — not just your own code

Free Tool

Write your policy without reading the specification

Our Permissions Policy builder lists every feature the standard defines, lets you set an allowlist for each, and produces the finished header. It also understands the legacy Feature-Policy syntax, so an older header can be pasted in and translated rather than rewritten by hand.

It is free, needs no account, and nothing you enter leaves your browser.

Scope

One layer in the stack. Here's how it fits.

Permissions Policy governs which browser capabilities are reachable from your pages. It does not decide what code is allowed to load, and it does not tell you what that code contains — it is the capability layer, and it works alongside the rest.

Permissions Policy does Pairs with
Restricts powerful browser features CSP for load control — deciding what is allowed to execute at all
Constrains what embedded frames may do Frame Watch for frame inventory — knowing which frames are there in the first place
Protects credential ceremonies from frames Passkeys Protection for the authentication case in full
Reports what was requested and by whom Script Watch for dependency visibility — knowing whose code did the asking

Together, these form the browser-native security layer that sits between your application and the code executing around it.