Skip to content

fix: don't mask Copilot CLI's ~/.copilot/config.json#6374

Merged
lpcox merged 1 commit into
mainfrom
fix-copilot-config-json-access
Jul 18, 2026
Merged

fix: don't mask Copilot CLI's ~/.copilot/config.json#6374
lpcox merged 1 commit into
mainfrom
fix-copilot-config-json-access

Conversation

@lpcox

@lpcox lpcox commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

smoke-copilot was failing consistently: the Copilot CLI crashed silently at startup (exit 1, zero stdout/stderr, ~0.5s).

Root cause: the centralize-mount-policy change (#6339) added .copilot/config.json to the credential deny list with the reason "Copilot CLI persisted auth token". That reason is incorrect:

  • ~/.copilot/config.json contains only experiment-assignment cache, first-launch timestamps, tips-shown flags, and installed-plugin metadata — no token. The Copilot CLI's real credentials live elsewhere (its sqlite stores), and ~/.copilot is already bind-mounted rw as a tool subdir, so masking config.json protected nothing.
  • Compose masks credential files with a read-only /dev/null overlay. The Copilot CLI reads and rewrites config.json at startup via temp-file + atomic rename (verified: the inode changes on write). A rename can't target a bind-mounted file, and the mask is read-only regardless — so the CLI crashed. sbx was unaffected because it moves the file aside, letting the CLI create a fresh one.

Fix

Remove .copilot/config.json from the credentials deny list — reverting the one problematic line from #6339. The CLI now reads/writes its config normally (pre-#6339 behavior).

This supersedes the earlier toolWritable / writable-stub approach on this branch: that added machinery couldn't work anyway (you can't rename over a bind-mounted file), and it's unnecessary once we recognize config.json isn't a credential file. History was collapsed to a single commit.

Also updated the sbx/compose tests, the sbx-manager.ts comment, and docs/sbx-integration.md that used config.json as their example credential path.

Validation

  • npm run build
  • Full suite: 3852 tests pass ✅
  • npm run lint: 0 errors ✅

Copilot AI review requested due to automatic review settings July 18, 2026 16:32
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 26ff40c

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds tool-writable credential policy support to prevent Copilot CLI startup failures in compose mode.

Changes:

  • Adds and validates toolWritable.
  • Excludes Copilot config from read-only compose overlays.
  • Documents and tests compose/sbx behavior.
Show a summary per file
File Description
src/config/sandbox-mount-policy.json Marks Copilot config tool-writable.
src/config/mount-policy.ts Parses and applies the new flag.
src/config/mount-policy.test.ts Tests policy filtering.
src/services/agent-volumes/credential-hiding.test.ts Verifies compose omission.
docs/mount-policy.md Documents tool-writable files.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/config/mount-policy.ts Outdated
const files: string[] = [];
for (const entry of mountPolicy.credentials) {
if (entry.type === 'file') {
if (entry.toolWritable) continue;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in b5fdf88. Instead of skipping the mask, compose now overlays a sandbox-owned empty writable stub file over each toolWritable credential (buildToolWritableCredentialOverlays). The stub is created and chowned to the agent UID/GID under the chroot-home placeholder in prepareChrootHomeMounts, then bind-mounted :rw at both the real $HOME path and the /host$HOME path. The Copilot CLI reads/writes the throwaway stub, while the host's real ~/.copilot/config.json never reaches the agent. sbx is unchanged (still moves the path aside).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked this entirely — you were right that the writable-stub approach was wrong, but it turned out the whole entry was the mistake.

~/.copilot/config.json is not a credential file. It holds only experiment-assignment cache, first-launch timestamps, tips-shown flags, and installed-plugin metadata — no token (verified against a real config). The Copilot CLI stores its actual auth elsewhere (sqlite stores), and ~/.copilot is already bind-mounted rw as a tool subdir, so masking config.json protected nothing in the first place.

It also could never work: the CLI rewrites config.json via temp-file + atomic rename (the inode changes on write), and you cannot rename over a bind-mounted file — plus the /dev/null mask was read-only. That, not a missing fresh-config, is what crashed smoke-copilot.

So the fix is now just removing .copilot/config.json from the credentials deny list (the one bad line from #6339). No stub, no new flag. History collapsed to a single commit.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Coverage Regression Detected

This PR decreases test coverage. Please add tests to maintain coverage levels.

Overall Coverage

Metric Base PR Delta
Lines 98.64% 98.65% 📈 +0.01%
Statements 98.46% 98.46% ➡️ +0.00%
Functions 99.24% 99.24% ➡️ +0.00%
Branches 94.55% 94.51% 📉 -0.04%
📁 Per-file Coverage Changes (2 files)
File Lines (Before → After) Statements (Before → After)
src/config/mount-policy.ts 80.2% → 79.6% (-0.59%) 74.3% → 74.3% (+0.05%)
src/log-directory-setup.ts 96.2% → 100.0% (+3.78%) 96.3% → 100.0% (+3.71%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

lpcox added a commit that referenced this pull request Jul 18, 2026
Address review feedback on #6374. Rather than skipping the credential
mask for toolWritable entries (which exposed the host's real
~/.copilot/config.json via the rw ~/.copilot bind mount), compose now
overlays a sandbox-owned empty writable stub file. The Copilot CLI reads
and writes the throwaway stub while the host's real file — which may hold
a persisted auth token — never reaches the agent.

Stubs are created (owned by the agent UID/GID) under the chroot-home
placeholder in prepareChrootHomeMounts and removed with it on cleanup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4bdbe67a-cb99-41a2-944b-49cfd949360e
@github-actions

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@lpcox Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

Comment thread src/chroot-home-setup.ts Fixed
Comment thread src/chroot-home-setup.ts Fixed
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Coverage Regression Detected

This PR decreases test coverage. Please add tests to maintain coverage levels.

Overall Coverage

Metric Base PR Delta
Lines 98.64% 98.64% ➡️ +0.00%
Statements 98.46% 98.46% ➡️ +0.00%
Functions 99.24% 99.25% 📈 +0.01%
Branches 94.55% 94.47% 📉 -0.08%
📁 Per-file Coverage Changes (3 files)
File Lines (Before → After) Statements (Before → After)
src/chroot-home-setup.ts 100.0% → 98.5% (-1.54%) 100.0% → 98.5% (-1.54%)
src/config/mount-policy.ts 80.2% → 80.4% (+0.17%) 74.3% → 75.2% (+0.93%)
src/log-directory-setup.ts 96.2% → 100.0% (+3.78%) 96.3% → 100.0% (+3.71%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@lpcox

lpcox commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot fix failed codeql check

Copilot AI commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

@copilot fix failed codeql check

Fixed in the latest commit. The two CodeQL alerts on src/chroot-home-setup.ts:139 were:

  1. TOCTOU race condition — removed the existsSync guard; the file is now created atomically with flag: 'wx' (O_EXCL), which throws EEXIST (caught and ignored) rather than racing between check and write.
  2. Insecure temporary file — added mode: 0o600 for each stub file and mode: 0o700 for the stub directory, restricting access to the owning process only.

CodeQL re-scan returned 0 alerts.

Copilot finished work on behalf of lpcox July 18, 2026 17:25
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Coverage Regression Detected

This PR decreases test coverage. Please add tests to maintain coverage levels.

Overall Coverage

Metric Base PR Delta
Lines 98.64% 98.62% 📉 -0.02%
Statements 98.46% 98.44% 📉 -0.02%
Functions 99.24% 99.25% 📈 +0.01%
Branches 94.55% 94.44% 📉 -0.11%
📁 Per-file Coverage Changes (3 files)
File Lines (Before → After) Statements (Before → After)
src/chroot-home-setup.ts 100.0% → 97.0% (-3.04%) 100.0% → 97.0% (-3.04%)
src/config/mount-policy.ts 80.2% → 80.4% (+0.17%) 74.3% → 75.2% (+0.93%)
src/log-directory-setup.ts 96.2% → 100.0% (+3.78%) 96.3% → 100.0% (+3.71%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (api-key) reports failed. AOAI BYOK (api-key) mode investigation needed...

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — Service connectivity failed ⚠️

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) reports failed. AOAI BYOK (Entra) mode investigation needed...

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Smoke Claude passed

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK reports failed. BYOK mode investigation needed...

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini completed. All facets verified. 💎

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Contribution Check failed. Please review the logs for details.

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Build Test Failed Build Test Suite - See logs for details

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing reports failed. OTel tracing regression detected. ⚠️

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

🔑 Smoke Copilot PAT reports failed. PAT auth path may have issues...

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation reports failed while checking network isolation. Investigate the egress model.

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot PAT Auth

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ (pre-step template vars unexpanded)
File write/read ⚠️ (pre-step template vars unexpanded)

Overall: PASS
Auth mode: PAT (COPILOT_GITHUB_TOKEN)
PR author: @lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔑 PAT report filed by Smoke Copilot PAT
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results

Test Result
MCP Connectivity
GitHub.com HTTP ⚠️ pre-step vars unresolved
File Write/Read ⚠️ pre-step vars unresolved

Overall: ⚠️ PARTIAL — template expressions not substituted before agent invocation.

CC @lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Services Connectivity

  • Redis PING: ❌ (host.docker.internal DNS resolution failed)
  • PostgreSQL pg_isready: ❌ (no response)
  • PostgreSQL SELECT 1: ❌ (DNS resolution failed)

Overall: FAILhost.docker.internal is not resolvable in this environment.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke test: network-isolation egress enforcement

EGRESS_RESULT allow=pass deny=pass

✅ Allowed domain (api.github.com) — HTTP 200
✅ Blocked domain (example.com) — 403 / blocked

Overall: PASS@lpcox

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • awmgmcpg
  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions github-actions Bot added smoke-copilot-network-isolation Copilot network-isolation egress smoke test smoke-copilot-byok labels Jul 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode

✅ GitHub MCP connectivity
✅ github.com HTTP (200)
✅ File write/read ops
✅ BYOK inference path active

Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) via api-proxy → api.githubcopilot.com
Status: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔑 BYOK report filed by Smoke Copilot BYOK
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🔥 AWF API Proxy OTEL Smoke Test Results

Scenario Result Notes
1. Module Loading otel.js loads; exports: startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled + test internals
2. Test Suite 39/39 tests pass (otel.test.js)
3. Env Var Forwarding api-proxy-env-config.ts forwards GH_AW_OTLP_ENDPOINTS, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, GITHUB_AW_OTEL_TRACE_ID, GITHUB_AW_OTEL_PARENT_SPAN_ID, OTEL_SERVICE_NAME
4. Token Tracker Integration onUsage callback present in token-tracker-http.js (line 343) — OTEL hook confirmed
5. OTEL Diagnostics File exporter active (fallback); spans written to /var/log/api-proxy/otel.jsonl when no endpoint configured

All 5 scenarios pass. OTEL tracing integration is functional with graceful degradation.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.18.0 v22.23.1 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

⚠️ Not all runtimes match — Python minor version differs (3.12.13 vs 3.12.3) and Node.js major version differs (v24 vs v22). The smoke-chroot label was not added.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Tested by Smoke Chroot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test\n- Reviewed PR: fix(smoke-copilot): revert agent job to read-only perms to unblock CI\n- Reviewed PR: Smoke Copilot: grant PR write permissions required by safe outputs\n- GitHub PR read: ✅\n- Discussion comment: ✅\n- File write/read: ✅\n- Build: ✅\n- Playwright title check: ❌\n- Overall status: FAIL

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • awmgmcpg
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke test result: PASS/FAIL analysis in progress.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

💎 Faceted by Smoke Gemini
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test direct BYOK (AzureOpenAI, o4-mini-aw):

  • MCP connectivity: ✅
  • GitHub.com connectivity: ✅
  • File I/O test: ✅
  • BYOK inference: ✅

Running in direct BYOK mode via api-proxy → AzureOpenAI (Foundry, o4-mini-aw)
Overall PASS

@lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Smoke Test: Docker Sbx — PASS

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ 200
File write/read Smoke test passed for Docker Sbx at Sat Jul 18 17:54:27 UTC 2026

Overall: PASS 🟢

📰 BREAKING: Report filed by Smoke Docker Sbx
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color passed ✅ PASS
Go env passed ✅ PASS
Go uuid passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx passed ✅ PASS
Node.js execa passed ✅ PASS
Node.js p-limit passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Build Test Suite for #6374 · 100.1 AIC · ⊞ 7.1K ·
Add label ready-for-aw to run again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants