Add repository-scoped AI sandbox mise task

Provides a shareable mise task, ai:sbx, that runs an AI coding agent in a
Docker Sandbox scoped to a single GitHub repository and a set of read-only
AWS roles.

The repository is derived from origin rather than configured, so the sandbox
identity cannot drift from the checkout in use. GitHub access is a
repository-scoped fine-grained PAT held in the sbx secret store and injected
by its host-side proxy, so the token is never exposed to the agent. The host
~/.aws directory and SSO token cache are never mounted; instead the host
exports short-lived credentials for approved read-only profiles and only
those land in the sandbox.

Host profiles are commonly suffixed to mark the grant (api-portal-readonly)
while Terraform references the account name (api-portal), so a trailing
-readonly is stripped when the profile is written into the sandbox. Two host
profiles that collapse to the same sandbox name are rejected during setup,
before any credentials are exported, since a silent overwrite would hand
Terraform the wrong identity under a plausible-looking name.

All state lives under ~/.config/ai-sbx; repositories supply nothing and need
no mise.toml.
This commit is contained in:
2026-07-30 13:52:57 -05:00
commit d43abe693e
3 changed files with 950 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
# shellcheck source-path=SCRIPTDIR
# shellcheck source=tasks/ai/sbx
source "$(dirname "${BASH_SOURCE[0]}")/../tasks/ai/sbx"
failures=0
assert_maps() {
local input="$1" expected="$2" actual
actual="$(sandbox_profile_name "$input")"
if [[ "$actual" != "$expected" ]]; then
printf 'FAIL: %s -> %s, expected %s\n' "$input" "$actual" "$expected" >&2
failures=$((failures + 1))
fi
}
assert_dies() {
local description="$1"
shift
if (validate_profile_mapping "$@") 2>/dev/null; then
printf 'FAIL: %s was accepted\n' "$description" >&2
failures=$((failures + 1))
fi
}
assert_maps api-portal-readonly api-portal
assert_maps prod-readonly prod
assert_maps dev dev
assert_maps readonly-first readonly-first
assert_maps team-readonly-readonly team-readonly
validate_profile_mapping api-portal-readonly prod-readonly dev
assert_dies 'dev-readonly colliding with dev' dev-readonly dev
assert_dies 'empty profile name' -readonly
if ((failures)); then
printf '%d assertion(s) failed\n' "$failures" >&2
exit 1
fi
printf 'All profile mapping assertions passed.\n'