Rewrite GitHub SSH remotes to HTTPS in the sandbox

The in-container clone inherits origin verbatim from the host, which is
commonly an SSH URL. Nothing in the sandbox can satisfy SSH: there is no key
and port 22 is closed. Only HTTPS carries the Authorization header the proxy
substitutes the repository token into, so every push failed.

Setup now writes a global insteadOf rewrite for both SSH spellings. Doing it
globally rather than per-remote covers the clone, anything the agent clones
later, and submodules, and leaves the host's own .git/config untouched under
--direct, where the working tree is bind-mounted read-write.
This commit is contained in:
2026-08-05 13:30:09 -05:00
parent b5dfae0696
commit e0f6113320
3 changed files with 104 additions and 0 deletions
+7
View File
@@ -243,6 +243,13 @@ gh pr list
gh pr create --fill
```
So is `git push`. The clone inherits `origin` from the host, which is usually an SSH
URL, and SSH cannot work in the sandbox — there is no key and port 22 is closed. A
global `insteadOf` rewrites `[email protected]:` and `ssh://[email protected]/` to
`https://github.com/`, so the push traverses the proxy and picks up the token. Remotes
on other hosts are left alone, and under `--direct` the host's own `.git/config` is
never touched.
AWS named profiles work as Terraform expects:
```bash
+28
View File
@@ -1101,6 +1101,28 @@ EOF
' </dev/null >/dev/null 2>&1 || true
}
# The in-container clone inherits origin verbatim from the host, which is
# commonly an SSH URL. Nothing in the sandbox can satisfy SSH - there is no key
# and port 22 is closed - and only HTTPS carries the Authorization header the
# proxy substitutes the GitHub token into. Rewriting globally covers the clone,
# any repository the agent clones later, and every submodule, while leaving the
# host's own .git/config untouched under --direct.
install_sandbox_git_https() {
# shellcheck disable=SC2016
sbx exec "$SANDBOX_NAME" bash -c '
key="url.https://github.com/.insteadOf"
# insteadOf is multi-valued, so a plain set would replace the first
# form with the second and a repeat setup would accumulate duplicates.
git config --global --unset-all "$key" 2>/dev/null
git config --global --add "$key" "[email protected]:"
git config --global --add "$key" "ssh://[email protected]/"
' </dev/null >/dev/null 2>&1 ||
printf 'Could not rewrite GitHub SSH remotes to HTTPS in %s.\n' \
"$SANDBOX_NAME" >&2
}
validate_launch_mode() {
case "$1" in
agent | tmux) ;;
@@ -1383,6 +1405,10 @@ setup_command() {
install_sandbox_dotfiles
# After the dotfiles: the allowlist may carry a .gitconfig, which would
# otherwise land on top of the rewrite.
install_sandbox_git_https
install_sandbox_network
install_sandbox_secrets
@@ -1435,6 +1461,8 @@ config_command() {
install_sandbox_dotfiles
install_sandbox_git_https
install_sandbox_network
install_sandbox_secrets
+69
View File
@@ -0,0 +1,69 @@
#!/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
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
fail() {
printf 'FAIL: %s\n' "$1" >&2
failures=$((failures + 1))
}
HOME="$work/home"
SANDBOX_NAME=ai-test
mkdir -p "$HOME"
sbx() {
[[ "$1" == exec && "$2" == "$SANDBOX_NAME" && "$3" == bash && "$4" == -c ]] ||
fail "unexpected sbx invocation: $*"
HOME="$HOME" bash -c "$5"
}
resolved() {
git -C "$work/repo" ls-remote --get-url origin
}
git init --quiet "$work/repo"
for remote in \
'[email protected]:owner/repo.git' \
'ssh://[email protected]/owner/repo.git'; do
rm -f "$HOME/.gitconfig"
git -C "$work/repo" remote remove origin 2>/dev/null || true
git -C "$work/repo" remote add origin "$remote"
[[ "$(resolved)" == "$remote" ]] ||
fail "$remote was already rewritten before the sandbox was configured"
install_sandbox_git_https
[[ "$(resolved)" == 'https://github.com/owner/repo.git' ]] ||
fail "$remote resolved to $(resolved), not an HTTPS URL"
done
install_sandbox_git_https
install_sandbox_git_https
values="$(HOME="$HOME" git config --global --get-all \
'url.https://github.com/.insteadOf' | wc -l)"
[[ "$values" -eq 2 ]] ||
fail "repeated setup left $values insteadOf values, expected 2"
git -C "$work/repo" remote set-url origin '[email protected]:owner/repo.git'
[[ "$(resolved)" == '[email protected]:owner/repo.git' ]] ||
fail "a non-GitHub remote was rewritten to $(resolved)"
((failures == 0)) ||
exit 1
printf 'ok: GitHub SSH remotes are rewritten to HTTPS inside the sandbox\n'