DiamondLightSource / DiamondLightSource/claude-sandbox
gh-auth: support a second, organisation-scoped GitHub token
- Dominant language
- Shell
- Stars
- 0
- Forks
- 2
- Avg merge
- 3h 11m
- Merged PRs (30d)
- 26
Description
## Problem
A fine-grained PAT has one resource owner, and `gh` stores one token per username per host. A single account that needs push access to repositories in two organisations therefore cannot hold both tokens: the second `gh auth login --with-token` replaces the first, and `gh auth switch` only helps when the tokens belong to different accounts.
Concrete case: an agent testing podbench against a cluster needs `epics-containers/podbench` (fixes, PRs) and a services repository in another organisation (`podbench hotfix apply` pushes to it). Both are the same user's account.
## Proposal
Git already routes credentials by path prefix, and helpers are asked in config order until one answers. Verified in a sandbox with fake helpers: an organisation section listed before the host-wide one wins for that organisation, and the prefix match is component-wise (`t11-org` does not match `t11-orgx`). `gh auth git-credential` also honours `GH_TOKEN`, so the scoped section can reuse the same helper:
```ini
[credential "https://github.com/ORG"]
helper = !GH_TOKEN=$(cat ~/.config/gh/scoped/ORG.token) gh auth git-credential
[credential "https://github.com"]
helper = !gh auth git-credential
```
Changes, roughly fifteen lines:
1. `claude-sandbox gh-auth --scope ORG` stores the pasted token at `~/.config/gh/scoped/ORG.token`, mode 600. Without `--scope` the command behaves as today. The directory is the existing container-scoped gh credential dir, so the token has the same lifetime and blast radius as the current one (Invariant 2 unchanged).
2. `render_gitconfig` in the shadow emits one section per file in `scoped/`, before the host-wide `github.com` section.
3. A paragraph in `docs/how-to/authenticate-with-forges.md`, and a `tests/bwrap_argv.sh` scenario asserting the rendered section order.
## Why ORG must be supplied
GitHub exposes no resource owner for a fine-grained PAT, and `gh api user/repos` under such a token still lists public repositories of every organisation the user belongs to, so the owner cannot be inferred from the token. Defaulting to the owner of the workspace `origin` remote is a cheap convenience, but the explicit form is what the two-organisation case needs. The recipe should print the section it will render so a mistyped organisation is visible at once.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_012Ur9Ks9k6VGnwc8PG7y73L
Contributor guide
Research direction
Start with the gh-auth command handling and the render_gitconfig function described in the issue. Review tests/bwrap_argv.sh and docs/how-to/authenticate-with-forges.md, then verify scoped tokens are stored with mode 600, scoped sections precede the host-wide section, and the scenario passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github, shell
- Domain
- authentication, cli, tooling
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100