Atex.ServiceAuth
(atex v0.9.1)
View Source
Validating and working with inter-service authentication tokens.
Provides functions for validating ATProto inter-service authentication JWTs,
either from a raw token string or directly from an incoming Plug.Conn.
Validation covers:
- Token timing (
iatnot in the future,expnot in the past). - Audience (
aud) matching the caller-supplied expected value. - Optional lexicon method (
lxm) matching the caller-supplied expected value. - Issuer DID resolution and signing-key verification via
Atex.IdentityResolver. - Replay prevention via
Atex.ServiceAuth.JTICache- eachjtinonce may only be accepted once.
Configuration
The JTI cache implementation is pluggable. See Atex.ServiceAuth.JTICache for
details.
Summary
Types
Options accepted by validate_conn/2 and validate_jwt/2.
Types
Options accepted by validate_conn/2 and validate_jwt/2.
:aud- required. The expected audience string. The token'saudclaim must equal this value exactly.:lxm- optional. When provided, the token'slxmclaim must match. If the token omitslxmthe check is skipped; if the token carrieslxmbut no expected value is configured, validation fails with:lxm_not_configured.
Functions
@spec validate_conn(Plug.Conn.t(), [validate_option()]) :: {:ok, jwt :: JOSE.JWT.t()} | {:error, reason :: atom()}
Validate a service auth token from a Plug.Conn request.
Extracts the Authorization: Bearer <jwt> header and delegates to
validate_jwt/2. Returns {:error, :missing_token} when the header is
absent or malformed.
Options
See validate_option/0.
Examples
iex> Atex.ServiceAuth.validate_conn(conn, aud: "did:web:my-service.example")
{:ok, %JOSE.JWT{}}
iex> Atex.ServiceAuth.validate_conn(conn, aud: "did:web:my-service.example", lxm: "app.bsky.feed.getTimeline")
{:error, :lxm_mismatch}
@spec validate_jwt(String.t(), [validate_option()]) :: {:ok, jwt :: JOSE.JWT.t()} | {:error, reason :: atom()}
Validate a raw service auth JWT string.
Performs the full validation pipeline:
- Decodes the JWT payload (without verifying the signature yet) to extract claims.
- Validates
:audand:lxmagainst the provided options. - Validates token timing (
iat,exp). - Resolves the issuer DID and retrieves the ATProto signing key from their DID document.
- Verifies the JWT signature with the resolved key.
- Records the
jtinonce inAtex.ServiceAuth.JTICache- returns{:error, :replayed_token}if it has already been seen.
Options
See validate_option/0.
Error reasons
:aud_mismatch-audclaim does not match the expected audience.:lxm_mismatch-lxmclaim does not match the expected lexicon method.:lxm_not_configured- token carries anlxmclaim but no expected value was provided via:lxmopt.:future_iat-iatis in the future.:expired-expis in the past.:replayed_token-jtihas already been used.
Examples
iex> Atex.ServiceAuth.validate_jwt(jwt, aud: "did:web:my-service.example")
{:ok, %JOSE.JWT{}}
iex> Atex.ServiceAuth.validate_jwt(expired_jwt, aud: "did:web:my-service.example")
{:error, :expired}