b2KIT

Permissions Policy Generator

Build Permissions-Policy headers to control browser features like camera, microphone, geolocation, and payment APIs.

Tested tool guide Tested browser tools Checked August 16, 2026

What Permissions Policy Generator does, with a checked example

Every browser capability your pages can request, from camera and microphone to geolocation, payment, and USB, has a server-side switch. This generator turns a few choices into a ready-to-paste Permissions-Policy HTTP header: for each feature you pick an allowlist - no one, your own origin, all origins, specific origins, or the src keyword for iframe-controlled delegation - and it emits the serialized header. The thing users get wrong first: the header is purely restrictive. It cannot grant a feature a browser or page does not already allow, and a cross-origin iframe gets a feature only when its origin is literally named in the allowlist.

Worked example

A concrete input and expected output from the current implementation.

Input

Selections: camera: self plus https://meet.example.com; microphone: only https://voip.example.com; geolocation: no one; payment: all origins; fullscreen: self

Expected output

Permissions-Policy: camera=(self "https://meet.example.com"), microphone=("https://voip.example.com"), geolocation=(), payment=*, fullscreen=(self)

Each feature serializes as feature=allowlist. () blocks the feature for every origin including the site itself, * allows every origin, and quoted strings name the only extra origins permitted; self always refers to the origin that serves the header.

How the result is produced

1

Allowlist serialization

Each feature pair follows the grammar in the Permissions-Policy spec. A wildcard (*) allows every origin. An empty pair () allows no one, not even your own site. (self) covers only the origin serving the header. Quoted origins such as ("https://meet.example.com") name extra hosts. The special src keyword defers to each iframe's own src attribute and allow attribute. Entries in one pair are space-separated inside parentheses; features are comma-separated in the order you added them.

2

Where the header applies

The browser evaluates the policy for every document, including every embedded frame, from the header in the final response. The policy is the ceiling: an iframe's allow attribute can grant a feature only if the header already permits that origin or uses src or *. Most features default to self when no header is sent, so the header narrows or extends those defaults, and it only takes effect as a real HTTP response header from your server, proxy, CDN, or edge function.

Good uses

  • A site that never touches device hardware blocks camera, microphone, geolocation, and payment for every origin, including iframes, so no embedded widget or script can request them.
  • A page embedding a third-party videoconferencing or checkout iframe grants camera and microphone, or payment, to exactly that one origin and nothing else.
  • Before changing a deployed policy, or while debugging a feature blocked inside an embedded frame, generate the candidate header, apply it, and inspect the effective policy per frame in browser DevTools.

Limits and checks

  • It only takes away. Features the browser would otherwise allow stay allowed unless the header names them, and the header cannot enable hardware access or APIs the browser does not support.
  • The wildcard is broader than it reads: * allows the feature to every origin, including all cross-origin iframes and their subframes, not just your own pages.
  • Browser support is uneven. Chromium honors the longest feature list; Safari and Firefox implement fewer, and unsupported entries are silently ignored. Test the blocked state, because a supported block is a hard block.

Common questions

Can I set this from a meta tag or in JavaScript?

No. Permissions-Policy only works as an HTTP response header delivered by the server, proxy, CDN, or edge function; a meta tag or script assignment has no effect. The only in-document mechanism is the iframe allow attribute, and it can narrow what the header permits but never extend it.

Why is my cross-origin iframe still blocked when I set camera=(self)?

Because self names only the origin that sent the header. The iframe's origin must appear in the allowlist, for example camera=(self "https://meet.example.com"), or you can use src so the iframe's own src attribute decides. A sandboxed iframe may also need the allow-same-origin token before permissions apply.

References and verification

The example and behavioral notes were checked against the browser implementation. Standards and primary references below define the relevant format, formula, or platform behavior.

Related Tools