fix: harden dev.containers.copyGitConfig — docs + runtime cleanup - #95
fix: harden dev.containers.copyGitConfig — docs + runtime cleanup#95shejnowicz wants to merge 6 commits into
Conversation
Design: belt-and-braces fix for issue #34. The dev.containers.copyGitConfig setting placed in devcontainer.json.customizations.vscode.settings is inert — VS Code's Dev Containers extension reads it from HOST user settings, not the container-side JSON, so the host .gitconfig still gets copied. Two-part fix: 1. Docs correction: update devcontainer.json comment + README to note the host-user-settings requirement, mirroring the existing terminal.integrated.allowLocalTerminal warning. 2. Runtime cleanup: app-user-init.sh unconditionally removes ~/.gitconfig before applying the sandcat-managed identity from env vars. Idempotent, applies to every agent, no configuration. Plan: 4 tasks — runtime cleanup in app-user-init.sh, devcontainer.json comment + bats test, README update, hands-on integration test that poisons ~/.gitconfig via docker cp and verifies cleanup wipes it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Hardens sandcat devcontainer behavior around dev.containers.copyGitConfig by documenting the host-settings requirement and adding a runtime cleanup so host .gitconfig contents can’t leak into the container.
Changes:
- Add a bats test ensuring the template comment mentions “host user settings”
- Update
app-user-init.shto remove~/.gitconfigbefore applying env-derived git identity - Update template comment and README to clarify the host user settings requirement and the cleanup fallback
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| cli/test/init/devcontainer.bats | Adds an assertion that the template comment points users to host settings. |
| cli/templates/devcontainer/sandcat/scripts/app-user-init.sh | Removes any existing ~/.gitconfig before applying sandcat-managed git config. |
| cli/templates/devcontainer/devcontainer.json | Expands the comment to clarify where copyGitConfig must be set and notes the runtime fallback. |
| README.md | Updates hardening docs to explain the host settings requirement and the cleanup behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @test "devcontainer.json comment notes copyGitConfig needs host user settings" { | ||
| # Verify the comment above `dev.containers.copyGitConfig` explicitly | ||
| # points at the host-user-settings requirement — mirrors the note on | ||
| # `terminal.integrated.allowLocalTerminal`. See issue #34. | ||
| local template="$SCT_TEMPLATEDIR/devcontainer/devcontainer.json" | ||
| run grep -B4 '"dev.containers.copyGitConfig"' "$template" | ||
| assert_success | ||
| assert_output --partial "host user settings" | ||
| } |
| # VS Code's Dev Containers extension reads dev.containers.copyGitConfig | ||
| # from HOST user settings, not from devcontainer.json — so a host | ||
| # ~/.gitconfig may have been copied in even though our template | ||
| # declares copyGitConfig: false (see issue #34). Remove any leftover | ||
| # gitconfig so it can't leak host credential helpers / signing keys | ||
| # or override the env-derived identity we're about to apply. | ||
| # Unconditional and idempotent — `-f` swallows the missing-file case. | ||
| rm -f "$HOME/.gitconfig" |
| // Signal our intent to VS Code that host .gitconfig should not | ||
| // be copied into the container (which can leak credential helpers | ||
| // and signing key references). NOTE: this setting is read by VS | ||
| // Code's Dev Containers extension from HOST user settings, not | ||
| // from this file, so it only takes full effect if you also set | ||
| // "dev.containers.copyGitConfig": false in your host user settings. | ||
| // See README for details. app-user-init.sh removes any .gitconfig | ||
| // that gets through as a defense-in-depth cleanup. |
| - **Disables git config copying** (`dev.containers.copyGitConfig: false` in | ||
| `devcontainer.json`) to prevent leaking host credential helpers and signing | ||
| key references into the container. The VS Code Dev Containers extension | ||
| reads this setting from your **host** user settings, not from | ||
| `devcontainer.json`, so for full effect also set it in | ||
| `~/Library/Application Support/Code/User/settings.json` (macOS) or the | ||
| equivalent for your OS. As a defense-in-depth fallback, `app-user-init.sh` | ||
| removes any `.gitconfig` that gets copied in anyway. |
… enumerate OS paths - Bats: replace brittle grep -B4 window with two independent grep -q presence checks (setting key + "host user settings" phrase anywhere in file) - devcontainer.json: reword comment from "Signal our intent" to "Document intent only" to make clear the setting here alone does NOT prevent copying - README: replace vague macOS-only path hint with explicit table of all three OS paths and a Command Palette alternative Addresses Copilot review comments on PR #95. See issue #34. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Three of the four Copilot comments addressed in
|
Fixes #34.
Summary
dev.containers.copyGitConfig: falseplaced indevcontainer.json.customizations.vscode.settingsis inert where it sits — VS Code's Dev Containers extension reads this setting from the host user settings, not fromdevcontainer.json. Result: the host.gitconfig(with credential helpers, signing key IDs,commit.gpgsign = true, etc.) gets copied into the container despite sandcat's declared intent otherwise, breaking sandcat's promise in the README's "Consequences of hardening" section.Two-part fix (belt-and-braces):
devcontainer.jsoncomment and README updated to note that the setting must also be in host user settings for full effect (mirrors the existingterminal.integrated.allowLocalTerminalwarning that already flags this same class of trap).app-user-init.shunconditionallyrm -f "$HOME/.gitconfig"before applyingGIT_USER_NAME/GIT_USER_EMAILfrom env. Whatever the extension copied (if the user's host settings don't disable the copy), sandcat wipes it before the agent runs. Applies to all agents identically.Test plan
fix/34-copyGitConfig-hardeninglocally, including the new assertion that thedevcontainer.jsoncomment mentions"host user settings"~/.gitconfigcontains only sandcat-managed keys (user.name,user.emailfrom env;commit.gpgsign = false)docker cpa fake.gitconfigwithuser.signingkey,credential.helper = osxkeychain,commit.gpgsign = true,core.editor = /usr/bin/nano-evilinto/home/vscode/.gitconfig— mimics what VS Code Dev Containers extension does/usr/local/bin/app-user-init.shuser.signingkey,credential.helper,core.editorall absent;user.name/user.emailback to sandcat env-derived values;commit.gpgsignback tofalseNotes
app-user-init.sh— on the next container start, any.gitconfigin the agent-home volume (including one the user might have manually created inside the container) is removed. Users who want to customize git config in-container should do it viaGIT_USER_NAME/GIT_USER_EMAILenv vars or a post-start hook, not by editing.gitconfigdirectly.copyGitConfig: falsealready declares the intent; the runtime cleanup honors that intent regardless of whether host settings agree. If a future opt-in is needed (e.g.SANDCAT_KEEP_HOST_GITCONFIG=true), that's a separate PR.🤖 Generated with Claude Code