diff --git a/docs/sbx-integration.md b/docs/sbx-integration.md index 2dd84a98d..ad0d2c5e6 100644 --- a/docs/sbx-integration.md +++ b/docs/sbx-integration.md @@ -188,7 +188,7 @@ What `createSandbox()` shares, in order: **Scrubbing nested credential stores.** Several whitelisted dirs legitimately hold tool settings but also stash a secret in a well-known child — e.g. `.config/gh`, `.config/gcloud`, `.cargo/credentials`, `.claude/.credentials.json`, -`.copilot/config.json`, `.gemini/oauth_creds.json`. Because the parent is mounted +`.gemini/oauth_creds.json`. Because the parent is mounted wholesale and sbx cannot overlay or mask a nested path, the manager instead **moves those credential paths aside on the host before `sbx create` and restores them after the sandbox is torn down** (`scrubHomeCredentials` / diff --git a/src/config/mount-policy.test.ts b/src/config/mount-policy.test.ts index 2be9dedc3..427302e0e 100644 --- a/src/config/mount-policy.test.ts +++ b/src/config/mount-policy.test.ts @@ -117,7 +117,7 @@ describe('mount-policy', () => { expect(paths).toContain('.config/gh'); expect(paths).toContain('.cargo/credentials'); - expect(paths).toContain('.copilot/config.json'); + expect(paths).toContain('.claude/.credentials.json'); // Never-mounted parents are excluded. expect(paths).not.toContain('.ssh/id_rsa'); expect(paths).not.toContain('.aws/credentials'); diff --git a/src/config/sandbox-mount-policy.json b/src/config/sandbox-mount-policy.json index ff72eac3d..715538ec3 100644 --- a/src/config/sandbox-mount-policy.json +++ b/src/config/sandbox-mount-policy.json @@ -52,7 +52,6 @@ { "path": ".cargo/credentials", "type": "file", "reason": "crates.io registry token" }, { "path": ".cargo/credentials.toml", "type": "file", "reason": "crates.io registry token (newer cargo)" }, { "path": ".claude/.credentials.json", "type": "file", "reason": "Claude Code OAuth tokens" }, - { "path": ".copilot/config.json", "type": "file", "reason": "Copilot CLI persisted auth token" }, { "path": ".gemini/oauth_creds.json", "type": "file", "reason": "Gemini CLI OAuth tokens" }, { "path": ".gemini/google_accounts.json", "type": "file", "reason": "Gemini CLI account identity" }, { "path": ".gemini/access_tokens.json", "type": "file", "reason": "Gemini CLI cached access tokens" }, diff --git a/src/sbx-manager.test.ts b/src/sbx-manager.test.ts index ac0da9d7e..fc707dbf8 100644 --- a/src/sbx-manager.test.ts +++ b/src/sbx-manager.test.ts @@ -182,14 +182,12 @@ describe('sbx-manager', () => { const parents = [ `${homePath}/.cargo`, `${homePath}/.claude`, - `${homePath}/.copilot`, `${homePath}/.gemini`, ]; const secrets = [ `${homePath}/.cargo/credentials`, `${homePath}/.cargo/credentials.toml`, `${homePath}/.claude/.credentials.json`, - `${homePath}/.copilot/config.json`, `${homePath}/.gemini/oauth_creds.json`, `${homePath}/.gemini/google_accounts.json`, ]; @@ -244,10 +242,10 @@ describe('sbx-manager', () => { it('restores scrubbed credentials after the sandbox is removed', async () => { const homePath = process.env.HOME || '/home/runner'; - const secret = `${homePath}/.copilot/config.json`; + const secret = `${homePath}/.claude/.credentials.json`; mockedExistsSync.mockImplementation( (p: fs.PathLike) => - String(p) === `${homePath}/.copilot` || + String(p) === `${homePath}/.claude` || String(p) === secret || String(p).includes('.awf-sbx-cred-backup'), ); diff --git a/src/sbx-manager.ts b/src/sbx-manager.ts index b7be8dd18..17f4dc4af 100644 --- a/src/sbx-manager.ts +++ b/src/sbx-manager.ts @@ -268,7 +268,7 @@ export async function createSandbox(config: SbxConfig): Promise { // individual file, so child-by-child expansion would drop loose files the // agent needs (e.g. ~/.copilot/mcp-config.json). Several of these dirs also // nest a credential store — e.g. .config/gh, .cargo/credentials, - // .claude/.credentials.json, .copilot/config.json, .gemini/oauth_creds.json. + // .claude/.credentials.json, .gemini/oauth_creds.json. // Those specific paths are moved aside on the host BEFORE `sbx create` (see // scrubHomeCredentials below) and restored after teardown, so the benign tool // state stays available while the secrets never enter the microVM. diff --git a/src/services/agent-volumes/credential-hiding.test.ts b/src/services/agent-volumes/credential-hiding.test.ts index 743bdf023..71116371f 100644 --- a/src/services/agent-volumes/credential-hiding.test.ts +++ b/src/services/agent-volumes/credential-hiding.test.ts @@ -23,7 +23,6 @@ describe('buildCredentialHidingOverlays', () => { expect(overlays).toContain('/dev/null:/home/runner/.config/gh/hosts.yml:ro'); expect(overlays).toContain('/dev/null:/host/home/runner/.config/gh/hosts.yml:ro'); // Newly centralized entries (previously only protected by sbx). - expect(overlays).toContain('/dev/null:/home/runner/.copilot/config.json:ro'); expect(overlays).toContain('/dev/null:/home/runner/.claude/.credentials.json:ro'); expect(overlays).toContain('/dev/null:/home/runner/.gemini/oauth_creds.json:ro'); });