Skip to content

docs(api): Phase 7c API-Auth design — 3-scope keys + rate-limit + /admin/api-keys UI#85

Merged
strausmann merged 3 commits into
mainfrom
docs/phase-7c-api-auth-spec
May 18, 2026
Merged

docs(api): Phase 7c API-Auth design — 3-scope keys + rate-limit + /admin/api-keys UI#85
strausmann merged 3 commits into
mainfrom
docs/phase-7c-api-auth-spec

Conversation

@strausmann
Copy link
Copy Markdown
Owner

@strausmann strausmann commented May 17, 2026

Summary

Phase 7c spec — closes the security gap exposed by Phase 7b deploy: single-secret Pangolin-Bypass replaced with multi-key app-side authentication.

Key design decisions (user-approved)

Decision Choice
Scope granularity 3 levels: read / print / admin
Rate limit 60/min default, configurable per-key, in-memory token bucket
Key storage bcrypt rounds=12, plaintext shown ONCE on creation, prefix-only in UI
Pangolin-Bypass post-7c Downgraded to read-only (feature-flagged) — recovery pathway preserved
Admin UI location New /admin/api-keys page, HTMX, Pangolin-SSO required
Audit fields api_key_id + source_ip on Jobs table

What's in scope

Backend:

  • New api_keys table + Alembic migration with bootstrap-admin seed
  • require_scope(level) FastAPI dependency, all routes annotated
  • bcrypt hashing + LRU cache (5min TTL) for <1ms warm verify
  • Per-key token bucket rate limiter
  • Per-key printer ACL (allowed_printer_ids)
  • Pangolin-Bypass scope-downgrade feature flag (pangolin_bypass_scope_downgrade)

Frontend (Go + HTMX):

  • /admin/api-keys page: list + create + revoke + detail-with-audit-log
  • Plaintext shown ONCE in copy-to-clipboard modal on creation

Out of scope (deferred)

  • OAuth / SSO Provider for browser users (Pangolin handles it)
  • Redis-backed limiter (single-instance design)
  • Per-user keys (HomeLab = 1 user)
  • Hardware-backed key storage

Spec polish — deferred suggestions

The following bot-review suggestions were reviewed and deferred as design choices appropriate for the HomeLab context:

Thread Suggestion Disposition
Line 62 (api_key_id FK) Use formal ForeignKey with ON DELETE SET NULL instead of "FK hint, no constraint" Deferred — the no-constraint approach is intentional: key deletion must not cascade or require a migration in Phase 7c. A proper FK with ON DELETE SET NULL is a Phase 7c.1 polish item once the table is stable.

Implementation

Overnight implementer subagent will derive the implementation plan from this spec on a feat branch. User reviews + merges in the next session.

Refs #22
Closes #78

…t, /admin/api-keys UI

App-side API-Key authentication replacing the current
single-secret Pangolin-Bypass for all writes. 3 scopes
(read/print/admin), bcrypt hashed keys with prefix UI
display, in-memory token-bucket rate limit, per-key
printer ACL, audit-trail in Jobs table, transition path
via feature flag for the Pangolin-Bypass scope-downgrade.

Refs #22
Refs #78
Copilot AI review requested due to automatic review settings May 17, 2026 22:47
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements Phase 7c of the API-Auth design, significantly hardening the application's security posture. By moving from a single shared secret to a granular, multi-key authentication system, the changes provide better access control, audit trails, and rate limiting. The implementation includes necessary database schema updates, a new administrative UI for key management, and a robust middleware layer to enforce scope-based access across the API.

Highlights

  • API Authentication Foundation: Introduced a robust, multi-key API authentication system using bcrypt-hashed keys and a 3-level scope model (read, print, admin) to replace the previous single-secret bypass.
  • Admin Management UI: Added a new HTMX-based admin interface at /admin/api-keys for managing keys, including creation, revocation, and audit logging.
  • Rate Limiting and Auditability: Implemented per-key rate limiting using an in-memory token bucket and added audit fields (api_key_id, source_ip) to the Jobs table for improved traceability.
  • Transition Strategy: Defined a secure migration path that includes a feature-flagged scope downgrade for the legacy Pangolin-Bypass authentication method.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.09%. Comparing base (cdaedeb) to head (a21d2f7).
⚠️ Report is 7 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #85      +/-   ##
==========================================
- Coverage   91.98%   91.09%   -0.89%     
==========================================
  Files          70       71       +1     
  Lines        3055     3189     +134     
  Branches      261      271      +10     
==========================================
+ Hits         2810     2905      +95     
- Misses        181      216      +35     
- Partials       64       68       +4     
Components Coverage Δ
Printer Backends (transport) 87.50% <ø> (ø)
Printer Models (drivers) 91.42% <ø> (ø)
Services 91.87% <ø> (-0.23%) ⬇️
REST API 87.04% <ø> (-4.26%) ⬇️
Pydantic Schemas 100.00% <ø> (ø)
Integration Plugins 100.00% <ø> (ø)
see 5 files with indirect coverage changes
Flag Coverage Δ
backend 91.09% <ø> (-0.89%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cdaedeb...a21d2f7. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Phase 7c design spec documenting the planned app-side API authentication model (scoped API keys, per-key rate limiting, admin UI, and audit fields) to address the current reliance on Pangolin edge auth.

Changes:

  • Introduces a new Phase 7c specification covering api_keys storage, endpoint scoping, rate limiting, and job audit fields.
  • Defines the /admin/api-keys HTMX UI flows and backend CRUD endpoints for key management.
  • Documents the transition plan for downgrading Pangolin Basic-Auth bypass to read-only via a feature flag.
Comments suppressed due to low confidence (1)

docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md:336

  • “Bootstrap-admin seed key emitted in startup log” is a high-risk requirement: secrets frequently end up in long-lived logs and third-party aggregators/backups. If the goal is avoiding lockout, prefer a bootstrap mechanism that surfaces the plaintext key out-of-band from normal app logs (or relies on Pangolin SSO for initial admin access).
- [ ] Backend API for key CRUD under `/api/admin/api-keys/*`
- [ ] Pangolin-bypass scope-downgrade feature flag
- [ ] Bootstrap-admin seed key emitted in startup log on first migration
- [ ] All tests passing, coverage >= 80%

Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request provides a design specification for app-side API authentication, introducing multi-key management, scoped access control, and rate limiting. The review feedback identifies critical implementation concerns: the necessity of offloading CPU-intensive bcrypt operations to thread pools to avoid blocking the FastAPI event loop, the need for the rate limiter to reflect database configuration changes, the recommendation for formal foreign key constraints to ensure data integrity, and the requirement for consistent timezone handling in database models.

Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md
Comment thread docs/superpowers/specs/2026-05-17-phase-7c-api-auth-design.md Outdated
…ixes

- 7c spec: fix key_prefix length example (11→12 chars consistent)
- 7c spec: datetime fields use DateTime(timezone=True) sa_column
- 7c spec: bootstrap seed key prints plaintext to Alembic stdout only (not app logger)
- 7c spec: require_scope() reconciles SSO=admin for /admin/* routes, 401 for missing creds / 403 for insufficient scope
- 7c spec: Pangolin-bypass reads feature flag settings.pangolin_bypass_scope_downgrade in pseudocode
- 7c spec: cache key is api_key_id (after prefix DB lookup), not raw hash; bcrypt uses asyncio.to_thread
- 7c spec: source_ip propagation via X-Real-IP injected by frontend proxy
- 7c spec: rate_limit_per_minute applies to all requests (not print-only); rename clarified
- 7c spec: RateLimiter uses asyncio.Lock + capacity-drift detection to handle concurrent requests + config changes
- 7d spec: replace strausmann.cloud with example.com (privacy scan fix)

Refs #22
Replace the pre-PR-#79-fix version of the Phase 7d spec with the
already-merged, privacy-sanitised version from main to eliminate
the merge conflict caused by main advancing past the PR base.

Refs #22
@strausmann strausmann merged commit 8792e84 into main May 18, 2026
11 checks passed
@strausmann strausmann deleted the docs/phase-7c-api-auth-spec branch May 18, 2026 07:24
github-actions Bot pushed a commit that referenced this pull request May 19, 2026
## <small>0.6.1 (2026-05-19)</small>

* fix(ui): preview-PNG data-URL must use template.URL type (#90) ([0f84976](0f84976)), closes [#90](#90) [#87](#87) [#22](#22) [#89](#89) [#22](#22)
* docs(api): Phase 7c API-Auth design — 3-scope keys + rate-limit + /admin/api-keys UI (#85) ([8792e84](8792e84)), closes [#85](#85) [#22](#22) [#78](#78) [#85](#85) [#22](#22) [#79](#79) [#22](#22)
* docs(api): Phase 7e Template Layout System v2 — semantic schema + aggregation (#86) ([0bab0c0](0bab0c0)), closes [#86](#86) [#22](#22) [#81](#81) [#22](#22)
* chore(deps): bump the go-minor-and-patch group (#89) ([d6ba346](d6ba346)), closes [#89](#89)

[skip ci]
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.

Phase 7c: App-side API-Authentifizierung (multi-key, scoped, audit-trail)

2 participants