Single-node ETS implementation of Attesto.RefreshStore.
Tokens live in an ETS table owned by a GenServer. The security-
critical consume/1 (check-unconsumed-and-mark-consumed) is serialised
through the owning process: routing it as a GenServer.call/2 makes the
read-modify-write atomic without an ETS compare-and-set dance, which is
the simplest correct primitive for a reference store. insert/1 and
revoke_family/1 go through the same process so all mutations are
ordered.
This is a per-node store. A multi-node deployment MUST back
Attesto.RefreshStore with a shared store whose consume/1 is atomic
across nodes (e.g. Postgres UPDATE ... WHERE consumed = false RETURNING), or reuse detection only holds per node.
Start options: :sweep_interval_ms (default 60_000). The sweeper
deletes tokens past their expiry; consumed-but-unexpired tokens are
retained so reuse within the TTL window is still detected.
children = [Attesto.RefreshStore.ETS]
Summary
Functions
@spec reset() :: :ok
Clear every entry. Test-facing.
@spec start_link(keyword()) :: GenServer.on_start()