trackslash
TRACK-77 P2

Save GitHub tokens on your account and reuse them across projects

0
All issues

Description

Problem

Every GitHub repository connection stores its own fine-grained access token. Connecting repositories in several projects means generating (or digging out) a token and pasting it again for each one. When a token expires, every connection that used it has to be reconnected by hand, one project at a time.

Expected behavior

  • A user saves one or more GitHub tokens on their account, each with a custom name (e.g. "Personal", "Work").
  • Connecting a repository on a project's About page lets you pick one of your saved tokens instead of pasting a new one.
  • Updating a saved token (for example after it expires) updates every repository connection that uses it, in every project, at once.
  • Saved tokens can be renamed, replaced and removed.

Acceptance criteria

  • Storage: saved tokens live in a new per-user table (migration), encrypted with AES-256-GCM using associated data bound to the token's row and owner. Tokens are never returned by the API or sent to browsers.
  • Validation: GitHub checks a token before it is saved or replaced (GET /user), and the token's GitHub login is shown next to it.
  • Names: unique per user, case-insensitively.
  • Ownership: only a token's owner can use it to connect a repository.
  • Connections: a repository connection references a saved token rather than holding its own copy. Existing connections that hold their own token keep working unchanged.
  • Removing a token: disconnects the repositories that use it. Their issue links keep showing their last known state, just as after a manual disconnect, and the project changelog records the disconnect without revealing the token's private name.
  • Tokens page UI: a "GitHub tokens" section on the Tokens account page lists saved tokens with their login, how many repositories use them, and when they were last checked. Add, edit/replace and remove actions use modals, with a confirmation that states how many repositories will be disconnected.
  • Connect dialog: the About page dialog offers the user's saved tokens. Pasting a new token there saves it to the account, so it can be picked in other projects. If the token saves but the connection then fails, the dialog says the token was saved.
  • About page: each connected repository shows which token it uses. The viewer's own token appears by name, anyone else's as "saved token", and legacy per-connection tokens as "project token".
  • API parity: GET|POST /api/v1/me/github-tokens and PATCH|DELETE /api/v1/me/github-tokens/{id}. Connecting a repository accepts credential_id as well as the existing token.
  • OAuth connectors: tokens issued to connectors can't manage saved GitHub tokens or connect a repository with one.
  • Docs: DEPLOYMENT.md and DESIGN_CONTEXT.md are updated.
  • Tests cover:
    • store CRUD, ownership, name conflicts, rotation and deletion
    • service encryption binding and rotation
    • API and UI flows, including errors and the unconfigured server
    • connector refusal

Status

Merged: PR #164, squash-merged to main as 924f5d7. CI passed: build + vet + test and docker build + healthcheck.

Changed during the final rebase:

  • #162 split Settings into account pages, so the "GitHub tokens" section moved to the Tokens page (/tokens#github-tokens), between Connectors and Web sessions.
    • Its forms still post to /settings/github-tokens, matching how #162 kept the other settings form routes, and they render the Tokens page.
    • The About page's Connect dialog links there.
  • Migrations 0044–0046 landed from #163, #165 and #167, so this change's migration is internal/migrations/0047_github_credentials.sql.

Verified:

  • Locally after the rebase, these packages pass: internal/store, internal/server, internal/githubintegration, internal/model and internal/seed.
  • go vet, gofmt and npm run assets are clean.
  • Checked the Tokens page and the Connect dialog in headless Chromium, in light and dark mode and at phone width.

Design decisions:

  • Saved tokens are shared by reference, not copied into each connection. This is the only way replacing a token can rotate it for every project.
  • Removing a token disconnects its repositories rather than leaving them broken. Reconnecting the same repository revives it with the same id, so its issue links resume.
  • The API still accepts an inline token for compatibility. The web UI no longer creates per-project tokens; pasting one saves it to the account.
  • Associated data for saved tokens is "github-credential\x00{id}\x00{user}". Legacy per-connection tokens keep project\x00repo.

Sub-issues

0

Linked issues

0

GitHub

0

No branches or pull requests linked.

Comments

0
No comments.