Attesto.Revocation (Attesto v0.5.0)

Copy Markdown View Source

RFC 7009 - OAuth 2.0 Token Revocation, for refresh tokens.

Revoking a refresh token revokes its entire family (every token descended from the same authorization), the same machinery refresh rotation uses for reuse detection. This module is the deliberate revocation entry point; it runs over an Attesto.RefreshStore.

No-existence oracle (RFC 7009 §2.2)

An invalid, expired, or unknown token does not produce an error: revoke/3 returns :ok regardless of whether the token existed. A revocation endpoint must not let a caller probe which tokens are live, so revoking a token the store has never seen is indistinguishable from revoking a real one.

Client binding (RFC 7009 §2.1)

When the token carries a client_id, revocation is fail-closed: the caller MUST present a matching :client_id or the call returns {:error, :unauthorized_client}, so one client cannot revoke another client's tokens. A caller that cannot authenticate the client passes allow_missing_client_id?: true. A token issued without a client binding skips the check.

Access tokens

Attesto access tokens are stateless, short-lived JWTs, so there is no per-token revocation list to consult; revoking them is a host concern (rely on their short TTL, or maintain a jti denylist the resource server checks). This module revokes the stateful, family-backed refresh credential, which is what RFC 7009 revocation is primarily for.

Summary

Functions

Revoke the refresh token token (and its whole family) via store.

Types

revoke_error()

@type revoke_error() :: :unauthorized_client

Functions

revoke(store, token, opts \\ [])

@spec revoke(module(), String.t(), keyword()) :: :ok | {:error, revoke_error()}

Revoke the refresh token token (and its whole family) via store.

Returns :ok whether or not the token existed (no-existence oracle). Returns {:error, :unauthorized_client} only when the token carries a client_id and the presented :client_id does not match (or is absent without allow_missing_client_id?: true).

Options: :client_id (the authenticated revoking client) and :allow_missing_client_id?.