Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT AC: Implement DPoP auth scheme #717

Open
johakoch opened this issue Feb 13, 2023 · 9 comments · May be fixed by #763
Open

JWT AC: Implement DPoP auth scheme #717

johakoch opened this issue Feb 13, 2023 · 9 comments · May be fixed by #763
Labels
enhancement New feature or request proposal spec feature specification theme/access_control

Comments

@johakoch
Copy link
Collaborator

johakoch commented Feb 13, 2023

For JWT (and reference token) access controls

Currently still in draft stage, but seems quite stable: Demonstrating Proof-of-Possession at the Application Layer (DPoP) is a method to sender-constrain an access token, so that only the party the token was issued for (by the AS) can use it (at the RS); whereas a bearer token can be used by anyone holding it.

e.g.

GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
 oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
 WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF
 c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E
 OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA

The DPoP proof (sent in the DPoP request header) is a JWT structure signed with a private key, containing among others

  • jwk JOSE header parameter containing the corresponding public key

and the following claims:

  • htm - the HTTP method of the current (resource) request
  • htu - the HTTP URI value for the current (resource) request
  • ath - the base64url encoding of the SHA-256 hash of the access token value

e.g.

{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"e1j3V_bKic8-LAEB",
  "htm":"GET",
  "htu":"https://resource.example.org/protectedresource",
  "iat":1562262618,
  "ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo"
}

The access token presented at the RS must contain the public key confirmation:

  • cnf - with a jkt property containing the JWK SHA-256 thumbprint of the public key included in the DPoP proof's jwk header

e.g.

{
  "sub":"[email protected]",
  "iss":"https://server.example.com",
  "nbf":1562262611,
  "exp":1562266216,
  "cnf":
  {
    "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  }
}
@johakoch
Copy link
Collaborator Author

spec configuration:

  • How to distinguish between "Bearer" auth scheme (header = "Authorization", default for jwt) and "DPoP" auth scheme?
  • How to configure availability of both schemes (client can use either "Bearer" OR "DPoP") or only one of them?

spec implementation:

  • Auth scheme "Bearer" is only a token source, "DPoP" would be both token source AND additional validation.

@johakoch johakoch added the spec feature specification label Feb 15, 2023
@filex
Copy link
Contributor

filex commented Feb 15, 2023 via email

@johakoch
Copy link
Collaborator Author

I always wanted to introduce bearer=true​ as a shortcut for header=…. As they are mutually exclusive (I guess), we could add dpop=true​ as a counterpart.

There may be a use case to configure support for both Bearer and DPoP (see 7.2. Compatibility with the Bearer Authentication Scheme).

So

jwt "at" {
  dpop = true
  bearer = true
}

would mean,

  • try to get the token from Authorization: DPoP ... (and do the other necessary DPoP stuff), if not then
  • try to get the token from Authorization: Bearer ... (and make sure that there is no DPoP request header), if not then
  • missing token error.

@johakoch
Copy link
Collaborator Author

With the introduction of bearer = true, we could deprecate the special treatment for header = "Authorization" (extracting the token from the value following "Bearer ") and remove it later (treating all headers equally).

Separate issue for bearer = true?

@filex
Copy link
Contributor

filex commented Feb 16, 2023 via email

@johakoch
Copy link
Collaborator Author

I think we can never remove it in 1.x.

:-(

Separate issue for bearer = true?

yes.

See #720 for bearer = true.

@johakoch
Copy link
Collaborator Author

What about

authorization = "bearer" # instead of bearer = true
# or
authorization = "dpop"   # instead of dpop = true

?

@filex
Copy link
Contributor

filex commented Feb 21, 2023 via email

@johakoch
Copy link
Collaborator Author

johakoch commented Feb 21, 2023

Hm, not sure if an authorization​` attribute is so expressive in the JWT AC block. It stands next to Attributes like permission_map that actually deal with authorization.

Yep, auth_scheme could be a better name.

And wouldn’t it also forbid the edge case of having both bearer and dpop on one request? Although I’m unsure if that would actually work.

Having both bearer and dpop on one request would have to be rejected by the RS, if I remember correctly.

But an RS supporting both bearer and dpop is possible, so that clients can use either bearer or dpop. That would require the single attribute to be able to have both values (e.g. = "bearer dpop" or = ["bearer", "dpop"]), though.

@johakoch johakoch linked a pull request Jul 7, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request proposal spec feature specification theme/access_control
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants