Permissions-Policy (formerly Feature-Policy)
What is Permissions-Policy?
Permissions-Policy (formerly known as Feature-Policy) is an HTTP security header that allows website owners to control which browser features and APIs can be used by a webpage. This header provides granular control over powerful browser capabilities, enabling developers to enhance security, privacy, and performance by restricting access to potentially sensitive features.
The header works by specifying a policy that defines which origins (if any) can use specific browser features, such as geolocation, camera, microphone, fullscreen, and more.
Header Syntax
The Permissions-Policy header uses the following syntax:
Permissions-Policy: <feature>=<allowlist>
Permissions-Policy: <feature>=(), <feature>=<allowlist>
Where:
<feature>is the browser feature being controlled<allowlist>specifies which origins are allowed to use the feature
Evolution from Feature-Policy to Permissions-Policy
The header was originally named Feature-Policy but was renamed to Permissions-Policy to better reflect its purpose and align with the Permissions API. The functionality remains largely the same, but the syntax and some feature names have been updated.
Key changes:
- Header name changed from
Feature-PolicytoPermissions-Policy - Some feature names were updated for consistency
- Improved syntax for better readability
Common Features and Directives
Permissions-Policy provides control over numerous browser features:
| Feature | Description | Example Policy |
|---|---|---|
| accelerometer | Controls access to accelerometer sensor | accelerometer=() |
| ambient-light-sensor | Controls access to ambient light sensor | ambient-light-sensor=('self') |
| autoplay | Controls automatic media playback | autoplay=('self' https://example.com) |
| camera | Controls access to camera | camera=() |
| display-capture | Controls screen sharing capabilities | display-capture=('self') |
| document-domain | Controls ability to set document.domain | document-domain=() |
| encrypted-media | Controls Encrypted Media Extensions (EME) | encrypted-media=('self') |
| fullscreen | Controls fullscreen mode | fullscreen=() |
| geolocation | Controls access to geolocation | geolocation=('self' https://trusted.com) |
| gyroscope | Controls access to gyroscope sensor | gyroscope=() |
| magnetometer | Controls access to magnetometer sensor | magnetometer=() |
| microphone | Controls access to microphone | microphone=() |
| midi | Controls access to MIDI devices | midi=() |
| payment | Controls Payment Request API | payment=('self') |
| picture-in-picture | Controls picture-in-picture video | picture-in-picture=() |
| publickey-credentials-get | Controls Web Authentication API | publickey-credentials-get=() |
| screen-wake-lock | Controls screen wake lock | screen-wake-lock=() |
| sync-xhr | Controls synchronous XHR requests | sync-xhr=() |
| usb | Controls WebUSB API | usb=() |
| web-share | Controls Web Share API | web-share=('self') |
| xr-spatial-tracking | Controls WebXR device API | xr-spatial-tracking=() |
Policy Syntax Examples
Disable a feature completely:
Permissions-Policy: geolocation=()
Allow a feature for the current origin:
Permissions-Policy: camera=('self')
Allow a feature for specific origins:
Permissions-Policy: microphone=('self' https://trusted-audio.com)
Multiple features in one header:
Permissions-Policy: geolocation=(), camera=(), microphone=('self')
Security and Privacy Benefits
Enhanced security:
- Prevents malicious scripts from accessing sensitive device features
- Reduces attack surface by disabling unnecessary browser APIs
- Mitigates risks from third-party scripts and iframes
Improved privacy:
- Prevents unauthorized access to location, camera, microphone, etc.
- Limits tracking capabilities through sensor data
- Gives users more control over their data
Performance optimization:
- Disables resource-intensive features when not needed
- Reduces battery consumption on mobile devices
- Prevents background processes from using sensors
Best Practices
- Follow the principle of least privilege - disable all features by default and only enable what's necessary
- Be specific with allowlists - avoid using
*which allows all origins - Combine with other security headers for comprehensive protection:
- Test policies thoroughly - ensure they don't break required functionality
- Regularly review and update policies as your application evolves
Example Implementations
HTTP Response Header:
Permissions-Policy: geolocation=(), camera=(), microphone=(), accelerometer=(), gyroscope=(), magnetometer=(), payment=(), usb=()
Web Server Configuration Examples:
Apache (.htaccess):
Header set Permissions-Policy "geolocation=(), camera=(), microphone=(), accelerometer=(), gyroscope=(), magnetometer=(), payment=(), usb=()"
Nginx:
add_header Permissions-Policy "geolocation=(); camera=(); microphone=(); accelerometer=(); gyroscope=(); magnetometer=(); payment=(); usb=()";
Express.js (Node.js):
app.use((req, res, next) => {
res.setHeader('Permissions-Policy', "geolocation=(), camera=(), microphone=(), accelerometer=(), gyroscope=(), magnetometer=(), payment=(), usb=()");
next();
});
Common Use Cases
- Privacy-focused websites: Disable all unnecessary sensors and device access
- E-commerce platforms: Control payment and geolocation features
- Corporate intranets: Restrict camera and microphone access in sensitive environments
- Educational platforms: Manage screen sharing and device access in virtual classrooms
- Healthcare applications: Secure access to sensitive features in medical apps
- Government websites: Enhance citizen privacy by limiting tracking capabilities
Browser Support
Permissions-Policy is supported in modern browsers:
- Chrome 60+ (as Feature-Policy), 88+ (as Permissions-Policy)
- Firefox 74+ (partial support)
- Edge 88+
- Safari 14+ (partial support)
Migration from Feature-Policy
To migrate from Feature-Policy to Permissions-Policy:
- Update the header name:
- Feature-Policy: geolocation 'none' + Permissions-Policy: geolocation=() - Update feature names (some features were renamed):
- Feature-Policy: vibrate 'none' + Permissions-Policy: vibrate=() - Update allowlist syntax:
- Feature-Policy: camera 'self' https://trusted.com + Permissions-Policy: camera=('self' https://trusted.com)
Related Security Concepts
- Content Security Policy (CSP) - Complementary security mechanism
- HTTP Security Headers - Overview of important security headers
- Same-Origin Policy (SOP) - Fundamental web security model
- Cross-Origin Resource Sharing (CORS) - Cross-origin resource sharing mechanism
- Privacy Enhancing Technologies - Technologies that protect user privacy
- Referrer-Policy - Privacy-enhancing HTTP header
- Cross-Origin Opener Policy (COOP) - Cross-origin isolation mechanism
- Cross-Origin Embedder Policy (COEP) - Cross-origin isolation mechanism
Password Spraying
A cyberattack technique that tests common passwords against multiple accounts to avoid detection and gain unauthorized access.
POODLE (CVE-2014-3566)
POODLE is a security vulnerability that exploits SSL 3.0 fallback mechanisms, allowing attackers to decrypt secure communications through man-in-the-middle attacks.
