fix(agent-team): dispatch via GitHub App so P3 reaches CI (run_id resolves) #63
1 changed files with 29 additions and 11 deletions
|
|
@ -99,30 +99,48 @@ access tokens** on demand (`agent_team/github_app.py`). Set all three of these t
|
|||
turn the App path on (all-or-nothing — partial config logs one warning and falls
|
||||
back to the inert gh-default path, it never crashes serve):
|
||||
|
||||
The App is the existing **`agent-team-apply`** App: **app_id `4119505`**,
|
||||
**installation `141992144`** (on `Sea-Haven-Industries/orchestrator`). These two
|
||||
IDs are not secrets (only the `.pem` is). Set all three vars (all-or-nothing —
|
||||
partial config logs one warning and falls back to the inert gh-default path, it
|
||||
never crashes serve):
|
||||
|
||||
```
|
||||
echo 'AGENT_TEAM_GH_APP_ID=...' >> ~/secrev.env # the App's numeric app_id
|
||||
echo 'AGENT_TEAM_GH_APP_INSTALLATION_ID=...' >> ~/secrev.env # installation id on Sea-Haven-Industries/orchestrator
|
||||
echo 'AGENT_TEAM_GH_APP_ID=4119505' >> ~/secrev.env
|
||||
echo 'AGENT_TEAM_GH_APP_INSTALLATION_ID=141992144' >> ~/secrev.env
|
||||
echo 'AGENT_TEAM_GH_APP_PRIVATE_KEY=/home/adam/.sea-haven/agent-team-apply.pem' >> ~/secrev.env # PATH to the .pem
|
||||
chmod 600 ~/secrev.env
|
||||
```
|
||||
|
||||
Place the App private key on the box and lock it down — it is a write-capable
|
||||
credential and must be owner-only:
|
||||
credential and must be owner-only. The CI-side Actions secret
|
||||
`AGENT_APPLY_APP_PRIVATE_KEY` is write-only and cannot be re-exported, so the
|
||||
box gets its OWN freshly-generated private key for the same App (generate one
|
||||
under the App settings — the App holds several keys; the CI key keeps working).
|
||||
Secure-copy it from the Mac (do NOT commit it; it is not in the repo):
|
||||
|
||||
```
|
||||
install -m 600 /dev/stdin ~/.sea-haven/agent-team-apply.pem < the-downloaded-key.pem
|
||||
chmod 600 ~/.sea-haven/agent-team-apply.pem && ls -l ~/.sea-haven/agent-team-apply.pem # expect -rw-------
|
||||
# From the Mac (the key lives in ~/Downloads after generation):
|
||||
scp ~/Downloads/agent-team-apply.*.private-key.pem adam@10.10.60.120:~/.sea-haven/agent-team-apply.pem
|
||||
# On the box:
|
||||
chmod 700 ~/.sea-haven && chmod 600 ~/.sea-haven/agent-team-apply.pem
|
||||
ls -l ~/.sea-haven/agent-team-apply.pem # expect -rw-------
|
||||
# Then DELETE the Mac copy (the box now holds the only working copy):
|
||||
# rm ~/Downloads/agent-team-apply.*.private-key.pem
|
||||
```
|
||||
|
||||
- `AGENT_TEAM_GH_APP_PRIVATE_KEY` is a **filesystem path** to the `.pem`, not the
|
||||
key material. The coordinator reads the file at graph-build time; an unreadable
|
||||
path logs one warning and falls back to gh-default (never crashes).
|
||||
- **App permission/scope audit (do before deploy).** The App (currently the
|
||||
reused **`agent-team-apply`** App) must be installed on **only**
|
||||
`Sea-Haven-Industries/orchestrator` with **Contents: Read/Write** + **Actions:
|
||||
Read/Write** and nothing broader. Minting an installation token grants exactly
|
||||
the App's scopes; over-broad scopes widen blast radius. (Follow-up: move to a
|
||||
dedicated least-privilege App to replace `agent-team-apply`.)
|
||||
- **App permission/scope (verified 2026-06-24).** A test mint of an installation
|
||||
token for app `4119505` / install `141992144` returned
|
||||
`{"actions":"write","contents":"write","metadata":"read","pull_requests":"write"}`
|
||||
with `repository_selection: selected` — i.e. Contents R/W + Actions R/W are in
|
||||
place and the install is scoped to selected repos (not all). Minting grants
|
||||
exactly the App's scopes; keep it scoped to `Sea-Haven-Industries/orchestrator`
|
||||
only. (Follow-up: move to a dedicated least-privilege App to replace
|
||||
`agent-team-apply`, dropping `pull_requests:write` which the box path does not
|
||||
need.)
|
||||
- The minted token is short-lived (~1h), is **never** logged, never put in an
|
||||
exception message, and never written to the ledger/graph state; on the
|
||||
authenticated push it rides in a host-scoped `http.extraHeader` passed via
|
||||
|
|
|
|||
Reference in a new issue