How Permissions Policy Controls Browser APIs
The Permissions Policy HTTP response header is a modern web security standard that allows developers to selectively enable, disable, and delegate browser features and APIs. This article explains how the Permissions Policy operates, its syntax and execution model, how it blocks or modifies powerful JavaScript APIs (such as camera, microphone, and geolocation), and how it governs embedded third-party content like iframes.
What is Permissions Policy?
Permissions Policy (formerly known as Feature Policy) provides explicit control over the capabilities granted to a web document and its embedded resources. By declaring a policy via an HTTP header, site operators can lock down sensitive device hardware, background services, and browser behaviors before any client-side JavaScript executes.
How It Constrains JavaScript APIs
When an API is restricted via Permissions Policy, the browser alters the runtime behavior of the corresponding JavaScript interfaces:
- Automatic Request Rejection: If a script attempts
to invoke a restricted API (such as
navigator.geolocation.getCurrentPosition()ornavigator.mediaDevices.getUserMedia()), the browser immediately denies the request. It does not prompt the user for permission. - Standardized Error Handling: Calls to disabled
asynchronous APIs typically fail with a rejected Promise containing a
NotAllowedErroror aDOMException. - Availability Checks: The JavaScript Permissions API
(
navigator.permissions.query()) reflects these restrictions by returning a state of'denied'for policies disabled by the header.
Header Syntax and Directive Rules
The Permissions-Policy header uses Structured Field
Values. Each directive specifies a feature and an allowlist of
origins:
Permissions-Policy: geolocation=(self), camera=(), microphone=(self "https://trusted-partner.com")
The allowlist definitions operate as follows: * ()
(Empty list): The feature is completely disabled for the top-level
origin and all embedded frames. * self: The feature is
allowed only on the exact origin hosting the document. * *:
The feature is allowed for all origins, including third-party frames. *
"https://example.com": The feature is explicitly delegated
to a specific third-party origin.
Controlling Iframes and Third-Party Contexts
A major security risk in modern web applications comes from embedded third-party scripts and widgets. Permissions Policy governs execution across framing boundaries:
- Default Inheritance: By default, powerful APIs like geolocation, camera, and microphone are restricted in cross-origin iframes unless explicitly granted.
- The
allowAttribute: To pass permissions down to an<iframe>, the parent document must allow the feature in its HTTP header and explicitly grant it on the frame element:
<iframe src="https://trusted-partner.com/widget" allow="camera; microphone"></iframe>If the top-level document disables a feature (e.g.,
camera=()), no iframe can re-enable that feature regardless
of the allow attribute value.
Commonly Constrained APIs
The policy covers a wide range of powerful JavaScript capabilities, including:
- Geolocation API (
geolocation): Disables tracking of the user’s physical location. - Media Devices (
camera,microphone): Blocks audio and video capture. - Payment Request API (
payment): Prevents unauthorized checkout interfaces. - Fullscreen API (
fullscreen): Prohibits programmatic fullscreen transitions viaElement.requestFullscreen(). - Device Sensors (
accelerometer,gyroscope,magnetometer): Blocks access to hardware motion and orientation data to mitigate device fingerprinting. - Screen Capture (
display-capture): Prevents screen recording vianavigator.mediaDevices.getDisplayMedia().
Security Benefits
Implementing the Permissions Policy header reduces attack surface by applying the principle of least privilege. If a cross-site scripting (XSS) vulnerability occurs or a compromised third-party library attempts to access device hardware, the browser blocks the execution at the platform level, neutralizing the exploit before user data is compromised.