Skip to content

feat: rotate GitHub tokens in place + re-point external projects at a different token - #85

Merged
dvcdsys merged 2 commits into
developfrom
feat/github-token-rotation-and-project-token-select
Jun 22, 2026
Merged

feat: rotate GitHub tokens in place + re-point external projects at a different token#85
dvcdsys merged 2 commits into
developfrom
feat/github-token-rotation-and-project-token-select

Conversation

@dvcdsys

@dvcdsys dvcdsys commented Jun 22, 2026

Copy link
Copy Markdown
Owner

What

Two admin-only capabilities for GitHub Integration:

  1. Rotate a key in placePUT /api/v1/github-tokens/{id} replaces a stored PAT's secret, re-validating against GitHub and refreshing scopes. The id/name stay the same, so every external project bound to the token keeps working with no re-binding.
  2. Re-point an external projectPUT /api/v1/projects/{hash}/git-repo/token changes which stored PAT a project uses (null detaches → public), via a token dropdown on the project's settings page.

Why

An expired GitHub PAT silently broke every external project bound to it. Tokens were immutable — the only "fix" was delete + recreate, which mints a new id, leaving all linked projects pointing at the old one (clone/fetch/webhook ops fail). And a project's token_id was set once at creation with no way to change it afterward. These two features close both gaps.

How

  • Service layer: githubtokens.Update() (re-encrypt + refresh scopes, id/name preserved) and gitrepos.SetTokenID() (nullableString → public when empty; webhook left intact).
  • Handlers: UpdateGithubToken (re-runs the same ValidateToken flow as create) and UpdateProjectGitRepoToken (validates the token id exists → 422 otherwise, 404 for local projects). Both gate on mustBeAdmin first.
  • Both endpoints added to doc/openapi.yaml; openapi.gen.go regenerated via make openapi-gen (confirmed idempotent).
  • Frontend: rotate dialog per token row in TokensTab, token <Select> + useUpdateProjectToken in SyncSettingsCard; generated.ts regenerated, dashboard rebuilt.
  • docs/AUTH_REVIEW.md matrix updated (both new rows are Admin).

Type of change

  • New feature

Checklist

  • HTTP handler tests + full go test ./... pass (service round-trip, rotate refresh-scopes/invalid/not-found, project token attach-detach-422-404, admin-gating 403)
  • go vet clean; dashboard tsc typecheck + lint + vite build pass
  • No secrets or API keys committed (plaintext PATs never logged or echoed)
  • Manual dashboard click-through not run (needs llama-server + interactive browser); API contract covered by tests

🤖 Generated with Claude Code

dvcdsys and others added 2 commits June 22, 2026 14:27
…rnal projects at a different token

An expired GitHub PAT silently broke every external project bound to it:
tokens were immutable (delete + recreate minted a new id), and a project's
token_id was set once at creation with no way to change it.

Two admin-only capabilities, both flowing through the OpenAPI spec:

1. Rotate a key in place — PUT /api/v1/github-tokens/{id} replaces the secret,
   re-validates against GitHub (GET /user) like create, and refreshes the
   stored scopes. id + name are unchanged, so linked projects keep working
   with no re-binding. UI: rotate dialog per token row in TokensTab.

2. Re-point an existing external project — PUT /api/v1/projects/{hash}/git-repo/token
   changes git_repos.token_id (null detaches → public). Validates the token id
   exists (422 otherwise); webhook left intact. UI: token dropdown in the
   project's SyncSettingsCard.

Adds githubtokens.Update() + gitrepos.SetTokenID() service methods, regenerated
openapi.gen.go, and tests: service round-trip, HTTP rotate (refresh scopes /
invalid / not-found), project token attach-detach-422-404, and admin-gating 403.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PUT /api/v1/github-tokens/{id} and PUT /api/v1/projects/{hash}/git-repo/token
gate on mustBeAdmin, which returns 403 for an authenticated non-admin — but the
spec only listed 401. Add the shared Forbidden (403) response to both, between
401 and 404. openapi.gen.go regenerated via make openapi-gen (only the embedded
spec blob changes; no types/interface/route changes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dvcdsys
dvcdsys merged commit 3ba6cf3 into develop Jun 22, 2026
1 check passed
@dvcdsys
dvcdsys deleted the feat/github-token-rotation-and-project-token-select branch June 22, 2026 13:56
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.

1 participant