Add API key authentication foundation #33

Closed
opened 2026-05-19 19:51:45 -05:00 by erik · 3 comments
Owner

Goal

Implement the DB-backed API key foundation needed for protected Slugkit API routes and future slug authentication checks, without building the full admin UI or passkey flow in this slice.

Spec: docs/web-specs/03-admin-auth-keys-passkeys.md

Requirements

  • Add SQLite migrations for API key records.
  • Store only API key hashes; never persist raw API keys.
  • Generate raw API keys with Node built-in cryptographic randomness.
  • Return/display the raw key only from the creation call result so future UI can show it exactly once.
  • Support API key listing metadata without exposing raw keys or hashes.
  • Support API key revocation.
  • Add reusable API key verification for bearer auth middleware.
  • Add a small protected API smoke route or test-only protected app that proves valid, missing, invalid, and revoked keys use the shared API error shape.
  • Keep schema compatible with adding scopes later, but do not implement scopes in this slice.
  • Do not implement admin login/logout UI or passkey flows in this slice.

Acceptance criteria

  • API key migration applies from an empty SQLite database.
  • API key creation returns a raw key once and persists only a hash.
  • API key listing never exposes raw keys or hashes.
  • API key revocation prevents future authentication.
  • Valid API keys authenticate protected API requests through shared bearer auth behavior.
  • Missing, invalid, and revoked API keys fail with the standard API error shape.
  • Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior.
  • Relevant lint/test checks pass.

Dependencies

  • task-69937fe4
  • task-c272cbda
## Goal Implement the DB-backed API key foundation needed for protected Slugkit API routes and future `slug` authentication checks, without building the full admin UI or passkey flow in this slice. Spec: `docs/web-specs/03-admin-auth-keys-passkeys.md` ## Requirements - Add SQLite migrations for API key records. - Store only API key hashes; never persist raw API keys. - Generate raw API keys with Node built-in cryptographic randomness. - Return/display the raw key only from the creation call result so future UI can show it exactly once. - Support API key listing metadata without exposing raw keys or hashes. - Support API key revocation. - Add reusable API key verification for bearer auth middleware. - Add a small protected API smoke route or test-only protected app that proves valid, missing, invalid, and revoked keys use the shared API error shape. - Keep schema compatible with adding scopes later, but do not implement scopes in this slice. - Do not implement admin login/logout UI or passkey flows in this slice. ## Acceptance criteria - [ ] API key migration applies from an empty SQLite database. - [ ] API key creation returns a raw key once and persists only a hash. - [ ] API key listing never exposes raw keys or hashes. - [ ] API key revocation prevents future authentication. - [ ] Valid API keys authenticate protected API requests through shared bearer auth behavior. - [ ] Missing, invalid, and revoked API keys fail with the standard API error shape. - [ ] Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior. - [ ] Relevant lint/test checks pass. ## Dependencies - task-69937fe4 - task-c272cbda
erik changed title from Add admin auth and API key UI to Add API key authentication foundation 2026-05-22 11:43:12 -05:00
Author
Owner

Synced from todu comment by @todu on 2026-05-22T16:40:09.342Z

Scope Split

Narrowed this task from the full admin auth/passkey/API-key UI scope to the first reviewable slice: DB-backed API key authentication foundation.

Tracked deferred scope as follow-up tasks:

  • task-8af07ab8 — Add admin login and session routes
  • task-931b710f — Add admin API key management UI
  • task-d352924e — Add admin passkey management
  • task-99c66789 — Add passkey admin authentication

Reason: the original task combined API key storage, protected API middleware, admin sessions, API key UI, and passkey flows into one broad PR. The foundation slice unblocks protected API route implementation while preserving follow-up work explicitly.

_Synced from todu comment by @todu on 2026-05-22T16:40:09.342Z_ ## Scope Split Narrowed this task from the full admin auth/passkey/API-key UI scope to the first reviewable slice: DB-backed API key authentication foundation. Tracked deferred scope as follow-up tasks: - `task-8af07ab8` — Add admin login and session routes - `task-931b710f` — Add admin API key management UI - `task-d352924e` — Add admin passkey management - `task-99c66789` — Add passkey admin authentication Reason: the original task combined API key storage, protected API middleware, admin sessions, API key UI, and passkey flows into one broad PR. The foundation slice unblocks protected API route implementation while preserving follow-up work explicitly.
Author
Owner

Synced from todu comment by @todu on 2026-05-22T16:46:57.857Z

PR Review: Approved

PR: #56

Summary

Reviewed PR #56 at commit a2b674b. The PR implements the narrowed API key authentication foundation: adds an api_keys migration, hash-only key storage, creation/listing/revocation/verification helpers, a reusable DB-backed bearer validator, and tests proving migration, redaction, revocation, invalid/missing auth failures, and valid protected-route authentication.

Acceptance Criteria

  • API key migration applies from an empty SQLite database — covered by migration test and manual db:migrate smoke.
  • API key creation returns a raw key once and persists only a hash — createApiKey returns rawKey; DB stores key_hash and metadata only; tests assert raw key is not persisted.
  • API key listing never exposes raw keys or hashes — listApiKeys selects metadata columns only; tests assert no rawKey or keyHash.
  • API key revocation prevents future authentication — revoked_at excludes keys from verification; tests cover revoked key rejection.
  • Valid API keys authenticate protected API requests through shared bearer auth behavior — tested via createBearerAuthMiddleware + createApiKeyValidator.
  • Missing, invalid, and revoked API keys fail with the standard API error shape — protected-route tests cover all three.
  • Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior.
  • Relevant lint/test checks pass — make check, ./scripts/pre-pr.sh, manual migration smoke, and Forgejo CI passed.

Blocking Issues

None.

Warnings

None.

Verdict

Approved for merge.

_Synced from todu comment by @todu on 2026-05-22T16:46:57.857Z_ ## PR Review: Approved PR: https://forge.caradoc.com/erik/slugkit/pulls/56 ### Summary Reviewed PR #56 at commit `a2b674b`. The PR implements the narrowed API key authentication foundation: adds an `api_keys` migration, hash-only key storage, creation/listing/revocation/verification helpers, a reusable DB-backed bearer validator, and tests proving migration, redaction, revocation, invalid/missing auth failures, and valid protected-route authentication. ### Acceptance Criteria - [x] API key migration applies from an empty SQLite database — covered by migration test and manual `db:migrate` smoke. - [x] API key creation returns a raw key once and persists only a hash — `createApiKey` returns `rawKey`; DB stores `key_hash` and metadata only; tests assert raw key is not persisted. - [x] API key listing never exposes raw keys or hashes — `listApiKeys` selects metadata columns only; tests assert no `rawKey` or `keyHash`. - [x] API key revocation prevents future authentication — `revoked_at` excludes keys from verification; tests cover revoked key rejection. - [x] Valid API keys authenticate protected API requests through shared bearer auth behavior — tested via `createBearerAuthMiddleware` + `createApiKeyValidator`. - [x] Missing, invalid, and revoked API keys fail with the standard API error shape — protected-route tests cover all three. - [x] Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior. - [x] Relevant lint/test checks pass — `make check`, `./scripts/pre-pr.sh`, manual migration smoke, and Forgejo CI passed. ### Blocking Issues None. ### Warnings None. ### Verdict Approved for merge.
erik 2026-05-22 11:53:44 -05:00
Author
Owner

Synced from todu comment by @todu on 2026-05-22T16:49:51.075Z

Closing Summary

PR #56 merged: #56

Acceptance criteria evidence:

  • API key migration applies from an empty SQLite database: met via migration test and manual migration smoke.
  • API key creation returns a raw key once and persists only a hash: met by createApiKey and tests asserting raw key is not persisted.
  • API key listing never exposes raw keys or hashes: met by metadata-only listApiKeys and redaction tests.
  • API key revocation prevents future authentication: met by revoked_at verification behavior and tests.
  • Valid API keys authenticate protected API requests through shared bearer auth behavior: met by protected route test using createBearerAuthMiddleware and createApiKeyValidator.
  • Missing, invalid, and revoked API keys fail with the standard API error shape: met by protected route tests.
  • Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior: met.
  • Relevant lint/test checks pass: met via make check, ./scripts/pre-pr.sh, PR CI, and main push CI.

Post-merge cleanup: local and remote feature branches deleted.

Readiness: READY

_Synced from todu comment by @todu on 2026-05-22T16:49:51.075Z_ ## Closing Summary PR #56 merged: https://forge.caradoc.com/erik/slugkit/pulls/56 Acceptance criteria evidence: - API key migration applies from an empty SQLite database: met via migration test and manual migration smoke. - API key creation returns a raw key once and persists only a hash: met by `createApiKey` and tests asserting raw key is not persisted. - API key listing never exposes raw keys or hashes: met by metadata-only `listApiKeys` and redaction tests. - API key revocation prevents future authentication: met by `revoked_at` verification behavior and tests. - Valid API keys authenticate protected API requests through shared bearer auth behavior: met by protected route test using `createBearerAuthMiddleware` and `createApiKeyValidator`. - Missing, invalid, and revoked API keys fail with the standard API error shape: met by protected route tests. - Tests cover hashing, one-time raw-key creation result, listing redaction, revocation, and protected-route auth behavior: met. - Relevant lint/test checks pass: met via `make check`, `./scripts/pre-pr.sh`, PR CI, and main push CI. Post-merge cleanup: local and remote feature branches deleted. Readiness: READY
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
erik/slugkit#33
No description provided.