fix(acq): bind GitHub token at create by prompting before provision - #386
Conversation
|
Leaving this in the draft state until #370 lands, whereupon we'll need to port the tests to BATS. |
9be912e to
1773b76
Compare
On msb, secrets bind at create time (--secret ENV@HOST), so the GitHub token must be stored before the sandbox is created — the same constraint the USAi key gate already respects. Move advise_github_scope ahead of acq_backend_provision on the fresh-create path of both create and run. Warn-and-continue: declining never aborts (the token is optional). Re-attach keeps a post-heal advisory that drives the live re-feed path. Co-authored-by: OpenCode [claude_4_8_opus] <bret.mogilefsky@gsa.gov>
19ff091 to
b2d9a54
Compare
wz-gsa
left a comment
There was a problem hiding this comment.
Adversarial review — LGTM
Structural correctness verified. `advise_github_scope` is called and returns as its own statement BEFORE `acq_backend_provision "$local_name" "$@"` is invoked (both at the fresh-`create` site and the fresh-create branch of `run`) — so the token write the prompt performs completes before the function that reads secrets to build `--secret` flags is even called. This isn't just "the call moved earlier in the file", it's the right causal ordering. The re-attach branch correctly gets a DIFFERENT treatment (an advisory that drives the live re-feed path, since a re-attach can't re-bind at create) — that distinction is exactly right and easy to get wrong.
Warn-not-block confirmed. Read `advise_github_scope`: on decline it `echo`s a continuation note and `return 0` — no exit code that could abort `create`. Matches ADR-0013 and is the correct contrast with the USAi gate (which fails closed).
Non-interactive path is safe. `[ ! -t 0 ]` short-circuits to advise-and-continue without blocking on a `read` — correct for CI/piped callers.
Non-blocking observations
-
Stale verification claim in the description: it cites `scripts/test-acq: 1142 passed`, but that runner doesn't exist on this branch (`git show origin/main:scripts/test-acq` — 0 bytes) — it was retired by the bats migration. The actual new coverage is correctly in `test/bats/30-dispatch-routing.bats`; just flagging the prose is stale (likely copied from before the local checkout picked up the migration).
-
The new test asserts co-occurrence, not sequencing. `create(msb): github advisory runs before provision…` checks `assert_output --partial 'no repo-scoped GitHub token'` AND `assert_regex "$CALLS" 'msb create'` — both true, but that doesn't prove the advisory ran first. I checked: `$CALLS` is a strictly append-only log (one `printf … >>"$CALLS"` per stub invocation), so line order is invocation order — a genuinely-available, cheap strengthening would be asserting the advisory's line number precedes `msb create`'s in `$CALLS` (or having the stub log a sentinel and checking relative position). Not blocking since the source-level ordering is structurally sound and independently verifiable by reading the diff, but a regression that silently moved the call back wouldn't be caught by this test today.
Approve — small, well-scoped, matches the USAi-gate pattern it's modeled on.
AI-assisted (OpenCode).
Context
On the MSB backend, secrets are bound at create time (
--secret ENV@HOST) — the same constraint the USAi API key already respects (ensure_key_presentruns beforeacq_backend_provision). But the GitHub-token prompt (advise_github_scope) ran afteracq_backend_provision, so a token stored during that prompt would never bind to the just-created sandbox.This makes the GitHub token behave like the USAi key: the prompt to set/scope it now happens before the sandbox is created.
Changes
acq(dispatch):createverb: movedadvise_github_scopeto run beforeacq_backend_provision, right after theensure_key_presentUSAi gate.runverb, fresh-create branch: addedadvise_github_scopebeforeacq_backend_provision(it previously only ran post-provision).runverb, re-attach branch: kept an advisory call — a re-attach can't rebind at create, so there it drives the live re-feed path (msb modify/ sbx proxy).The prompt now runs pre-create for all backends and stays warn-and-continue (declining never aborts the create — the GitHub token is optional, consistent with ADR-0013, unlike the USAi gate which fails closed).
Docs:
docs/adr/0013-per-sandbox-github-token-downscoping.md— documents the pre-create ordering and rationale.docs/howto/msb.md— notes that both the USAi key and a GitHub token must be in place before create, and thatacq run/acq createhandle this ordering.Verification
bash -n acqandbash -n scripts/test-acq: clean./scripts/test-acq: 1142 passed, 0 failed (+3 new msb assertions covering "advisory runs beforemsb create" and "declined advisory still provisions")shellcheck --severity=warningonacq,acq.backends/common.sh,scripts/test-acq: clean (one file per invocation, per the repo's shellcheck guidance)Security impact
No change to attack surface. The GitHub token is still read from the TTY (never argv), stored sandbox-scoped, and the real value never enters the guest. Reordering only affects when the prompt fires relative to sandbox creation.
Rollback
Revert the single commit on this branch; the prior post-provision ordering is restored.