dpop#
Minimal OCaml implementation of RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP).
DPoP binds an OAuth access token to a public key held by the client so that a leaked bearer token cannot be replayed by an attacker who does not also hold the private key. Clients attach a signed JWT (a DPoP proof) to every token-endpoint and resource request; authorization servers bind the issued access token to the public key via its JWK thumbprint (RFC 7638).
Installation#
Install with opam:
$ opam install dpop
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install dpop
Usage#
let () = Crypto_rng_unix.use_default ()
let key = Dpop.generate Dpop.ES256
(* Attach a proof to every token-endpoint request. *)
let token_header () =
let proof =
Dpop.proof key
~htm:"POST"
~htu:"https://as.example.com/token"
()
in
("DPoP", proof)
(* On resource requests, bind the proof to the access token. *)
let resource_header ~access_token =
let ath = Dpop.access_token_hash access_token in
let proof =
Dpop.proof key
~htm:"GET"
~htu:"https://api.example.com/me"
~ath
()
in
("DPoP", proof)
Supported algorithms#
- ES256 — ECDSA P-256 + SHA-256 (RFC 7518 §3.4). Mandatory for DPoP per RFC 9449 §5.1.
- EdDSA — Ed25519 (RFC 8037).
Other algorithms (RS256, ES384, etc.) are intentionally not supported: each adds parser complexity, attack surface, and rarely matches the DPoP use case better than the two above.
License#
MIT. See LICENSE.md.