ProtoRune.Atproto.OAuth.DPoP (proto_rune v0.5.2)

Copy Markdown

DPoP (Demonstrating Proof of Possession, RFC 9449) support for the AT Protocol OAuth flow.

AT Protocol requires clients to bind tokens to an ES256 (ECDSA over P-256) key pair and to attach a signed DPoP proof JWT to authorization server requests. This module implements key generation, JWK encoding and proof signing with :crypto and :public_key only, with no external JWT dependency.

Private keys are raw 32-byte binaries and can be persisted by the caller to resume a session later.

Summary

Functions

Generates a fresh ES256 key pair.

Builds a signed DPoP proof JWT for a request.

Derives the public JWK for an existing private key.

Types

jwk()

@type jwk() :: %{required(String.t()) => String.t()}

private_key()

@type private_key() :: <<_::256>>

Functions

generate_key()

@spec generate_key() :: {private_key(), jwk()}

Generates a fresh ES256 key pair.

Returns {private_key, public_jwk} where private_key is a raw 32-byte binary and public_jwk is the public key in JWK form, ready to embed in DPoP proof headers.

proof(private, jwk, method, url, opts \\ [])

@spec proof(private_key(), jwk(), atom() | String.t(), String.t(), keyword()) ::
  String.t()

Builds a signed DPoP proof JWT for a request.

Parameters

  • private - The ES256 private key (32-byte binary)
  • jwk - The matching public JWK, embedded in the proof header
  • method - The HTTP method of the request being proven (:get, :post, ...)
  • url - The target URL (query string and fragment are stripped per RFC 9449)
  • opts - Optional keyword list:
    • :nonce - Server-provided DPoP nonce
    • :access_token - Access token to bind via the ath claim

public_jwk(private)

@spec public_jwk(private_key()) :: jwk()

Derives the public JWK for an existing private key.

Useful when the caller persisted the private key and needs to rebuild the JWK without storing it.