feat: token lifecycle — named, scoped api tokens#427
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
adds named API tokens with scopes, TTL, and revocation, managed by a new
yoq tokencommand. first half of the rbac item in next-steps.md; enforcementin the dispatch path follows in a second pr.
summary
tokenstable (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 a32-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).
tested
YOQ_SKIP_SLOW_TESTS=1 zig build test— 2179 passed, 2 skipped, 0 failed.findActiveTokenByHashfilteringexpired and revoked rows, duplicate-name rejection; scope validation and
allows(wildcards, write-implies-read, denials).status/scopes/expiry; duplicate name and invalid scope are rejected; revoke
flips status to revoked.
zig fmt --checkclean.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.