Skip to content

feat(auth): wire and validate API key auth end-to-end, close Bug #24 - #40

Merged
bodybybuddha merged 2 commits into
devfrom
feature/api-key-auth-e2e
Apr 15, 2026
Merged

bodybybuddha merged 2 commits into
devfrom
feature/api-key-auth-e2e

Conversation

@bodybybuddha

Copy link
Copy Markdown
Owner

Summary

Completes the last 1.0.0 scope item: fully wired and validated API key authentication/authorization, closing Bug #24.

Changes

Bug #24 — Scope validation (fixed)

  • Exported VALID_SCOPES constant from validation.py; CreateAPIKeyRequest Pydantic validator now rejects any unknown scope with 422 — arbitrary values like admin, superuser are blocked at creation
  • require_scopes dependency was already wired on project endpoints — tests now unconditionally assert 403 for keys lacking the required scope (previously soft-conditional, so the test never actually enforced anything)

Expiration — user choice (no more silent default)

  • Keys now default to no expiration (expires_at = null) — the previous undocumented 1-year default is gone
  • JSON API: supply expires_at (ISO 8601) or omit/null for never
  • Form: replaced preset dropdown with a radio toggle (No expiration default / Set expiration date → date picker)
  • Backend validates the chosen date is in the future

last_used_at tracking

  • api_keys model gains a last_used_at (nullable DateTime) column
  • _get_user_id_from_api_key in auth.py updates it on every successful authentication (best-effort — auth not blocked if update fails)
  • Migration 010: adds the column

Tests

  • Rewrote tests/integration/test_api_key_scopes.py with 11 real tests covering: valid/invalid scope creation, read/write scope enforcement, revocation, no-expiry nullability, future/past expiry, and last_used_at
  • Strengthened tests/validation/test_api_key_validation.py: scope rejection now asserts 422; insufficient-scope usage now asserts 403 unconditionally; no-expiry key asserts expires_at is null

Checklist

- Add VALID_SCOPES constant to validation.py; CreateAPIKeyRequest validator
  now rejects unknown/arbitrary scopes with 422 (Bug #24)
- Scope enforcement already wired via require_scopes on project endpoints;
  regression tests now unconditionally assert 403 for under-scoped keys
- API keys default to NO expiration (null); previous silent 1-year default
  removed — users can now supply a specific date or leave blank for forever
- Form date-picker replaces preset dropdown: radio 'No expiration' (default)
  or 'Set expiration date' with a date input (YYYY-MM-DD)
- JSON API supports expires_at ISO string or null/omitted for no expiry
- Record last_used_at on every successful API key authentication (best-effort)
- Migration 010: add last_used_at column (nullable DateTime) to api_keys
- Add VALID_SCOPES to api_key model comment and bump key_hash comment to SHA-256
- Rewrite tests/integration/test_api_key_scopes.py with full scope/expiry/
  revocation coverage (11 tests replacing placeholder)
- Close Bug #24 in BUGS.md; update CHANGELOG under [Unreleased / v1.0.0-rc.1]
@bodybybuddha
bodybybuddha merged commit b27a7b5 into dev Apr 15, 2026
5 checks passed
@bodybybuddha
bodybybuddha deleted the feature/api-key-auth-e2e branch April 15, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant