OAuth 2.0 is the protocol that lets you click "Sign in with Google" or "Sign in with GitHub" and end up logged into a third-party app without ever handing that app your password. It is, in practical terms, the load-bearing identity layer of the modern web. Every API key flow, every social login, every machine-to-machine token exchange in modern SaaS rides on top of it.
The protocol itself, defined in RFC 6749, is mostly about how tokens are issued, refreshed, and presented. But the tokens themselves are usually JSON Web Tokens (JWTs), which are signed with JSON Web Signature (JWS), defined in RFC 7515. And those signatures, today, are almost always made with classical algorithms like RSA-PSS, ECDSA, or EdDSA — algorithms that a sufficiently large quantum computer running Shor's algorithm would shred through.
When NIST finalized FIPS 204 (ML-DSA) in August 2024, the JOSE (JavaScript Object Signing and Encryption) Working Group inside IETF began the slow, careful process of registering post-quantum algorithm identifiers in the JOSE algorithms registry. This blog post walks through what changes, what stays the same, and what implementers need to start thinking about now.
OAuth 2.0 In One Paragraph
OAuth 2.0 is a delegation protocol. A user (the resource owner) authorizes a client (an app) to access protected resources hosted by a resource server, mediated by an authorization server. The authorization server hands the client an access token. The client presents that token to the resource server, which verifies it and either grants or denies access.
The token is opaque to the client in some flows, but in most modern deployments — especially when OpenID Connect is layered on top — the token is a signed JWT. The signature is what makes the token trustworthy: anyone who has the authorization server's public key can verify that the token was actually issued by that authorization server and has not been tampered with.
That signature is exactly where post-quantum cryptography enters the picture.
Why JWS Signatures Matter For PQC
Access tokens have short lifetimes — often 5 minutes, sometimes an hour. Refresh tokens last longer, sometimes weeks or months. ID tokens (the OpenID Connect ones that carry user identity claims) are usually short, but they often get logged, and those logs sit around forever.
The threat model for harvest now, decrypt later does not apply quite the same way to signatures as it does to encryption. A signature, once verified, has done its job. An attacker who later breaks the signing algorithm cannot retroactively un-verify a transaction.
But the attacker can do something much worse: they can forge new tokens. If a quantum-capable adversary derives the authorization server's private signing key from harvested public keys plus algorithmic break, they can mint arbitrary access tokens that pass verification at every resource server. They can issue themselves admin tokens. They can impersonate any user. They can do this silently, with no log entry that distinguishes a forged token from a legitimate one.
This is why the JOSE WG is being deliberate about getting PQC signature identifiers right.
The JOSE Algorithms Registry
IANA maintains the JOSE algorithms registry under https://www.iana.org/assignments/jose. Every algorithm name that can appear in a JWS alg header — RS256, ES256, EdDSA, and so on — is registered there. The registry is the single source of truth.
For ML-DSA, the IETF draft draft-ietf-cose-dilithium (which was renamed during the standardization process and now tracks the FIPS 204 final names) and the related JOSE work specify the identifier scheme. The names follow the FIPS 204 naming directly: ML-DSA-44, ML-DSA-65, and ML-DSA-87 correspond to the three parameter sets for security categories 2, 3, and 5 respectively.
So a post-quantum-signed JWT header looks like this:
`` {"alg":"ML-DSA-65","typ":"JWT"} ``
The verification side of the equation is symmetric: the relying party fetches the signing key from a JWKS (JSON Web Key Set) endpoint, sees that the key has a kty (key type) appropriate for ML-DSA, and runs the FIPS 204 verification routine.
Token Size: The Elephant In The Header
Here is where the conversation gets uncomfortable. ECDSA P-256 produces 64-byte signatures. EdDSA over Ed25519 produces 64-byte signatures. RSA-2048 with PSS produces 256-byte signatures. These are small enough that a JWT carrying user claims plus a signature still fits comfortably in an HTTP header, in a URL fragment, or in a cookie.
ML-DSA-65, by contrast, produces signatures of 3,309 bytes. ML-DSA-87 produces signatures of 4,627 bytes. Public keys are also bigger: 1,952 bytes for ML-DSA-65 and 2,592 bytes for ML-DSA-87.
A JWT signature in base64url is roughly 4/3 the size of the binary signature. So an ML-DSA-65 JWT signature, encoded for transport, is around 4,400 bytes. The full JWT — header plus claims plus signature — easily exceeds 5 KB.
What does this break?
- Cookie size limits: most browsers cap individual cookies at 4 KB. A PQC-signed JWT cookie may not fit.
- HTTP header size limits: many HTTP servers default to 8 KB total header size. If your app stores the JWT in
Authorization: Bearer ...and also has other large headers, you can blow past this. - URL length limits: some flows (like the deprecated implicit grant, or some token introspection responses) put tokens in URLs. PQC JWTs are too big.
- Mobile networks: every kilobyte of header sent on every API call adds latency on slow connections.
The mitigation strategies the JOSE WG and OAuth WG are exploring include:
- Pushed Authorization Requests (RFC 9126) to keep large requests off the URL.
- Sender-constrained tokens via DPoP (RFC 9449), where the proof is a separate JWT.
- Token introspection (RFC 7662) so that the resource server can ask the authorization server about the token rather than parsing a giant JWT.
ML-DSA vs SLH-DSA In OAuth Contexts
NIST standardized two PQC signature schemes: ML-DSA (FIPS 204) based on lattices, and SLH-DSA (FIPS 205) based on hash trees. We have a whole article comparing these two, but the OAuth-specific summary is:
- ML-DSA has signatures of 2,420–4,627 bytes depending on parameter set. Verification is fast.
- SLH-DSA has signatures of 7,856–49,856 bytes depending on parameter set. Verification is fast for the smaller sets but signing is significantly slower.
For high-throughput authorization servers minting millions of tokens per minute, ML-DSA is the realistic default. SLH-DSA's bigger signatures and slower signing make it impractical for hot-path token issuance, though it remains attractive for long-lived signing keys (like trust anchors) where the conservative hash-based foundation is reassuring.
Hybrid Signatures In OAuth
Just like in hybrid encryption, there is interest in hybrid signatures: a JWT that carries both an ECDSA signature and an ML-DSA signature, with the verifier requiring both to pass.
The JOSE WG has discussed this but has not yet standardized a specific composite identifier scheme. The conservative approach in the meantime is to issue two JWTs — one classical, one PQC — and have the relying party verify both. This is messy but works with deployed code.
Migration Plan For OAuth Servers
If you operate an authorization server today, here is the practical sequence.
Step 1: Inventory your signing keys. Most authorization servers have a small number of signing keys with well-defined rotation schedules. Document them.
Step 2: Add ML-DSA key generation to your key ceremony. When you next rotate, generate an ML-DSA key alongside your ECDSA or RSA key.
Step 3: Publish both keys at your JWKS endpoint. A JWKS endpoint can serve multiple keys. Add the ML-DSA key with a distinct kid (key ID).
Step 4: Sign with the classical key by default. Most relying parties cannot verify ML-DSA yet. Do not break them.
Step 5: Offer ML-DSA signing as an opt-in. Let advanced clients request ML-DSA tokens via a request parameter or scope.
Step 6: Monitor the JOSE registry. Once ML-DSA-65 is officially registered with a stable identifier, switch your opt-in clients to use it.
Step 7: Eventually flip the default. When the majority of relying parties support ML-DSA verification, default to ML-DSA and offer ECDSA as the legacy fallback.
This is a multi-year process. Start now.
What QNSQY Does With OAuth
QNSQY's file protection is independent of OAuth. Files are encrypted and signed on the user's device, and a file's post-quantum signature protects its integrity whatever happens to the tokens that authorize access to an online service. Tokens and file signatures are different layers, and each needs its own migration plan.
DPoP, mTLS, And Sender-Constrained Tokens
A specific OAuth pattern that interacts interestingly with PQC is sender-constrained tokens. With DPoP (RFC 9449), the client holds a private key and signs a "DPoP proof" JWT with each API call, proving possession of the key. The access token references the public key thumbprint, so a stolen access token cannot be used by anyone who lacks the corresponding private key.
DPoP today uses ECDSA or EdDSA proofs. Migrating DPoP to ML-DSA inherits the same size penalty: every API call now carries a 4 KB DPoP proof on top of the access token. For high-volume APIs, this is operationally painful.
The alternative is mTLS-bound tokens (RFC 8705), where the access token is bound to a TLS client certificate. Here PQC arrives at the TLS layer (via the TLS 1.3 hybrid handshake) and the binding to the access token is via the certificate fingerprint, which is not a PQC-affected primitive. This means mTLS-bound tokens may be a more PQC-friendly direction for sender-constrained OAuth than DPoP.
OAuth deployments with security-sensitive sender-constraint requirements should evaluate mTLS over DPoP for the PQC era, especially for high-throughput cases.
Authorization Server Performance
Authorization servers mint access tokens at very high rates. Major cloud IdPs issue billions of tokens per day. Each token issuance is a signing operation.
ML-DSA-65 signing on modern x86 hardware runs at roughly 100,000 signatures per second per core, comparable to ECDSA-P256 signing speed. So pure CPU cost is not the bottleneck. The bottleneck is the bandwidth and storage cost of the larger tokens flowing through the system: token databases (if you store tokens), rate-limiting state, audit logs, and all the operational telemetry.
For most authorization servers, this means an infrastructure scaling exercise rather than a cryptographic capability gap. The crypto is fast; the surrounding infrastructure needs to absorb the size growth.
Frequently Asked Questions
Q: Will my existing OAuth library work with ML-DSA tokens? Not yet. Most JOSE libraries do not implement ML-DSA verification. As the IANA registration completes and major libraries (jose-jwt, nimbus-jose-jwt, jsonwebtoken) ship support, this will change. Track your library's release notes.
Q: Are JWT bearer tokens still safe to use without PQC? For now, yes. There is no quantum computer today that can break Ed25519 or ECDSA P-256. The risk is forward-looking. But because rolling out PQC takes years, planning needs to start now.
Q: Does PKCE need to change for PQC? No. PKCE (RFC 7636) uses SHA-256 as a one-way hash for code challenges. SHA-256 is not broken by quantum attacks (Grover's algorithm only halves its security, leaving 128-bit effective security, which is fine).
Q: What about client authentication via private_key_jwt? Same answer as for ID tokens. The client's signing key needs to migrate to ML-DSA on the same timeline as the authorization server's signing key. Plan the migration jointly.
Q: Is there a smaller PQC signature scheme I could use instead? Falcon (FN-DSA, the upcoming FIPS 206) has smaller signatures (around 666 bytes for Falcon-512). But it has implementation hazards around constant-time floating-point arithmetic, and the FIPS standard is not finalized yet. ML-DSA is the safer near-term choice.
Sources
- RFC 6749 — The OAuth 2.0 Authorization Framework. https://datatracker.ietf.org/doc/html/rfc6749
- RFC 7515 — JSON Web Signature (JWS). https://datatracker.ietf.org/doc/html/rfc7515
- RFC 7519 — JSON Web Token (JWT). https://datatracker.ietf.org/doc/html/rfc7519
- NIST FIPS 204 — Module-Lattice-Based Digital Signature Standard. https://csrc.nist.gov/pubs/fips/204/final
- IANA JOSE Algorithms Registry. https://www.iana.org/assignments/jose
- RFC 9126 — OAuth 2.0 Pushed Authorization Requests. https://datatracker.ietf.org/doc/html/rfc9126
- RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP). https://datatracker.ietf.org/doc/html/rfc9449
Related Articles
- What Is Post-Quantum Cryptography?
- ML-DSA Explained
- Hybrid Encryption
- NIST FIPS Guide
- Harvest Now, Decrypt Later
- ACME and PQC: Let's Encrypt Roadmap
- Mozilla NSS: Post-Quantum Roadmap and Current Support
- AWS CloudHSM: PQC Algorithm Coverage
- Node.js crypto Module: Post-Quantum Algorithm Status
Protect Your Data Before Q-Day Arrives
QNSQY's NIST-standardized post-quantum encryption protects files against both current and quantum-era threats.