Also available in: Español · Português · Français · العربية
Permissions-Policy converter: header and iframe allow attribute
Convert a policy between its two spellings, and see exactly what changes between them.
What is Permissions Policy?
Permissions Policy is how a page says which browser features it and the things it embeds are allowed to use — the camera, the microphone, geolocation, fullscreen, payment requests and a few dozen others. It replaced Feature Policy, and it is delivered two ways: as a Permissions-Policy response header covering the whole document, and as an allow attribute on an individual iframe covering just that frame.
Both are defined in the same W3C specification, and both express the same idea: a feature name, followed by a list of origins that may use it. What is easy to miss is that the specification serialises that list in two different grammars, one for each delivery mechanism, and they do not look alike.
This converter takes either spelling and produces the other, then names every difference it applied. It is a translation tool rather than a policy generator: it does not decide what your policy should be, and it takes no view on which features you ought to restrict.
How to use it
- Say which spelling you are starting from. An iframe allow attribute, or a Permissions-Policy header value. The parser follows the grammar for whichever you pick, so a header pasted as an attribute will be reported as wrong rather than quietly accepted.
- Paste the value on its own. Without the attribute name, the surrounding quotes, or the header's field name and colon — just what sits inside. The sample buttons load five policies, each chosen to show a different part of the two grammars.
- Read both outputs and the three panels under them. One panel lists what the parser found in your input. One lists anything that will not survive the trip into a header. And one names the four ways the two grammars differ, so you can see which of them applied to your policy.
Four ways the two grammars differ
Section 5.1 of the specification gives the attribute an ABNF grammar of its own; section 5.2 says the header is a Structured Fields dictionary instead. The result is that `allow="geolocation 'self' https://example.com"` and `Permissions-Policy: geolocation=(self "https://example.com")` are the same policy written two ways, and four things change between them.
The quoting inverts. Keywords are quoted in the attribute and bare in the header; origins are the other way round, bare in the attribute and quoted strings in the header. The separator changes too: a semicolon between directives in the attribute, a comma in the header, because a dictionary's members are comma-separated. And blocking a feature is the keyword none in the attribute but an empty pair of brackets in the header — the word does not appear in a header at all.
The fourth is the one worth being careful about, because it silently reverses the meaning rather than failing. A feature written with nothing after it means opposite things in the two grammars. Empty brackets in a header are a list of no origins: nobody. A bare feature name in an attribute is not empty at all — section 5.1 says the allowlist then defaults to 'src', which is the origin of whatever that iframe loads. Convert one to the other without noticing and a blocked feature becomes an allowed one.
Honest limitations
There is one thing an attribute can say that a header cannot. The keyword 'src' means the origin of the document in the iframe's src attribute, and a response header is not attached to an iframe, so there is nothing for it to refer to. The specification is subtle here and worth reading carefully: section 4 says the keyword can appear in the text of allowlists in headers and attribute strings, so it is not a syntax error, and section 9 only resolves it when a target origin is given. In a header it parses and then does nothing. This tool reports that as a loss rather than as an error, because that is what the specification describes.
The same shape applies to feature names. Section 5.2 says that if a dictionary member does not name a feature the browser supports, the member is ignored by the processing steps. A typo in a header does not produce a warning anywhere; the directive simply has no effect. This converter checks that a name is spelled legally — letters, digits and hyphens — but it deliberately does not carry a list of supported features, because that list differs between browsers and versions and a stale copy would be worse than none.
One more thing worth knowing. The specification cites RFC 8941 for the header's grammar, and RFC 9651 replaced that document in 2024. The replacement adds two data types this header does not use, moves the grammar to an informative appendix and refines how parse failures are handled; it changes nothing about dictionaries, tokens or bracketed lists. So the citation is out of date and the behaviour is not — which is worth saying in full, because either half on its own is misleading.
Why is it free?
It is two small parsers and two serialisers, and your browser runs them as you type. No server is involved, so there is nothing to meter and no account to create.
Nothing is uploaded. The policy you paste stays in this tab.