Security · Checked once per domain
Permissions-Policy headerWhat it checks and how to fix it
What it checks
Fetches the homepage and reads Permissions-Policy (or the legacy Feature-Policy). A missing or empty header fails. It then looks at eleven sensitive features (geolocation, camera, microphone, payment, usb, bluetooth, display-capture, midi, magnetometer, gyroscope, accelerometer): any set to * or to external origins gets a warning, none of them restricted gets a warning, and at least one restricted to () or (self) with none left open passes.
Why it matters
Permissions-Policy decides which powerful browser features your pages, and every iframe and third-party script on them, may use. Without it, an injected or compromised script, or an embedded ad, can prompt visitors for their camera, microphone or location under your domain's name. Turning off what you do not use costs nothing.
How to fix it
Send a policy that disables every feature you do not use, and limits the ones you do use to self.
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=(), bluetooth=(), display-capture=(), midi=(), magnetometer=(), gyroscope=(), accelerometer=()
nginx
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), bluetooth=(), display-capture=(), midi=(), magnetometer=(), gyroscope=(), accelerometer=()" always;
Apache
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), bluetooth=(), display-capture=(), midi=(), magnetometer=(), gyroscope=(), accelerometer=()"
Cloudflare: Rules → Transform Rules → Modify Response Header → set Permissions-Policy.
Rails (config/initializers/permissions_policy.rb)
Rails.application.config.permissions_policy do |policy|
policy.geolocation :none
policy.camera :none
policy.microphone :none
policy.payment :self
policy.usb :none
policy.gyroscope :none
policy.accelerometer :none
policy.magnetometer :none
policy.midi :none
end