livery_auth_jose (livery v0.13.0)

View Source

JWS signature checks for livery_auth.

Supports the asymmetric algorithms of RFC 7518 and RFC 9864: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, Ed25519 and Ed448, plus the older EdDSA name, whose curve comes from the key. none and the HMAC algorithms are never accepted: a resource server has no business sharing a signing secret with its issuer.

A key is used for a token only when everything it says about itself agrees with the token: its kty and crv fit the algorithm, its alg (if present) names it, its use (if present) is sig, its key_ops (if present) include verify, and its kid matches when the token carries one. RSA keys shorter than 2048 bits are skipped (RFC 7518 section 3.3). Without a kid, every fitting key is tried in order.

Deviations: EdDSA is still accepted although RFC 9864 deprecates it, because most issuers still send it. See AGENTS.md, Known deviations.

Summary

Functions

Every algorithm Livery can verify, the default allow list.

Decode unpadded base64url.

Decode a base64url JOSE part that must hold a JSON object.

The public JWK of a signing key {Alg, PrivateKey} (the key records sign/3 takes), with only its public members and alg.

Sign Claims into a compact JWS with {Alg, PrivateKey}. Header is merged over #{alg => Alg}. PrivateKey is an OTP private key record: #'RSAPrivateKey'{} for RS and PS, #'ECPrivateKey'{} for ES, Ed25519 and Ed448.

Check Sig over SigningInput with a key from Keys that fits Alg and Kid, among the Allowed algorithms.

Functions

algorithms()

-spec algorithms() -> [binary()].

Every algorithm Livery can verify, the default allow list.

b64url(B64)

-spec b64url(binary()) -> {ok, binary()} | error.

Decode unpadded base64url.

decode_json(B64)

-spec decode_json(binary()) -> {ok, map()} | error.

Decode a base64url JOSE part that must hold a JSON object.

public_jwk/1

-spec public_jwk({binary(), term()}) -> map().

The public JWK of a signing key {Alg, PrivateKey} (the key records sign/3 takes), with only its public members and alg.

sign/3

-spec sign({binary(), term()}, map(), map()) -> binary().

Sign Claims into a compact JWS with {Alg, PrivateKey}. Header is merged over #{alg => Alg}. PrivateKey is an OTP private key record: #'RSAPrivateKey'{} for RS and PS, #'ECPrivateKey'{} for ES, Ed25519 and Ed448.

verify(Alg, Kid, SigningInput, Sig, Keys, Allowed)

-spec verify(term(), term(), binary(), binary(), [livery_auth:jwk()], [binary()]) ->
                ok | {error, {unsupported_alg, term()} | no_matching_key | bad_signature}.

Check Sig over SigningInput with a key from Keys that fits Alg and Kid, among the Allowed algorithms.