Permissions-Policy Configuration Issues | Blue Frog Docs

Permissions-Policy Configuration Issues

Understanding and fixing Permissions-Policy header configuration problems

Permissions-Policy Configuration Issues

What This Means

Permissions-Policy (formerly Feature-Policy) is an HTTP header that allows websites to control which browser features and APIs can be used by the page and embedded iframes. Misconfiguration or absence of this header can lead to:

  • Unauthorized use of sensitive APIs (camera, microphone, geolocation)
  • Third-party scripts accessing features without consent
  • Privacy violations from embedded content
  • Unexpected battery drain from background features
  • Security vulnerabilities in cross-origin iframes
  • Failed security audits and compliance issues

Proper Permissions-Policy configuration is essential for security, privacy, and performance.

How to Diagnose

Check Current Policy

# Check if Permissions-Policy header is present
curl -I https://example.com | grep -i permissions-policy

# Example response:
# Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Browser DevTools

  • Open Network tab and inspect response headers
  • Look for Permissions-Policy header
  • Check Console for policy violation warnings

JavaScript Feature Detection

// Check if feature is allowed
if (document.featurePolicy) {
  console.log('Camera allowed:',
    document.featurePolicy.allowsFeature('camera'));
  console.log('Geolocation allowed:',
    document.featurePolicy.allowsFeature('geolocation'));

  // List all allowed features
  document.featurePolicy.allowedFeatures().forEach(feature => {
    console.log(feature);
  });
}

Online Tools

Common Issues

  • Missing Permissions-Policy header entirely
  • Overly permissive policies allowing all features
  • Blocking features the site actually needs
  • Not restricting third-party iframe permissions
  • Conflicting policies between headers and iframe attributes

General Fixes

  1. Set restrictive default policy - Block all features by default, allow only what's needed

    Permissions-Policy: camera=(), microphone=(), geolocation=(),
      payment=(), usb=(), magnetometer=(), gyroscope=(),
      accelerometer=(), ambient-light-sensor=()
    
  2. Allow specific features for same-origin

    Permissions-Policy: camera=(self), microphone=(self), geolocation=(self)
    
  3. Allow features for trusted origins

    Permissions-Policy: camera=(self "https://trusted-domain.com"),
      payment=(self "https://payment-provider.com")
    
  4. Use wildcard cautiously - Only for non-sensitive features

    Permissions-Policy: fullscreen=*, picture-in-picture=(self)
    
  5. Configure in web server

    # nginx
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=(self)";
    
    # Apache
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(self)"
    
  6. Control iframe permissions - Use allow attribute on iframes

    <iframe src="https://example.com"
            allow="camera 'none'; microphone 'none'; geolocation 'self'">
    </iframe>
    
  7. Common feature directives

    • camera - Camera access
    • microphone - Microphone access
    • geolocation - Location data
    • payment - Payment Request API
    • autoplay - Media autoplay
    • fullscreen - Fullscreen mode
    • accelerometer, gyroscope, magnetometer - Motion sensors
    • usb, bluetooth - Device APIs
  8. Test before deploying - Ensure needed features still work

    // Test geolocation
    navigator.geolocation.getCurrentPosition(
      (position) => console.log('Success:', position),
      (error) => console.error('Blocked by policy:', error)
    );
    

Platform-Specific Guides

Platform Guide
nginx Header Configuration
Apache mod_headers
Next.js Security Headers
Cloudflare Transform Rules
Netlify Custom Headers

Further Reading

// SYS.FOOTER