files/en-us/web/http/reference/headers/permissions-policy/index.md
{{SeeCompatTable}}
The HTTP Permissions-Policy {{Glossary("response header")}} provides a mechanism to allow and deny the use of browser features in a document or within any {{HTMLElement("iframe")}} elements in the document.
For more information, see the main Permissions Policy article.
<table class="properties"> <tbody> <tr> <th scope="row">Header type</th> <td>{{Glossary("Response header")}}</td> </tr> </tbody> </table>Permissions-Policy: <directive>=<allowlist>
<directive>
allowlist to. See Directives below for a list of the permitted directive names.<allowlist>
: An allowlist is a list of origins that takes one or more of the following values contained in parentheses, separated by spaces:
* (wildcard)
<iframe>s) regardless of their origin.() (empty allowlist)
<iframe> allow attributes is 'none'.self
<iframe>s) in the same origin only. The feature is not allowed in cross-origin documents in nested browsing contexts. self can be considered shorthand for https://your-site.example.com. The equivalent for <iframe> allow attributes is self.src
<iframe>, as long as the document loaded into it comes from the same origin as the URL in its {{HTMLElement('iframe','src','#Attributes')}} attribute. This value is only used in the <iframe> allow attribute, and is the default allowlist value in <iframe>s."<origin>"
"https://a.example.com"). Origins should be separated by spaces. Note that origins in <iframe> allow attributes are not quoted.The values * and () may only be used on their own, while self and src may be used in combination with one or more origins.
[!NOTE] Directives have a default allowlist, which is always one of
*,self, ornonefor thePermissions-PolicyHTTP header, and governs the default behavior if they are not explicitly listed in a policy. These are specified on the individual directive reference pages. For<iframe>allowattributes, the default behavior is alwayssrc.
Where supported, you can include wildcards in Permissions Policy origins. This means that instead of having to explicitly specify several different subdomains in an allowlist, you can specify them all in a single origin with a wildcard.
So instead of
("https://example.com" "https://a.example.com" "https://b.example.com" "https://c.example.com")
You can specify
("https://example.com" "https://*.example.com")
[!NOTE]
"https://*.example.com"does not match"https://example.com".
{{httpheader('Permissions-Policy/accelerometer','accelerometer')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/ambient-light-sensor','ambient-light-sensor')}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/aria-notify", "aria-notify")}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/attribution-reporting','attribution-reporting')}} {{deprecated_inline}}
{{httpheader('Permissions-Policy/autoplay','autoplay')}} {{Experimental_Inline}}
NotAllowedError {{domxref("DOMException")}}. The autoplay attribute on {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements will be ignored.{{httpheader('Permissions-Policy/bluetooth','bluetooth')}} {{Experimental_Inline}}
false or reject the returned {{JSxRef("Promise")}} with a SecurityError {{DOMxRef("DOMException")}}.{{httpheader('Permissions-Policy/browsing-topics','browsing-topics')}} {{deprecated_inline}} {{non-standard_inline}}
NotAllowedError {{domxref("DOMException")}}.{{httpheader('Permissions-Policy/camera', 'camera')}} {{experimental_inline}}
NotAllowedError {{DOMxRef("DOMException")}} if the permission is not allowed.{{HTTPHeader('Permissions-Policy/captured-surface-control', 'captured-surface-control')}} {{experimental_inline}}
NotAllowedError {{DOMxRef("DOMException")}} if the permission is not allowed.{{HTTPHeader('Permissions-Policy/ch-ua-high-entropy-values', 'ch-ua-high-entropy-values')}} {{experimental_inline}}
brands, mobile, and platform low-entropy data.{{httpheader('Permissions-Policy/compute-pressure','compute-pressure')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/cross-origin-isolated','cross-origin-isolated')}} {{Experimental_Inline}}
{{HTTPHeader('Permissions-Policy/deferred-fetch', 'deferred-fetch')}} {{experimental_inline}}
fetchLater() quota.{{HTTPHeader('Permissions-Policy/deferred-fetch-minimal', 'deferred-fetch-minimal')}} {{experimental_inline}}
fetchLater() quota.{{HTTPHeader('Permissions-Policy/display-capture', 'display-capture')}} {{experimental_inline}}
getDisplayMedia() will reject with a NotAllowedError {{DOMxRef("DOMException")}} if permission is not obtained to capture the display's contents.{{httpheader('Permissions-Policy/encrypted-media', 'encrypted-media')}} {{Experimental_Inline}}
SecurityError {{domxref("DOMException")}}.{{httpheader('Permissions-Policy/fullscreen','fullscreen')}} {{experimental_inline}}
{{httpheader('Permissions-Policy/gamepad','gamepad')}} {{Experimental_Inline}}
SecurityError {{domxref('DOMException')}}, and the {{domxref("Window.gamepadconnected_event", "gamepadconnected")}} and {{domxref("Window.gamepaddisconnected_event", "gamepaddisconnected")}} events will not fire.{{httpheader('Permissions-Policy/geolocation','geolocation')}} {{experimental_inline}}
PERMISSION_DENIED.{{httpheader('Permissions-Policy/gyroscope','gyroscope')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/hid','hid')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/identity-credentials-get','identity-credentials-get')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/idle-detection','idle-detection')}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/language-detector", "language-detector")}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/local-fonts','local-fonts')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/magnetometer','magnetometer')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/microphone','microphone')}} {{experimental_inline}}
NotAllowedError {{domxref("DOMException")}}.{{httpheader('Permissions-Policy/midi', 'midi')}} {{Experimental_Inline}}
SecurityError {{domxref("DOMException")}}.{{httpheader("Permissions-Policy/on-device-speech-recognition", "on-device-speech-recognition")}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/otp-credentials", "otp-credentials")}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/payment', 'payment')}} {{Experimental_Inline}}
SecurityError {{domxref("DOMException")}}.{{httpheader('Permissions-Policy/picture-in-picture', 'picture-in-picture')}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/private-state-token-issuance','private-state-token-issuance')}} {{Experimental_Inline}}
token-request operations.{{httpheader('Permissions-Policy/private-state-token-redemption','private-state-token-redemption')}} {{Experimental_Inline}}
token-redemption and send-redemption-record operations.{{httpheader("Permissions-Policy/publickey-credentials-create", "publickey-credentials-create")}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/publickey-credentials-get", "publickey-credentials-get")}} {{experimental_inline}}
{{httpheader('Permissions-Policy/screen-wake-lock', 'screen-wake-lock')}} {{experimental_inline}}
{{httpheader('Permissions-Policy/serial','serial')}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/speaker-selection", "speaker-selection")}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/storage-access", "storage-access")}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/translator", "translator")}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/summarizer", "summarizer")}} {{Experimental_Inline}}
{{httpheader('Permissions-Policy/usb', 'usb')}} {{Experimental_Inline}}
{{httpheader("Permissions-Policy/web-share", "web-share")}} {{experimental_inline}}
{{httpheader("Permissions-Policy/window-management", "window-management")}} {{experimental_inline}}
{{httpheader("Permissions-Policy/xr-spatial-tracking", "xr-spatial-tracking")}} {{Experimental_Inline}}
To allow all origins access to geolocation, you would do this:
Permissions-Policy: geolocation=*
Or to allow access to a subset of origins, you'd do this:
Permissions-Policy: geolocation=(self "https://a.example.com" "https://b.example.com")
Several features can be controlled at the same time by sending the header with a comma-separated list of policies, or by sending a separate header for each policy.
For example, the following are equivalent:
Permissions-Policy: picture-in-picture=(), geolocation=(self https://example.com/), camera=*
Permissions-Policy: picture-in-picture=()
Permissions-Policy: geolocation=(self https://example.com/)
Permissions-Policy: camera=*
For an <iframe> to have a feature enabled its allowed origin must also be in the allowlist for the parent page. Because of this inheritance behavior, it is a good idea to specify the widest acceptable support for a feature in the HTTP header, and then specify the subset of support you need in each <iframe>.
To allow all origins access to geolocation, you would do this:
<iframe src="https://example.com" allow="geolocation *"></iframe>
To apply a policy to the current origin and others, you'd do this:
<iframe
src="https://example.com"
allow="geolocation 'self' https://a.example.com https://b.example.com"></iframe>
This is important: By default, if an <iframe> navigates to another origin, the policy is not applied to the origin that the <iframe> navigates to. By listing the origin that the <iframe> navigates to in the allow attribute, the Permissions Policy that was applied to the original <iframe> will be applied to the origin the <iframe> navigates to.
Several features can be controlled at the same time by including a semi-colon-separated list of policy directives inside the allow attribute.
<iframe
src="https://example.com"
allow="geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"></iframe>
It is worth giving the src value a special mention. We mentioned above that using this allowlist value will mean that the associated feature will be allowed in this <iframe>, as long as the document loaded into it comes from the same origin as the URL in its {{HTMLElement('iframe','src','#Attributes')}} attribute. This value is the default allowlist value for features listed in allow, so the following are equivalent:
<iframe src="https://example.com" allow="geolocation 'src'"></iframe>
<iframe src="https://example.com" allow="geolocation"></iframe>
SecureCorp Inc. wants to disable Microphone (for example {{domxref("MediaDevices.getUserMedia()")}}) and {{domxref("Geolocation")}} APIs in its application. It can do so using the following response header:
Permissions-Policy: microphone=(), geolocation=()
By specifying () for the origin list, the specified features will be disabled for all browsing contexts (this includes all <iframe>s), regardless of their origin.
<iframe> policiesFor example, let's say that we wanted to enable geolocation usage on our own origin, and in embedded content coming from our trusted ad network. We could set up the page-wide Permissions Policy like this:
Permissions-Policy: geolocation=(self https://trusted-ad-network.com)
Over in our ad <iframe>s, we could set access to the https://trusted-ad-network.com origin like this:
<iframe src="https://trusted-ad-network.com" allow="geolocation"></iframe>
If a different origin ended up getting loaded into <iframe>, it would not have access to geolocation:
<iframe src="https://rogue-origin-example.com" allow="geolocation"></iframe>
{{Specifications}}
{{Compat}}