SPA with DPoP
Client-side auth · DPoP token binding · Online Refresh Tokens · Refresh Token Metadata
Architecture & Token Flow
Security Implications
Strengths
- DPoP binds the access token to an ephemeral key pair generated in the browser — a token intercepted or exfiltrated alone is useless without the private key.
- Refresh Token Metadata gives visibility into which device/browser is holding each refresh token, without needing a server-side session.
Risks & Considerations
- It's still a public client with no client secret — anyone can register a client with the same client_id.
- DPoP protects the token, not the page: XSS during an active session can still call getTokenSilently() and act as the user for as long as the tab is open.
- DPoP's guarantee depends on the private key being non-extractable — if it were ever generated as an exportable WebCrypto key, XSS could exfiltrate the key itself alongside the token, defeating the binding entirely. Confirm the SDK generates it non-extractable; don't assume it.
Hardening Checklist
- Ship a strict Content-Security-Policy — XSS is the primary residual risk once DPoP is in place.
- Keep the redirect URI allowlist exact-match, not prefix/wildcard.
- Verify DPoP proof iat/nonce windows are tight enough to make replay impractical.
- DPoP binding is only as strong as the downstream API's own validation — a Resource Server that checks the access token's signature but not the DPoP proof and jkt thumbprint gets no protection from any of this.
