Per-user forge connections — keyring, host-keyed resolution, project pin (#2778) #114

Merged
bvandeusen merged 1 commits from dev into main 2026-08-19 15:24:47 -04:00
Owner

Forge credentials move from instance-wide admin settings to per-user keyring rows, resolved by repo host on the project OWNER's keyring.

  • forge_connections table + projects.forge_connection_id pin (migration 0078 — carries the existing admin config into the first admin's row, deletes the old setting keys)
  • get_forge()get_forges(owner_id, project_id) -> ForgeSelector; pinned projects use ONLY their pinned connection; stale pins after ownership transfer are ignored, never honored across users
  • env FORGE_* survives as an implicit entry for admin owners only; stored rows beat it
  • routes: user-level /api/settings/forge-connections CRUD + test; /api/admin/forge shrinks to /api/admin/forge-webhook; PUT /api/projects/<id>/forge pins (owner's connections only)
  • UI: Git Forges card in Settings → Integrations; webhook secret stays admin; owner-only forge select on the project coverage card
  • backups exclude forge_connections (credentials, api_keys precedent)

CI: run 4012 green (typecheck, unit, integration incl. 0078 + six new keyring isolation tests).

🤖 Generated with Claude Code

Forge credentials move from instance-wide admin settings to per-user keyring rows, resolved by repo host on the project OWNER's keyring. - `forge_connections` table + `projects.forge_connection_id` pin (migration 0078 — carries the existing admin config into the first admin's row, deletes the old setting keys) - `get_forge()` → `get_forges(owner_id, project_id) -> ForgeSelector`; pinned projects use ONLY their pinned connection; stale pins after ownership transfer are ignored, never honored across users - env `FORGE_*` survives as an implicit entry for admin owners only; stored rows beat it - routes: user-level `/api/settings/forge-connections` CRUD + test; `/api/admin/forge` shrinks to `/api/admin/forge-webhook`; `PUT /api/projects/<id>/forge` pins (owner's connections only) - UI: Git Forges card in Settings → Integrations; webhook secret stays admin; owner-only forge select on the project coverage card - backups exclude `forge_connections` (credentials, api_keys precedent) CI: run 4012 green (typecheck, unit, integration incl. 0078 + six new keyring isolation tests). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bvandeusen added 1 commit 2026-08-19 15:24:38 -04:00
feat(forge): per-user forge connections — keyring, host-keyed resolution, project pin (#2778)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / TypeScript typecheck (push) Successful in 41s
CI & Build / integration (push) Successful in 37s
CI & Build / Python tests (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 40s
1faf8f3ece
A forge token is a user's credential, not an instance's. The single
admin-settings config is replaced by per-user keyring rows (one per forge
host), and every server-side forge read runs on the PROJECT OWNER's keyring:

- forge_connections table + projects.forge_connection_id pin (migration 0078,
  which also carries the existing admin config into the first admin's row and
  deletes the old setting keys — no legacy dual-read)
- get_forge() replaced by get_forges(owner_id, project_id) -> ForgeSelector;
  resolve(repo) picks the connection whose host serves the repo. A pinned
  project uses ONLY its pinned connection; a stale pin (ownership moved) is
  ignored, never honored across users
- env FORGE_* config survives as an implicit entry for admin owners only;
  a stored row for the same host beats it
- consumers threaded: pull-time freshness (owner of the note), coverage
  (owner of the project), coverage routes' configured flag
- routes: /api/settings/forge-connections CRUD + per-connection test
  (own-rows only, tokens never returned); /api/admin/forge shrinks to
  /api/admin/forge-webhook (secret only); PUT /api/projects/<id>/forge pins,
  owner-or-admin asking, owner's connections only
- UI: Git Forges card moves to Settings -> Integrations as a connection
  list; webhook secret stays in the admin Config tab; owner-only forge
  select on the project coverage card
- backups exclude forge_connections (credentials, api_keys precedent) and
  the pin, so restores fall back to keyring resolution

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bvandeusen merged commit c1cb8fb183 into main 2026-08-19 15:24:47 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledScribe#114