Skip to content

Harden and document the mcp gateway Authorization header contract against workspace credential exposure - #7794

Merged
lpcox merged 3 commits into
mainfrom
copilot/awf-fix-mcp-gateway-authorization-header
Aug 28, 2026
Merged

Harden and document the mcp gateway Authorization header contract against workspace credential exposure#7794
lpcox merged 3 commits into
mainfrom
copilot/awf-fix-mcp-gateway-authorization-header

Conversation

Copilot AI commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Engine config adapters that consume AWF's MCP gateway handoff can write the Authorization header verbatim into workspace-visible config files, making the gateway credential readable by any file-read tool, not just code execution. The concretely reported adapters (pydantic.md, crush.md, convert_gateway_config_codex.cjs) live in github/gh-aw, not this repo — this PR hardens and documents the AWF-side contract those adapters build on so the fix has an unambiguous, tested API to rely on.

  • Explicit, named contract constant

    • Extracted the Authorization header value in buildEnclaveMcpgUpstreamContract() into ENCLAVE_MCP_AUTHORIZATION_HEADER_TEMPLATE, a literal environment-variable-reference template (never the resolved capability).
    • buildEnclaveMcpgUpstreamContract() takes no environment argument, so it structurally cannot bake a real secret into the contract it returns.
  • Regression test

    • Added a test asserting the header always equals the literal template and never matches a resolved 64-char hex capability shape, guarding against a future refactor accidentally resolving the value.
  • Documentation

    • docs/enclaves-architecture.md and docs/awf-config-spec.md §14.3 now spell out that any config adapter rendering this contract into a file must copy the template verbatim and resolve it from the MCP client's own process environment at request time — never persist the resolved value to any agent-readable file.
// Before: inline, easy to miss the security intent
headers: { Authorization: 'Bearer ' + '$' + `{${ENCLAVE_MCP_CAPABILITY_ENV}}` }

// After: named, documented invariant
headers: { Authorization: ENCLAVE_MCP_AUTHORIZATION_HEADER_TEMPLATE }

Copilot AI changed the title [WIP] Fix readable MCP gateway authorization header in agent workspace Harden and document the mcp gateway Authorization header contract against workspace credential exposure Aug 27, 2026
Copilot AI requested a review from lpcox August 27, 2026 18:59
@lpcox
lpcox marked this pull request as ready for review August 27, 2026 19:02
Copilot AI balanced review requested due to automatic review settings August 27, 2026 19:02

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

Extracts and documents the enclave MCP upstream authorization template, but does not address the client-facing gateway credential exposure in #7787.

Changes:

  • Adds a named authorization-template constant.
  • Adds a regression test for the literal template.
  • Documents credential-handling requirements.
Show a summary per file
File Description
src/enclave/gateway.ts Extracts the upstream header template.
src/enclave/gateway.test.ts Tests that the template remains unresolved.
docs/enclaves-architecture.md Documents workspace credential exposure.
docs/awf-config-spec.md Adds authorization handling requirements.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread src/enclave/gateway.ts Outdated
type: 'http',
url: ENCLAVE_MCP_UPSTREAM_URL,
headers: { Authorization: 'Bearer ' + '$' + `{${ENCLAVE_MCP_CAPABILITY_ENV}}` },
headers: { Authorization: ENCLAVE_MCP_AUTHORIZATION_HEADER_TEMPLATE },
Comment thread docs/enclaves-architecture.md Outdated
Comment on lines +76 to +79
cannot bake a real secret into the contract it returns. Any config-adapter
that renders this contract into an engine or tool config file (for example
under `GITHUB_WORKSPACE`) MUST copy this template string verbatim and let the
MCP client resolve it from its own process environment at request time.
Comment thread docs/awf-config-spec.md Outdated
Comment on lines +1831 to +1834
argument so it cannot bake a real secret into the contract. Any config adapter
that renders this contract into an engine/tool config file MUST copy the
template verbatim and resolve it from the MCP client's own process environment
at request time; persisting the resolved capability to any agent-readable file
@lpcox

lpcox commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

@copilot address review feedback

Copilot AI commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address review feedback

Addressed in 48b1745: removed the misleading AWF upstream-only exposure claim and documented the separate mcpg client-to-gateway credential hop, including the runtime-only/no-persistence requirement for adapters consuming mcpg's rewritten output. Targeted gateway tests, type-check, docs lint, secret scanning, and CodeQL pass.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

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

@github-actions

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 1c8407c

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Contribution Check completed successfully!

Contribution check complete for PR #7794: the PR includes a clear description, references a related issue, adds documentation updates, and includes a regression test for the new contract constant. No contribution-guideline issues found.

Generated by Contribution Check for #7794

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

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

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

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

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini reports failed. Facets need polishing...

💎 Faceted by Smoke Gemini

@lpcox
lpcox deployed to aoai-model August 27, 2026 21:13 — with GitHub Actions Active
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Contribution Check completed successfully!

PR #7794 follows CONTRIBUTING.md: it includes tests for the new contract invariant, updates the relevant docs, references a related issue in the description, and keeps the change in existing src/docs files. No contribution-guideline issues found.

Generated by Contribution Check for #7794

@lpcox
lpcox deployed to aoai-model August 27, 2026 21:38 — with GitHub Actions Active
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

Generated by Build Test Suite for #7794

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

Copy link
Copy Markdown
Contributor

Copilot Network Isolation Smoke Test @lpcox

EGRESS_RESULT allow=pass deny=pass
  • ✅ Allowed domain (api.github.com): allowed=200
  • ✅ Blocked domain (example.com): denied via proxy (CONNECT 403)

Overall: PASS

Warning

Firewall blocked 1 domain

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

  • example.com

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

network:
  allowed:
    - defaults
    - "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

Copy link
Copy Markdown
Contributor

🧪 Smoke Test: Docker Sbx — PASS ✅

Overall: PASS

cc @lpcox

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Result
API status ✅ PASS
gh check ✅ PASS
File status ✅ PASS

Overall result: PASS

Generated by Smoke Claude for #7794 · claude · haiku45 · 59.7 AIC · ⊞ 4.5K ·
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode ✅

Test Result
GitHub MCP Connectivity
GitHub.com HTTP (200)
File Write/Read
BYOK Inference Path

Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) → api-proxy sidecar → api.githubcopilot.com

Status: PASS

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Services Connectivity

  • Redis PING: ❌ (name resolution failure for host.docker.internal)
  • PostgreSQL pg_isready: ❌ (no response, name resolution failure)
  • PostgreSQL SELECT 1: ❌ (name resolution failure)

Overall: FAILhost.docker.internal could not be resolved from the AWF sandbox.

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot Engine@lpcox

Overall: PASS

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

@lpcox
lpcox deployed to aoai-model August 27, 2026 21:42 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Harden and document the mcp gateway Authorization header contract against workspace credential exposure

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

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)

Overall: PASS

Cc: @lpcox @Copilot

🔑 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

Chroot vs Host Version Comparison

Runtime Host Version Chroot Version Match?
Python Python 3.12.14 Python 3.12.14 ✅ YES
Node.js v24.19.0 v22.23.2 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

⚠️ Not all tests passed — Node.js version differs between host and chroot environments. smoke-chroot label not added.

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

@github-actions

Copy link
Copy Markdown
Contributor
  • refactor: split Cloud Hypervisor backend helpers
  • Split Cloud Hypervisor manager lifecycle into focused modules
  • ❌ GitHub MCP PR listing
  • ✅ GitHub.com connectivity
  • ✅ File I/O test
  • ✅ BYOK inference test
    Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra
    Overall: FAIL
    /cc @lpcox @Copilot

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

@lpcox
lpcox deployed to aoai-model August 27, 2026 21:42 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test

PR titles:

  • Split Cloud Hypervisor manager lifecycle into focused modules
  • refactor: split Cloud Hypervisor backend helpers
  • Merged PR review: ✅
  • safeinputs-gh PR query: ❌
  • Playwright title check: ✅
  • File write/read: ✅
  • Discussion query/comment: ❌
  • Build (npm ci + npm run build): ✅
  • Overall: FAIL

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

network:
  allowed:
    - defaults
    - "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

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia passed ✅ PASS
Bun hono 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 run OK ✅ PASS
.NET json-parse run OK ✅ 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

Notes:

  • Java Maven required -Dmaven.repo.local pointed at a writable directory since the default ~/.m2/repository was not writable in this environment; the proxy config in ~/.m2/settings.xml (squid-proxy:3128) worked correctly for dependency downloads once the repo path was fixed.
  • All other ecosystems built/tested successfully on the first attempt with no firewall-related issues.

Generated by Build Test Suite for #7794 · copilot · auto · 51.1 AIC · ⊞ 12K ·
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: API Proxy OTEL Tracing — Results

  • Module Loading: otel.js loads successfully, exports startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, plus internal exporter classes (_ProxyAwareOtlpExporter, _FileSpanExporter, _FanOutSpanExporter).
  • Test Suite: otel.test.js, otel-fanout.test.js, otel-workload-identity.test.js68/68 tests passed.
  • Env Var Forwarding: env-passthrough.ts forwards GITHUB_AW_OTEL_TRACE_ID/GITHUB_AW_OTEL_PARENT_SPAN_ID/COPILOT_OTEL_FILE_EXPORTER_PATH to the agent container; api-proxy-env-config.ts (buildOtelEnv()) forwards OTLP endpoint/headers, service name, and parent trace context to api-proxy.
  • Token Tracker Integration: onUsage callback confirmed as the OTEL hook point in token-tracker-http.js (invoked after normalized usage extraction, feeding gen_ai.usage.* attributes).
  • OTEL Diagnostics: /tmp/gh-aw/otel.jsonl contains an exported span (gh-aw.agent.setup) with full resource attributes (service.name, run id, repo, engine), confirming OTLP export path is functioning end-to-end for this run.

All 5 scenarios pass. No unexpected failures.

📡 OTel tracing validated by Smoke OTel Tracing
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.

[awf] MCP gateway Authorization header is written readable into agent workspace via engine config files

3 participants