v151 · Web APIs · Policy Reference

Policy Reference

Allowlist syntax, default values, sandbox interaction, and recommended header patterns for the focus-without-user-activation Permissions Policy directive.

directive behaviour

Property Value
Directive namefocus-without-user-activation
Default allowlist* (all origins — allowed by default, matching pre-Chrome 151 behaviour)
When allowedIframes may call element.focus() at any time, including without a prior user gesture
When deniedfocus() calls from within the iframe are silently ignored unless there is transient user activation in the iframe's frame
Top-level pagePolicy only constrains iframes — the top-level document is unaffected regardless of its own header
AffectsHTMLElement.focus(), window.focus(), autofocus attribute processing

header patterns

# Allow all origins (default — no change from pre-Chrome 151 behaviour)
Permissions-Policy: focus-without-user-activation=*

# Deny all iframes — iframes must have user activation to call focus()
Permissions-Policy: focus-without-user-activation=()

# Allow only same-origin iframes to focus without activation
Permissions-Policy: focus-without-user-activation=self

# Per-iframe override via allow attribute:

<!-- Explicitly allow a specific trusted embed to focus freely -->
<iframe src="https://trusted.example/"
        allow="focus-without-user-activation"></iframe>

<!-- Deny focus stealing for an ad or analytics iframe -->
<iframe src="https://ads.example/"
        allow="focus-without-user-activation 'none'"></iframe>

sandbox interaction

When an iframe uses the sandbox attribute, it has no user activation by default unless allow-user-activation is also granted. The focus-without-user-activation directive adds a further layer: even with allow-user-activation, the iframe must wait for an actual user gesture before its focus() calls are honoured if the directive is denied.
<!-- Sandbox without allow-user-activation:
     iframe has no activation at all → focus() blocked by sandbox -->
<iframe sandbox="allow-scripts allow-same-origin"
        src="https://embed.example/"></iframe>

<!-- Sandbox with allow-user-activation + focus policy denied:
     iframe can get activation via user gestures inside it,
     but cannot call focus() spontaneously -->
<iframe sandbox="allow-scripts allow-same-origin allow-user-activation"
        allow="focus-without-user-activation 'none'"
        src="https://embed.example/"></iframe>

recommended patterns

// Pattern 1: blanket deny for untrusted embeds
// Add to your HTTP response:
// Permissions-Policy: focus-without-user-activation=()
//
// Then selectively re-allow trusted partners via the allow attribute:
// <iframe allow="focus-without-user-activation" src="...">

// Pattern 2: detect and warn about focus theft in development
document.addEventListener('focusin', (e) => {
  if (!navigator.userActivation?.isActive) {
    console.warn('Focus moved without user activation:', e.target);
  }
}, { capture: true });

// Pattern 3: server-side opt-in for the whole page
// Permissions-Policy: focus-without-user-activation=self
// This allows same-origin iframes (e.g. component microfrontends)
// but blocks all cross-origin embeds from stealing focus.

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗