KemalIdentity::ApiTokens::LifetimePolicy
How long a personal access token may live in this deployment.
An enterprise requires every token to expire within thirty days and forbids unbounded ones;
the deployment next door permits a non-expiring deploy key. Both are correct, so this is
absent by default — Service.new with no policy accepts what its caller asks for,
including no expiry at all, which is the shipped behaviour and stays it.
Checked at issuance, and only there
A policy describes what may be created. It is not consulted on the authentication path:
every request already reads the token's own expires_at, and re-deriving a limit per request
would put a policy lookup on the hot path to answer a question the row already answers.
The consequence, which docs/02-security-model.md states rather than leaves to be
discovered: tightening the policy does not shorten the tokens that already exist. A
ninety-day token issued under the old rule keeps its ninety days. That is the honest
behaviour for a rule about creation, and it is why Service#expire exists — an organisation
that must apply a new limit retroactively walks its tokens and brings each deadline forward,
which is one call per token and cannot lengthen anything by mistake.
policy = KemalIdentity::ApiTokens::LifetimePolicy.new(maximum: 30.days, default: 7.days)
Constructors
Instance methods
What to use when the caller names no expiry. nil means an issuance with no expiry is
refused rather than defaulted — the stricter reading, and the one an enterprise asking
for this feature usually wants: a client that forgot to ask for a deadline should be told,
not quietly given one.
The expiry to store, filling in default when the caller named none. Returns nil when
there is nothing to fill in, which #violation then refuses.
Why this expiry is unacceptable, or nil if it is fine.
Takes now rather than reading a clock: a policy is a value, and the one thing worse
than a policy that cannot be tested is one that reads the system clock while being
tested.