Skip to main content

Module dpop

Module dpop 

Source
Expand description

Device keys and DPoP proofs (RFC 9449, R18).

§Design

Each device has one P-256 key. The private part stays on the device, in the OS keyring. Each request carries a proof: a short JWT that the key signs (ES256). The proof names the method and the URL of the request, and the hash of the access token. So a copied token or a copied proof is of no use without the key.

 Authorization: DPoP <access token>
 DPoP: <header>.<payload>.<signature>
       header  {"typ":"dpop+jwt","alg":"ES256","jwk":{public key}}
       payload {"jti","htm","htu","iat","ath"}

The server binds each sign-in to the thumbprint of the key (RFC 7638). It accepts a token only with a proof from that key.

§Rules for a valid proof

  • typ is dpop+jwt, alg is ES256, and jwk is a public P-256 key with no private part.
  • The signature is good for that key.
  • htm is the method and htu is the URL of the request, with no query and no fragment.
  • iat is at most MAX_AGE seconds old, and at most MAX_SKEW seconds in the future (R86).
  • jti is not empty. The server refuses a jti that it saw before.
  • With an access token, ath is its hash.

§Example

use riff_core::dpop::{Key, verify};

let key = Key::generate();
let url = "https://riff.example.com/v1/who";
let proof = key.proof("POST", url, Some("t-1"), 1_000);
let checked = verify(&proof, "POST", url, Some("t-1"), 1_000).unwrap();
assert_eq!(checked.jkt, key.thumbprint());

// The proof does not work for another token or another URL.
assert!(verify(&proof, "POST", url, Some("t-2"), 1_000).is_err());
assert!(verify(&proof, "POST", "https://riff.example.com/v1/post", Some("t-1"), 1_000).is_err());

Structs§

DpopError
Why a proof is not valid.
Jwk
A public P-256 key as a JWK.
Key
The private key of a device.
Proof
What a valid proof tells the server.

Constants§

ALG
The only signing algorithm.
MAX_AGE
A proof may be this many seconds old (R86).
MAX_SKEW
A proof may be this many seconds in the future, for clock skew (R86).

Functions§

token_hash
The ath of an access token: base64url of its SHA-256 hash.
verify
Checks a proof for one request. See the module docs for the rules. The caller checks that the jti is new.