Skip to content

feat: token lifecycle — named, scoped api tokens#427

Merged
kacy merged 2 commits into
mainfrom
feat/token-lifecycle
May 24, 2026
Merged

feat: token lifecycle — named, scoped api tokens#427
kacy merged 2 commits into
mainfrom
feat/token-lifecycle

Conversation

@kacy
Copy link
Copy Markdown
Owner

@kacy kacy commented May 24, 2026

adds named API tokens with scopes, TTL, and revocation, managed by a new
yoq token command. first half of the rbac item in next-steps.md; enforcement
in the dispatch path follows in a second pr.

summary

  • new tokens table (migration): name, sha256(secret), scopes (csv), created,
    optional expiry, revocation. store helpers create/list/revoke and
    findActiveTokenByHash (filters revoked + expired). secrets are never stored.
  • lib/scopes.zig: the permission vocabulary — <resource>:read|write, the *
    and <resource>:* wildcards, and write-implies-read — plus scope validation.
  • yoq token create <name> --scope <s> [--scope ...] [--ttl 30d] generates a
    32-byte secret, stores its hash, and prints the secret once;
    yoq token list; yoq token revoke <name>. lifecycle ops are audited
    (token_create / token_revoke).
  • backup validator updated to expect the new table.

tested

  • YOQ_SKIP_SLOW_TESTS=1 zig build test — 2179 passed, 2 skipped, 0 failed.
  • unit tests: store create/list/revoke + findActiveTokenByHash filtering
    expired and revoked rows, duplicate-name rejection; scope validation and
    allows (wildcards, write-implies-read, denials).
  • ran the binary: create prints a one-time secret with its scopes; list shows
    status/scopes/expiry; duplicate name and invalid scope are rejected; revoke
    flips status to revoked.
  • zig fmt --check clean.

follow-up

pr 2 wires enforcement into the api dispatch (per-route scope checks, 403 on
insufficient scope) and sets the audit actor to the token name. the existing
single api_token keeps working as full admin.

kacy added 2 commits May 24, 2026 16:01
new tokens table (migration) storing sha256(secret) + scopes + optional
expiry + revocation, with store create/list/revoke/findActiveByHash
helpers. add lib/scopes.zig defining the permission vocabulary
(<resource>:read|write, wildcards, write-implies-read) and validation.
backup validator now expects tokens (count 21); audit gains
token_create/token_revoke actions.
manage named, scoped api tokens from the cli. create generates a 32-byte
secret, stores only its sha256, and prints the secret once; list shows
name/status/scopes/expiry; revoke marks a token revoked. token lifecycle
ops are audited.
@kacy kacy merged commit 2d30658 into main May 24, 2026
2 checks passed
@kacy kacy deleted the feat/token-lifecycle branch May 24, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant