Repository navigation
fix(acq): use sandbox workspace for github scoping - #476
Conversation
|
AI-assisted review (OpenCode), advisory — needs a human to confirm before it drives a change. Reviewed at head The defect this fixes is real: scoping a token to whatever repos happen to sit in the caller's 1. It collides with #504, and the resolution matters for more than merge order. #504 now carries ADR-0030 and its implementation, and commit 3 migrates the - ws=$({ _acq_msb_cli exec "$name" -u 0 -- sh -c 'cat /var/lib/acq/workspace …
+ ws=$(acq_host_config_read msb "$name" workspace | tr -d '\r\n')Both PRs modify 2. The sbx half is not covered by that migration ( acq_backend_workspace_for() {
sbx exec "$1" -- sh -c 'printf "%s" "${ACQ_WORKSPACE:-}"' </dev/null 2>/dev/null || true
}I grepped #504's diff for Nothing validates it in between — no absolute-path check, no Quoting is fine throughout; I checked every expansion. This is about scope, not injection. 3. The guest value is persisted as though it were host provenance ( gs_ws=$(acq_backend_workspace_for "$gs_sandbox")
[ -z "$gs_ws" ] || acq_workspace_record_write "${ACQ_RESOLVED_BACKEND}" "$gs_sandbox" "$gs_ws" || trueAfter one fallback, every later run takes the "recorded" branch and reports Fail-closed would be to drop the guest fallback entirely: a sandbox with no record can simply require the explicit Smaller items: Method: static analysis at head |
|
AI-assisted adversarial review (nexus-agents High:
On msb — the default backend — Suggested fix: either map guest→host before recording on msb (acq already knows the host mount path at provision time — that's what should be persisted), or have msb's provisioning path capture the host-side value the same way sbx does, rather than the guest env var. Secondary, non-blocking (raised as conditions if the above is fixed, not separate blockers):
No command-injection, no scope-creep, no over-engineering findings — the added helpers reuse the existing provenance-file/awk/mv machinery rather than introducing a new store. The core defect is specifically the msb/sbx path-domain mismatch above. |
|
Addressed the review feedback and pushed commit Changes since the review:
Verification:
Please re-review when you have a chance. |
basiliskus
left a comment
There was a problem hiding this comment.
Reviewed at 48a7aa0.
I reviewed the current head with the change-review procedure, focusing on the credential-scoping path and the prior advisory findings. The risky guest-to-host fallback appears removed from the github-scope path: pathless acq github-scope now reads only host-marked provenance and fails closed when no trusted record exists.
-
Minor: PR description is stale (PR body, no file line)
The body still says this PR adds fallback workspace discovery where SBX reads
ACQ_WORKSPACEfrom the guest and MSB reads/var/lib/acq/workspace. Current code no longer does that:acq github-scopereadsacq_workspace_record_readand errors if no host-marked record exists, andacq_backend_workspace_foris gone. Please update the PR body before merge so the review/merge record does not describe the unsafe fallback that was removed.
Below the bar: the test/bats/90-sbx-startup-kit.bats git-identity isolation change is not directly part of github-scope, but it is small and test-isolation-only, so I would not block on it.
Validation note: I confirmed the working tree is at 48a7aa02064eb3a8c9ce3c35aacec1b111489aef, reviewed the diff from 907f4043d14d65e1b70fb62eef6b1d4d8dac4606, checked the prior advisory comments, ran git diff --check and ShellCheck locally with no output, and inspected gh pr checks 476, which shows all checks passing at this head. I did not locally run ./scripts/test-acq-bats or npm run lint:md in this read-only review session because they can create temp/cache artifacts; I relied on the passing GitHub checks for those.
Verdict: approve/comment at 48a7aa02064eb3a8c9ce3c35aacec1b111489aef.
Assisted-by: OpenCode [usai/gpt_5_5_default_v2] change-review
🤖 I have created a release *beep* *boop* --- ## [4.0.0](v3.1.0...v4.0.0) (2026-10-06) ### ⚠ BREAKING CHANGES * **kits:** acq no longer installs podman/OCI tooling by default. Users who need docker, docker compose, or rootless podman when the base image doesn't provide it must opt into the oci-engine kit with `acq configure`, `--kit`, or `ACQ_EXTRA_KITS`. * **kits:** acq no longer performs native OpenCode npm fallback installation. OpenCode is supplied by the pinned opencode agent kit from agentic-coding-patterns v1.12.0, currently delivering OpenCode v2.0.22. If the kit is unavailable or invalid, acq fails closed instead of installing opencode-ai from npm. * **kits:** existing acq sandboxes with adapter-installed podman are not migrated in place. Recreate affected sandboxes or add the oci-engine kit before relying on OCI behavior after stop/start. ### Features * **acq:** choose the host port per sandbox, and let --publish pin it ([#526](#526)) ([410f332](410f332)) * **acq:** export ACQ_WORKSPACE and ACQ_CLONE into the guest on both backends ([#457](#457)) ([e0b9a3b](e0b9a3b)) * **acq:** interactive `acq configure` UI for extra kits + token-scoping defaults ([#500](#500)) ([13d9d3a](13d9d3a)) * **kits:** adopt pinned agent and capability kits ([#474](#474)) ([6a67063](6a67063)) * **secrets:** add Windows-native DPAPI secret backend ([#464](#464)) ([907f404](907f404)) * **windows:** add acq preview install path ([#463](#463)) ([d6d76f4](d6d76f4)) ### Bug Fixes * **acq:** use sandbox workspace for github scoping ([#476](#476)) ([1610835](1610835)) * **ci:** bump js-yaml to 4.3.2 to clear a high-severity CPU-DoS advisory ([#454](#454)) ([3217b49](3217b49)) * **ci:** bump smol-toml to 1.7.1 to clear an infinite-loop DoS advisory ([#459](#459)) ([c2291bf](c2291bf)) * **ci:** centralize markdownlint coverage ([#548](#548)) ([a27c31e](a27c31e)) * **ci:** pin markdownlint-cli2 once, clear GHSA-253c, unify file selection ([#527](#527)) ([e712685](e712685)) * **ci:** unblock unrelated PRs from the bash32 required-check deadlock ([#513](#513)) ([187aa57](187aa57)) * **install:** keep curl | sh stdin intact and tap msb formula first ([#462](#462)) ([c808d74](c808d74)) * **install:** trust the microsandbox-acq dependency before brew install ([#534](#534)) ([ffac0fa](ffac0fa)) * **kits:** land collapsed kit stack implementation ([#549](#549)) ([bcd5b9c](bcd5b9c)) * **msb:** allow Playwright browser downloads ([#477](#477)) ([0c399c5](0c399c5)) * **msb:** block unsafe 0.7 migration versions ([#510](#510)) ([3634046](3634046)) * **msb:** carry every origin URL, keep the scratch private, fail closed on a copy miss ([#488](#488)) ([babcd49](babcd49)) * **msb:** carry the source checkout's git identity into the --clone scratch ([#443](#443)) ([320d784](320d784)) * **msb:** follow the host resolvers and disable DNS rebind protection in the guest ([#444](#444)) ([d2f4bdc](d2f4bdc)) * **msb:** point the --clone scratch's origin at the source checkout's remote ([#455](#455)) ([7f48b94](7f48b94)) * **msb:** refresh ssh authorization for port publish ([#446](#446)) ([72a6bd5](72a6bd5)) * **msb:** session parity for exec/attach/shell (cwd, terminal identity, login shell) ([#427](#427)) ([6261eda](6261eda)) * **msb:** skip the recursive home chown when the image baked the agent user ([#432](#432)) ([d8f66a4](d8f66a4)) * **msb:** thread the merged kit env onto kit lifecycle commands ([#519](#519)) ([2248a92](2248a92)) * **msb:** translate kit wildcard network rules ([#451](#451)) ([e22bbc3](e22bbc3)) * **msb:** verify post-hoc port forward listener ([#530](#530)) ([8ca50e1](8ca50e1)) * **msb:** warn on broadened kit wildcard rules ([#460](#460)) ([6ded3ce](6ded3ce)) * **msb:** warn when ssh-agent route is missing ([#448](#448)) ([3a767a4](3a767a4)) * **sbx:** emit valid setup.install shape for the git-identity mixin ([#492](#492)) ([8e6160c](8e6160c)) * **sbx:** raise the version floor to 0.39.0, where sbx create --env first exists ([#491](#491)) ([30f9ecf](30f9ecf)) * **sbx:** wait for startup barrier before attach ([#512](#512)) ([33c83c5](33c83c5)) * **secret:** reject multiline test secret values ([#447](#447)) ([f2da950](f2da950)) * **secrets:** propagate rotation across backends ([#509](#509)) ([9641958](9641958)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Bret Mogilefsky <bret.mogilefsky@gsa.gov>
Context
acq github-scope SANDBOXpreviously defaulted the workspace path to the caller's current directory. That could suggest repositories unrelated to the sandbox when the command was run from a parent directory. The flow also printed one PAT URL per GitHub owner but accepted only one token, even though fine-grained PATs are single-owner and acq stores one sandbox-scoped GitHub token today.Changes
acq github-scope SANDBOXto the sandbox's recorded workspace instead of$PWD.ACQ_WORKSPACEfrom the guest./var/lib/acq/workspacemarker.Verification
git diff --checkpassed.npm run lint:mdpassed with 0 issues.printf '%s\n' acq acq.backends/*.sh scripts/test-acq-lib.sh scripts/test-acq-bats test/bats/*.bats test/bats/helper.bash | xargs -r -n8 shellcheck --severity=warningpassed../scripts/test-acq-batspassed: 477/477.Rollback
Revert commit
c4a66c9to restore the priorgithub-scopebehavior.Security Impact
Improves least-privilege GitHub token guidance by preventing accidental scoping to unrelated repositories and failing closed for unsupported multi-owner PAT flows. No secret values are logged or placed on argv. AI-assisted.