· 5 min read ·

Passkeys Grow Up: What Chrome's 2026 Identity Stack Actually Solves

Source: chrome-devblog

Google’s I/O 2026 web identity session landed with the usual mix of recap and roadmap. The Chrome developer blog post frames it as a modernization story: passkeys for primary auth, the Digital Credentials API for verified identity, and a growing set of signal APIs to keep credentials healthy over time. That framing is fine as far as it goes, but it skips the part developers care about, which is what actually changed in the last twelve months and whether the rough edges from 2024 and 2025 are gone.

I want to focus on three things the session points at without fully unpacking: the signal API for syncing passkey state between sites and providers, the Digital Credentials API moving past its origin trial, and the quiet but important shift in how related origins are handled. These are the pieces that decide whether a passkey rollout in 2026 is smooth or whether you end up rebuilding password fallback flows six months later.

The signal API closes the orphan-credential loop

The original WebAuthn spec had a quiet problem. A site registers a passkey, the user later deletes their account or rotates the credential, and the passkey provider (iCloud Keychain, Google Password Manager, 1Password, Bitwarden) keeps showing the now-dead credential forever. Users see a passkey for example.com, tap it, get an authentication failure, and conclude that passkeys are broken.

The Signal API, shipped in Chrome 132 and now broadly available, lets the relying party push state back to the provider. Three signals matter:

// Tell providers a credential is no longer valid
await PublicKeyCredential.signalUnknownCredential({
  rpId: 'example.com',
  credentialId: 'base64url-encoded-id',
});

// Reconcile the full list after a server-side change
await PublicKeyCredential.signalAllAcceptedCredentials({
  rpId: 'example.com',
  userId: 'base64url-user-handle',
  allAcceptedCredentialIds: ['id1', 'id2'],
});

// Update the displayed username after a profile change
await PublicKeyCredential.signalCurrentUserDetails({
  rpId: 'example.com',
  userId: 'base64url-user-handle',
  name: 'alice@example.com',
  displayName: 'Alice',
});

The practical impact is bigger than it sounds. Before this, the recommended pattern was to silently fail the assertion and show the user a password fallback, which trained people to distrust passkeys. With signals, the dead credential disappears from the autofill sheet and the system UI, and the failure rate on the next login attempt drops to roughly what you’d see for a fresh credential. The FIDO Alliance UX guidelines updated in late 2025 now treat signal calls as a baseline expectation, not a nice-to-have.

If you’ve already deployed passkeys, the migration is mechanical. After any account deletion, credential revocation, or email change, fire the matching signal. The provider decides what to do with it; Google Password Manager and iCloud Keychain both honor signalUnknownCredential by removing the entry, while some third-party managers still treat it as advisory. Either way, the relying party has done its job.

Digital Credentials moves from origin trial to baseline

The Digital Credentials API was the more speculative half of the 2025 story. It lets a website request a verified credential, like a mobile driver’s license or an EU Digital Identity Wallet attestation, through the same kind of mediated browser flow as WebAuthn. Chrome ran the origin trial through 2025, and the shipping version in Chrome 138 cleaned up the request shape considerably.

A typical age-verification request now looks roughly like this:

const credential = await navigator.credentials.get({
  digital: {
    requests: [{
      protocol: 'openid4vp',
      data: {
        client_id: 'https://example.com',
        nonce: serverNonce,
        presentation_definition: {
          id: 'age-over-18',
          input_descriptors: [{
            id: 'mdl',
            format: { mso_mdoc: { alg: ['ES256'] } },
            constraints: {
              fields: [{
                path: ["$['org.iso.18013.5.1']['age_over_18']"],
                intent_to_retain: false,
              }],
            },
          }],
        },
      },
    }],
  },
});

The shape borrows from OpenID for Verifiable Presentations and the ISO/IEC 18013-5 mDL standard, which is the right call. It means a relying party that already integrates with a wallet over OID4VP can reuse most of its verifier logic. The browser’s contribution is the mediated UI, the same-origin guarantees, and the cross-device flow that hands off to a phone holding the credential.

The interesting design choice is that Chrome does not verify the presentation itself. The browser returns the signed response, and the server validates the issuer signature, the nonce, and the disclosed attributes. This keeps the browser out of the trust chain, which matters for jurisdictions where the list of acceptable issuers is regulated. The W3C Federated Identity Working Group has been explicit that this separation is intentional, partly to avoid the browser becoming a global certificate authority for government IDs.

The rough edge here is the wallet ecosystem. On Android, Google Wallet and Samsung Wallet both respond to the API; on iOS, Safari has its own equivalent but the cross-browser story for mDLs issued in non-US states is still patchy. If you’re building age verification for a global audience in 2026, you’ll still need a server-side fallback for users whose wallet doesn’t speak OID4VP yet.

The quiet win is Related Origin Requests, which solved a problem nobody outside of large enterprises noticed but everyone inside them complained about constantly. A company with example.com, example.co.uk, and example-cdn.net used to need a separate passkey per domain because the relying party ID was bound to the eTLD+1.

The fix is a .well-known/webauthn file at the relying party ID origin listing the related origins:

{
  "origins": [
    "https://example.com",
    "https://example.co.uk",
    "https://example.de",
    "https://login.example-corp.net"
  ]
}

Chrome fetches the file during registration and assertion, and treats the listed origins as valid for the same RP ID. The WebAuthn Level 3 spec formalized this in 2025, and Safari and Firefox both shipped support by early 2026. The list is capped at five origins by default in Chrome, which has caused some grumbling from companies with sprawling brand portfolios, but the cap is there to keep the file fetchable and the trust surface bounded.

What the recap doesn’t say

The I/O session is upbeat, and the underlying tech genuinely is better than it was. But there are two things worth keeping in mind before you rip out password auth.

First, passkey recovery is still the user’s problem. If someone loses their phone and their cloud account in the same week, no amount of signal API plumbing will help them get back in. Every serious deployment I’ve seen in the last year keeps a recovery path that’s either an email magic link, a customer support flow, or a hardware security key registered as a second credential. The Cloudflare team wrote up their experience with this in late 2025 and the takeaway is that passkeys reduce password resets by a lot but don’t eliminate the recovery surface.

Second, the cross-device QR flow is still slow. The hybrid transport handshake takes ten to fifteen seconds on a good network, longer on a flaky one, and users on desktop logging into a service for the first time on a new laptop will feel it. Chrome 140 added some caching improvements that help on subsequent uses, but the first-time cost remains. If your conversion funnel is sensitive to a fifteen-second pause, test the hybrid flow before you make it the primary path.

The 2026 stack is the first version of web identity where you can build a primary-passkey login without a long list of caveats in the design doc. The signal API closes the lifecycle loop, the Digital Credentials API gives you a real path for verified attributes, and related origins finally make enterprise rollouts tractable. The remaining work is on the deployment side: pick recovery paths that match your risk tolerance, instrument the hybrid flow, and treat the signal calls as part of every account-mutation code path rather than an afterthought.

Was this interesting?