demo · v137

SPC Error Probe

The bug fixed in v137 surfaces in one specific path: calling credentials.create({ payment }) in a cross-origin iframe without a fresh user activation. Before v137, you got SecurityError — wrong name, breaks e instanceof NotAllowedError error handlers. After v137, the spec-aligned NotAllowedError.

probing…
scenariospec error namepre-v137v137+
same-origin, no activationNotAllowedErrorNotAllowedErrorNotAllowedError
cross-origin iframe, with activationresolves / NotAllowedError on declinesamesame
cross-origin iframe, no activationNotAllowedErrorSecurityErrorNotAllowedError

A. same-origin, no activation

Calls create({ payment }) immediately on click — no user gesture inside the call site, though the click itself is a gesture.

awaiting…

B. “cross-origin iframe”, no activation

A sandboxed iframe (opaque origin = treated as cross-origin) calls the same API on load with no activation — exactly the path the v137 rename fixes.

awaiting…

the code

// Inside a cross-origin iframe, no user activation:
try {
  await navigator.credentials.create({
    publicKey: { /* ... */ },
    payment:   { /* ... */ },
  });
} catch (e) {
  // Spec: NotAllowedError (matches every other user-gated WebAuthn flow).
  // Pre-v137 Chrome: SecurityError -> breaks `e instanceof NotAllowedError`
  //                    checks copied from non-payment WebAuthn code.
  // Post-v137 Chrome: NotAllowedError.
  reportTo(e.name);
}

see also