Add `grace_period` support to token regeneration

Summary

When regenerating a token via POST /v0.1/tokens/{id}/regenerate, callers can optionally specify a grace_period (in seconds) to keep the previous API key valid for a transition window. This enables seamless key rotation without downtime for clients still using the old key.

If grace_period is not provided, the previous key is immediately invalidated (current behavior preserved).

Changes

  • Add previous_api_key (encrypted) and previous_api_key_expires_at (DateTime) nullable columns to the Token model with an Alembic migration
  • Extend TokenRegenerateIn schema with an optional grace_period field, validated against MAX_TOKEN_GRACE_PERIOD_SECONDS (default 30 days, configurable via dynaconf validator in config.py and overridable in settings.yaml)
  • Update get_token_db() to fall back to previous_api_key lookup when the primary key match fails and the grace period hasn't expired
  • Block grace_period on TokenCreateIn (inherited from TokenRegenerateIn but not applicable)

Design notes

  • No new tablesprevious_api_key and previous_api_key_expires_at are inline nullable columns on tokens
  • At most one previous key per token — each regeneration overwrites the previous key, preventing unbounded key accumulation
  • Zero overhead for normal auth — the fallback query only fires when the primary api_key match fails
  • No cleanup needed — expired previous keys are ignored by the query filter and overwritten on next regeneration

Resolves: TFT-4543

Assisted-by: Claude Code

Edited by Miroslav Vadkerti

Merge request reports

Loading