Attesto.Keystore behaviour (Attesto v0.6.6)

Copy Markdown View Source

The behaviour Attesto uses to obtain signing and verification keys.

A keystore answers two questions:

  • What key do we sign new tokens with? signing_pem/0 returns the private signing key PEM. Attesto derives the public half and the kid from it (Attesto.Key), so the keystore never has to compute a thumbprint.

  • What keys may verify a presented token? verification_pems/0 returns a list of PEMs (private or public) whose public halves are trusted. With a single key this is just [signing_pem()]. During a key rotation it carries both the outgoing and incoming keys so tokens minted under either verify, and Attesto.Token.verify/3 selects the right one by the JWS header kid.

Implementations decide where keys come from - an environment variable, a secrets manager, a file, a hardware module. Attesto only consumes the PEMs, so the security-sensitive resolution and any fail-fast boot checks stay in the host application.

Attesto.Keystore.Static is a ready-made implementation for the common single-key (or manually-rotated) case.

Summary

Callbacks

Optional per-key JOSE algorithm metadata, keyed by RFC 7638 kid.

Optional global algorithm for the current signing key.

The private RSA key PEM used to sign newly issued tokens.

The PEMs (private or public) whose public halves are trusted to verify a presented token. MUST include the public half of whatever signing_pem/0 currently returns.

Callbacks

key_algs()

(optional)
@callback key_algs() :: %{required(String.t()) => String.t()} | keyword(String.t())

Optional per-key JOSE algorithm metadata, keyed by RFC 7638 kid.

When omitted, Attesto infers an algorithm from the public key shape: RSA -> RS256, P-256 -> ES256, P-384 -> ES384, P-521 -> ES512, and Ed25519/Ed448 -> EdDSA. Use this callback to label RSA keys that should verify as PS256, or to make a rotation window explicit.

signing_alg()

(optional)
@callback signing_alg() :: String.t()

Optional global algorithm for the current signing key.

This is a convenience for single-key RSA deployments that want PS256 without precomputing the signing key's kid. Verification still uses key_algs/0 when present, then key inference.

signing_pem()

@callback signing_pem() :: String.t()

The private RSA key PEM used to sign newly issued tokens.

verification_pems()

@callback verification_pems() :: [String.t()]

The PEMs (private or public) whose public halves are trusted to verify a presented token. MUST include the public half of whatever signing_pem/0 currently returns.