Skip to content

docs(github): plan for a multi-org company bot - #800

Merged
vikasprogrammer merged 1 commit into
mainfrom
feat/gh-multi-org
Sep 9, 2026
Merged

docs(github): plan for a multi-org company bot#800
vikasprogrammer merged 1 commit into
mainfrom
feat/gh-multi-org

Conversation

@vikasprogrammer

Copy link
Copy Markdown
Owner

The defect

GithubIdentity.ensureBotToken (src/edge/github-identity.ts:162) persists a single github_installation_id and, when it is unset, resolves it as installations[0] — whichever install GET /app/installations happens to return first — then caches one token blob under one vault key.

With the App installed on two orgs the bot acts on exactly one of them and 404s every repo in the other. Nothing fails at launch (the token is valid, it just doesn't cover that repo), so it reads to a human as "the agent can't see our repo". The stale-id retry path re-picks [0] as well, so a reinstall can flip which org works without anyone touching a setting.

The per-member OAuth lane is unaffected — a user-to-server token already spans every org that member can reach.

What the plan specs

  • Installation registry — a github_installations setting alongside the existing github_installation_id, which keeps its exact meaning as the primary. Both are plain settings rows: no migration, and a one-org tenant behaves bit-for-bit as today.
  • Per-installation token cachegithub_bot_token:<installationId>, with the legacy key migrated to the primary's suffixed key on first read.
  • Per-repo git credentialscredential.https://github.com.useHttpPath=true makes git pass path=<org>/<repo> to the helper, which resolves the right token through a new session-secret loopback route (modelled on /api/agent/github/refresh). Any failure falls back to $GH_TOKEN.
  • The member-lane guard — the route refuses a bot token to a run with a linked GitHub identity. Without it, a human's PR would be silently re-authored as agent-os[bot] the moment they touched a second org.
  • The gh gap, namedgh reads GH_TOKEN and ignores git credential helpers, so the helper fixes git for both orgs but not gh. Answer now is a github_token({ org }) MCP tool; a PATH shim that resolves the org from origin is sketched as a later PR.

Four phases, each its own PR, plus the tests to add to test:governance.

Docs only — no behaviour change, no version bump (CHANGELOG note under Unreleased).

🤖 Generated with Claude Code

https://claude.ai/code/session_01UfJRSqtHhuk7x51Cqy4NB5

The bot lane collapses to one org today: `ensureBotToken` persists a single
`github_installation_id` and, when unset, resolves it as `installations[0]` —
whichever install GitHub returns first. With the App on two orgs the bot acts on
one of them and 404s every repo in the other, with nothing failing at launch (the
token is valid, it just doesn't cover that repo), so it reads to a human as "the
agent can't see our repo". The stale-id retry re-picks `[0]` too, so a reinstall
can flip which org works with no setting touched.

The plan: an installation registry alongside the existing primary id (both plain
settings rows — no migration, single-org tenants unchanged), a vault token cache
keyed per installation, and a per-repo git credential helper that resolves the org
out of git's `path=` (via `useHttpPath`) through a session-secret loopback route.
The member OAuth lane already spans orgs and is deliberately left alone — the route
refuses to hand a bot token to a run with a linked human, since that would re-author
their PRs as the bot the moment they touched a second org. Also names the `gh` gap:
`gh` ignores git credential helpers, so it needs its own tool (then, later, a shim).

Docs only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfJRSqtHhuk7x51Cqy4NB5
@vikasprogrammer
vikasprogrammer merged commit 23de78a into main Sep 9, 2026
1 check passed
@vikasprogrammer
vikasprogrammer deleted the feat/gh-multi-org branch September 9, 2026 12:34
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