Passkeys Aren’t Enough: Ship Device‑Bound Sessions in 90 Days

By Diogo Hudson Dias
Security engineer in a São Paulo office analyzing session security metrics on a large monitor with a Chrome browser window visible and a hardware security key on the desk.

Passkeys killed most password phish. Attackers adapted. They stopped chasing your login box and started stealing the thing you trust more than passwords: long‑lived session tokens. Chrome is now rolling out device‑bound sessions, and OAuth finally has a practical proof‑of‑possession story. If you don’t plan for this in the next 90 days, you’re budgeting for account takeover claims.

What just changed (and why you should care)

Two signals landed at once. First, Chrome began adopting what it calls device‑bound sessions (widely reported as the strongest browser‑level defense yet against account takeovers). Translation: a browser‑managed key binds a session to a specific device so a stolen cookie can’t be replayed elsewhere. Second, new research surfaced fresh pitfalls in real‑world passkey deployments—clever social engineering and recovery gaps that route around WebAuthn entirely. Together, they confirm what your incident queue already knows: passkeys harden step one, but tokens decide who wins.

None of this is theoretical. Reverse‑proxy phishing kits (Evilginx et al.) and commodity infostealers target session cookies precisely because they bypass 2FA and passkeys. Ask any SaaS at scale: stolen session reuse outnumbers classic password phish by a wide margin. Passkeys aren’t the end state; device‑bound sessions are.

Update your 2026 threat model

  • Primary adversary behavior: Replay of stolen sessions and refresh tokens obtained via malware, reverse proxies, or misconfigured third‑party SDKs. They avoid your auth wall entirely.
  • Where you’re soft: Long session lifetimes, refresh tokens usable from any device, lax rotation, and recovery paths (email/SMS support flows) that mint fresh device‑agnostic sessions.
  • Why now: Chrome’s device‑bound sessions begin closing the replay gap client‑side. On the server side, OAuth’s DPoP gives you a vendor‑neutral way to bind tokens to a per‑device key today. You don’t need to wait for browser features to mature.

A decision framework: What to ship first

Make this a sequencing problem, not a standards debate. Use your traffic mix and risk to pick the order.

  • Traffic mix: If 55–70% of your sessions are on Chrome, plan to ride device‑bound sessions as they hit stable. But do not park on a vendor timeline—ship proof‑of‑possession now with DPoP for all modern browsers.
  • App surface: SPAs and native apps can adopt DPoP immediately. Traditional server‑rendered sites can still bind refresh/token issuance to a per‑device key and require proof‑of‑possession during renewal.
  • Customer profile: Enterprise customers behind brittle proxies? Roll out behind a feature flag and gracefully fall back. Consumer traffic at scale? Prioritize faster rotation and telemetry to kill token reuse.
  • Recovery and support: If your helpdesk can mint a session without device binding, attackers can too. Fix recovery in parallel with any token work.

The 30‑60‑90 plan

Day 0–30: Stop minting bearer tokens you can’t defend

  • Inventory and shorten: Enumerate every token you issue (session cookies, API tokens, refresh tokens). Set aggressive max‑age for access tokens (10–15 minutes) and require rotation for session cookies at least every few hours. Use __Host‑ prefix, HttpOnly, Secure, SameSite=Strict where compatible.
  • Kill sliding sessions without proof: Sliding renewals should only occur if the client can prove it’s the same device that first obtained the token.
  • Add theft telemetry: Log a binding key ID with every token (placeholder for now), record user agent, platform, and coarse geo. Alert on reuse from a different device/ASN—even before binding goes live.
  • Block recovery bypasses: Eliminate SMS as a recovery method for high‑risk accounts. Move to backup codes + hardware key fallback and require a fresh device binding step to mint a post‑recovery session.

Day 31–60: Bind tokens to devices via DPoP

  • Generate a per‑device key in the client: For SPAs, use WebCrypto to create an ECDSA P‑256 key and persist it in IndexedDB. For native apps, use the OS keychain with hardware‑backed storage (Secure Enclave on iOS/macOS; StrongBox/TEE on Android).
  • Adopt OAuth DPoP for token issuance: When the client requests an access/refresh token, include a DPoP proof signed by the device key. The server binds the issued token to that public key. See RFC 9449.
  • Require DPoP on API requests: For calls authenticated with an access token, require a DPoP header proving possession of the bound key. Reject tokens presented without a valid proof or with a mismatched method/URI.
  • Rotate and attest: On refresh, require a new proof. Consider periodic key attestation on mobile (Play Integrity / DeviceCheck) for high‑risk tiers. Do not block on attestation availability—it’s an additive signal.
  • Measure overhead: ECDSA P‑256 verification typically adds ~0.3–0.9 ms CPU per request on a modern core. Budget roughly 1–2 KB of extra header per call. That’s noise compared to the cost of a support ticket, let alone an incident.

Day 61–90: Turn on browser‑native device binding and close the loop

  • Enable device‑bound sessions where supported: As Chrome’s feature rolls out, participate for your primary domain(s) and map the browser‑managed binding to your server‑side notion of a device key. Keep DPoP as a cross‑browser baseline.
  • Harden refresh paths: Every path that returns a new token must require proof‑of‑possession. No PoP, no token. This includes OAuth device code flows, PKCE exchanges, and customer support session mints.
  • Incident automation: On suspected theft (token seen without PoP or with a new device key), auto‑revoke that token family, force a fresh device bind, and notify the user. Add a one‑click "This wasn’t me" that escalates to account‑wide review.
  • Recovery redesign: Recovery creates a low‑risk, short‑lived session that can only be upgraded by performing a new WebAuthn ceremony or producing the device key proof. No direct jump to a long‑lived, fully‑privileged session.

Reference architecture: What “good” looks like

  1. Device key bootstrap: On first sign‑in (passkey/WebAuthn recommended), the client generates a long‑lived device key pair (WebCrypto or OS keychain). The public key and a random device ID are registered with your auth service.
  2. Token issuance with PoP: The client requests tokens with a DPoP proof. The auth service binds the tokens (access + refresh + session cookie) to the device public key and returns them. Cookies stay HttpOnly; PoP goes in a header.
  3. API enforcement: Your API gateway validates the token and verifies the DPoP signature against the bound public key, method, and URL. Mismatches, clock skew, or reuse of a jti are rejected and flagged.
  4. Rotation discipline: Access tokens expire after 10–15 minutes. Refresh tokens are single‑use and rotate on every exchange. Session cookies rotate every few hours or privilege change. All renewals require PoP.
  5. Recovery and step‑up: Recovery creates a limited session, not a free pass. Any elevation (billing, data export, API key creation) requires either a WebAuthn assertion or PoP from the stored device key.
  6. Telemetry: Store and analyze "device binding key ID × IP AS number × platform". Alert on sudden device key churn for a user or reuse of a binding key across many accounts (malicious automation).

Trade‑offs and gotchas (acknowledge them now)

  • Not every browser is ready: Device‑bound sessions will arrive unevenly. That’s why DPoP is the cross‑browser baseline. Keep fallbacks, but don’t let them silently bypass PoP.
  • Corporate proxies and API gateways: Some middleboxes rewrite headers. Protect DPoP headers end‑to‑end (TLS termination only at your edge) and document requirements for enterprise customers.
  • Shared accounts: Stop sharing. Implement delegated access and role‑based API keys tied to each user. If you absolutely must, support separate device bindings per operator and restrict privileges.
  • Performance: PoP adds crypto work. Amortize at the edge, cache token introspection, and prefer ECDSA P‑256 over heavier curves. In practice, the added latency is sub‑millisecond on commodity hardware.
  • Key lifecycle: Devices get replaced. Provide a clean “retire device key” flow and notify on new device bindings. Keep a short list (5–10) of active device keys per user.
  • Legal and privacy: Binding to a device key is not device fingerprinting. You’re storing a public key, not a canvas hash. Still, document it in your privacy notice and give users visibility and control.

How this intersects with passkeys (and where teams go wrong)

Passkeys prove it’s the right human, on a real device, at sign‑in. After that, the risk moves to tokens. Common failure modes we see in audits:

  • Passkey in, bearer out: Teams upgrade login to WebAuthn but still mint a bearer cookie that any machine can replay. You improved the front door and left the safe open.
  • Recovery blind spots: SMS and email links mint unbound sessions. Use them to bootstrap a new device binding, not to bypass it.
  • Long refresh lifetimes: 30‑day refresh tokens without PoP are a gift to infostealers. Rotate on every use; expire unused tokens quickly.

KPIs your board will accept

  • Stolen session reuse rate: Target an 80%+ reduction within 90 days post‑rollout, measured by tokens presented without valid PoP or with a new device binding.
  • Time‑to‑revoke: From first suspicious token use to family‑wide revocation under 60 seconds.
  • Coverage: Percentage of active user sessions with device binding enforced. Hit 70% by day 60; 90% by day 120.
  • Support load: Fewer ATO tickets per million MAU. Expect a short‑term bump as you close gaps, then a steady decline.

Implementation notes by platform

  • Web (SPA/MPA): Generate device keys with WebCrypto; store in IndexedDB; sign DPoP with SubtleCrypto. For MPA, you can still maintain a background "device key service worker" to sign proofs for privileged POSTs.
  • Mobile: Hardware‑backed keys via Keychain (iOS) and Keystore (Android). Use attestation where available. Bind tokens to those keys; require PoP on refresh and sensitive API calls.
  • Desktop (Electron/Tauri): Use OS keychain APIs. Prevent exporting private keys. Consider mTLS for internal enterprise deployments.
  • Servers and CLIs: For automation, use short‑lived OAuth client credentials or scoped, PoP‑bound service tokens. Never put long‑lived bearer tokens into CI secrets.

Rollout strategy: Minimize breakage, maximize impact

  • Feature flag by audience: Start with employee accounts, then a cohort of high‑risk customers, then the rest. Provide self‑service device management UI before you flip the switch broadly.
  • Gradual enforcement: Log‑only mode for a week, then soft‑enforce on refresh, then hard‑enforce on all privileged endpoints.
  • Communicate like you mean it: Explain the change in plain language: "We’re binding sessions to your device to stop token theft. You’ll see a one‑time prompt to register this device." Offer backup codes and clear recovery steps.

Why nearshore matters here

This isn’t a moonshot; it’s a disciplined engineering project with clear acceptance criteria. A focused nearshore pod can deliver it end‑to‑end—auth service changes, gateway enforcement, mobile/web key storage, telemetry, and SOC playbooks—while your core team keeps shipping product. Expect 6–8 weeks of work for a mid‑sized SaaS (web + mobile), plus two weeks of staged rollout and tuning.

The bottom line

Passkeys made phishing expensive. Device‑bound sessions make token theft unprofitable. Combine browser‑level binding as it lands with DPoP you can deploy today, and you’ll take the biggest ATO class off the table without rebuilding your entire auth stack. If you can ship one security project this quarter, make it this one.

Key Takeaways

  • Passkeys are necessary but insufficient; attackers replay stolen tokens to bypass them.
  • Chrome’s device‑bound sessions and OAuth DPoP close the replay gap by requiring proof‑of‑possession.
  • Ship in 90 days: shorten tokens, add telemetry, implement DPoP, then enable browser‑native binding as it rolls out.
  • Enforce PoP on every refresh and privileged API call; recovery must bootstrap a new device binding, not bypass it.
  • Expect sub‑millisecond crypto overhead and a measurable drop in ATO incidents within one quarter.

Ready to scale your engineering team?

Tell us about your project and we'll get back to you within 24 hours.

Start a conversation