About the hot-off-the-press OAuth2 DPoP specification: https://datatracker.ietf.org/doc/html/rfc9449.
DPoP is a “sender constraint”: a way of checking that the sender of an access (JW) token is the same as the entity to whom the access token was issued.
My simplified understanding of DPoP is as follows:
the client generates a private/public key pair
the client generates a request for an access token. The request includes:
the client’s public key
the the authorization endpoint’s URL
the client signs the request with the client’s private key
the authorization server validates the request (signature and all) and issues an access (JW) token including the thumbprint of the client’s public key. As is normal in OAuth2, the access token is signed by the authorization server’s private key.
the client generates a new proof including the client’s public key and the intended API endpoint, attaches that to the access token (remember, the access token also includes the thumbprint of the client’s public key). The client sends the proof and access token to the API.
The API validates
the proof was signed by the client’s public key
the client’s public key matches the thumbprint in the access token
and the access key was signed by the and the authorization server’s public key
This seems much easier to manage than MTLS, which (I think) involves maintaining long-lived X509 certificates, signing infrastructure, and chains of trust.
Note: IdP = “Identity Provider”.
Also note that the OAuth 2.0 spec separates the user from the “user-agent”, which is typically the browser. For my notes I’m calling the human user the same thing as their browser.
Authorization Code flow with Proof Key for Code Exchange (PKCE)
Note that the “code challenge” and “code verifier” are roughly equivalent to public and private keys, respectively.
However, no specific cryptographic method is specified.
The “code challenge” might be the hash of the “code validator”, etc.
Differences with vanilla Authorization Code Flow
--- Authorization code flow
+++ Authorization code flow with PKCE
@@ -1,8 +1,8 @@
User -> Client : click login
-Client -> Authorization Server : POST client ID, redirect URI
+Client -> Authorization Server : POST client ID, redirect URI, code challenge
Authorization Server -> User : redirect to IdP
User -> IdP : Log into IdP
IdP -> Authorization Server : ID token
Authorization Server -> Client : OTP
-Client -> Authorization Server : OTP, client ID, client secret
+Client -> Authorization Server : OTP, code verifier
Authorization Server -> Client : Access token, ID token