Skip to content

feat: add Copilot BYOK support via COPILOT_API_KEY#1918

Merged
lpcox merged 4 commits intomainfrom
copilot/add-support-for-byok-env-var
Apr 11, 2026
Merged

feat: add Copilot BYOK support via COPILOT_API_KEY#1918
lpcox merged 4 commits intomainfrom
copilot/add-support-for-byok-env-var

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 11, 2026

Adds support for COPILOT_API_KEY as a direct Copilot API key (BYOK) alongside the existing COPILOT_GITHUB_TOKEN OAuth flow. When api-proxy is enabled, the key is held exclusively in the sidecar — never exposed to the agent.

Changes

  • src/types.ts — new copilotApiKey?: string field on WrapperConfig
  • src/cli.ts — reads COPILOT_API_KEY from env; updates validateApiProxyConfig to treat either token as satisfying the Copilot key requirement; excludes from redacted config log
  • src/docker-manager.ts:
    • Adds COPILOT_API_KEY to AWF_ONE_SHOT_TOKENS
    • Sets early placeholder (placeholder-token-for-credential-isolation) when api-proxy is enabled to block --env-all leakage
    • Forwards real value to api-proxy sidecar; forwards to agent only when api-proxy is not enabled
    • COPILOT_API_URL + COPILOT_TOKEN placeholder now also set when copilotApiKey is provided
  • containers/api-proxy/server.js — introduces COPILOT_AUTH_TOKEN = COPILOT_GITHUB_TOKEN || COPILOT_API_KEY (GitHub token takes precedence); Copilot proxy starts with either key present
  • containers/agent/api-proxy-health-check.sh — validates COPILOT_API_KEY is placeholder when api-proxy is active

Usage

export COPILOT_API_KEY="cpat_..."   # BYOK direct key
sudo -E awf --enable-api-proxy \
  --allow-domains api.githubcopilot.com \
  -- npx @github/copilot --prompt "..."

COPILOT_GITHUB_TOKEN and COPILOT_API_KEY are interchangeable; if both are set, COPILOT_GITHUB_TOKEN takes precedence in the proxy.

Copilot AI linked an issue Apr 11, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add support for new BYOK env var feat: add Copilot BYOK support via COPILOT_API_KEY Apr 11, 2026
Copilot AI requested a review from lpcox April 11, 2026 18:55
@lpcox lpcox marked this pull request as ready for review April 11, 2026 19:02
@lpcox lpcox requested a review from Mossaka as a code owner April 11, 2026 19:02
Copilot AI review requested due to automatic review settings April 11, 2026 19:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Bring Your Own Key (BYOK) support for GitHub Copilot via COPILOT_API_KEY, integrating it into the existing API-proxy credential-isolation flow so the real key can be kept in the sidecar (and only passed to the agent when the proxy is disabled).

Changes:

  • Extend config + CLI env parsing to support COPILOT_API_KEY alongside COPILOT_GITHUB_TOKEN.
  • Update docker-compose generation to protect/forward COPILOT_API_KEY correctly (one-shot-token + placeholder isolation + sidecar injection).
  • Update api-proxy sidecar to accept either Copilot credential, with precedence for COPILOT_GITHUB_TOKEN, plus docs/examples/tests adjustments.
Show a summary per file
File Description
src/types.ts Adds copilotApiKey?: string and documents behavior when API proxy is enabled.
src/cli.ts Reads COPILOT_API_KEY, updates API-proxy validation + config redaction + status logging.
src/docker-manager.ts Adds COPILOT_API_KEY to one-shot-token list; sets placeholders; forwards real key to sidecar and conditionally to agent.
src/docker-manager.test.ts Adds unit tests for forwarding/isolation behavior of COPILOT_API_KEY.
src/cli.test.ts Updates validation warning expectations to include COPILOT_API_KEY.
containers/api-proxy/server.js Introduces COPILOT_AUTH_TOKEN (`COPILOT_GITHUB_TOKEN
containers/agent/api-proxy-health-check.sh Ensures COPILOT_API_KEY is a placeholder in the agent when API-proxy is active.
examples/github-copilot.sh Updates example commentary to focus on COPILOT_API_KEY usage with the sidecar.
docs/api-proxy-sidecar.md Documents COPILOT_API_KEY as a sidecar-held secret and placeholder behavior in the agent.
docs-site/src/content/docs/reference/cli-reference.md Adds COPILOT_API_KEY to the CLI environment variable reference.

Copilot's findings

Tip

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

  • Files reviewed: 10/10 changed files
  • Comments generated: 3

Comment thread src/docker-manager.ts Outdated
// it gets a placeholder value set earlier (line ~362) for credential isolation
if (process.env.COPILOT_GITHUB_TOKEN && !config.enableApiProxy) environment.COPILOT_GITHUB_TOKEN = process.env.COPILOT_GITHUB_TOKEN;
// COPILOT_API_KEY (BYOK) — forward when api-proxy is NOT enabled; when api-proxy IS enabled,
// it is excluded from agent env (held securely in api-proxy sidecar)
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

The comment says COPILOT_API_KEY is “excluded from agent env” when api-proxy is enabled, but the implementation sets a placeholder value in the agent environment for credential isolation. Please reword to clarify that the real key is not forwarded and a placeholder may still be present.

Suggested change
// it is excluded from agent env (held securely in api-proxy sidecar)
// the real key is not forwarded to the agent env and a placeholder may still be present
// for credential isolation while the real key is held securely in the api-proxy sidecar

Copilot uses AI. Check for mistakes.
Comment thread examples/github-copilot.sh Outdated
Comment on lines +39 to +41
# Run Copilot CLI with API proxy enabled
# Use sudo -E to preserve environment variables (COPILOT_GITHUB_TOKEN, GITHUB_TOKEN, AWF_ONE_SHOT_TOKEN_DEBUG)
# Use sudo -E to preserve environment variables (COPILOT_API_KEY, GITHUB_TOKEN, AWF_ONE_SHOT_TOKEN_DEBUG)
# The api-proxy sidecar holds the real COPILOT_API_KEY and injects it into requests.
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

This example script currently hard-requires COPILOT_API_KEY; however, the PR description/documentation states COPILOT_GITHUB_TOKEN and COPILOT_API_KEY are interchangeable. Consider updating the example to accept either credential (and mention/preserve both in the sudo -E comment) so it matches the supported behavior.

Copilot uses AI. Check for mistakes.
Comment thread containers/api-proxy/server.js Outdated
Comment on lines +62 to +67
const OPENAI_API_KEY = (process.env.OPENAI_API_KEY || '').trim() || undefined;
const ANTHROPIC_API_KEY = (process.env.ANTHROPIC_API_KEY || '').trim() || undefined;
const COPILOT_GITHUB_TOKEN = (process.env.COPILOT_GITHUB_TOKEN || '').trim() || undefined;
const COPILOT_API_KEY = (process.env.COPILOT_API_KEY || '').trim() || undefined;
// BYOK: use COPILOT_GITHUB_TOKEN (GitHub OAuth) or COPILOT_API_KEY (direct key), GitHub token takes precedence
const COPILOT_AUTH_TOKEN = COPILOT_GITHUB_TOKEN || COPILOT_API_KEY;
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

COPILOT_API_KEY / COPILOT_AUTH_TOKEN support was added here, but there are no unit tests covering the new env var path or the precedence rule (COPILOT_GITHUB_TOKEN should win when both are set). Since containers/api-proxy/server.js already has a test suite, please add/extend tests to validate these cases.

Suggested change
const OPENAI_API_KEY = (process.env.OPENAI_API_KEY || '').trim() || undefined;
const ANTHROPIC_API_KEY = (process.env.ANTHROPIC_API_KEY || '').trim() || undefined;
const COPILOT_GITHUB_TOKEN = (process.env.COPILOT_GITHUB_TOKEN || '').trim() || undefined;
const COPILOT_API_KEY = (process.env.COPILOT_API_KEY || '').trim() || undefined;
// BYOK: use COPILOT_GITHUB_TOKEN (GitHub OAuth) or COPILOT_API_KEY (direct key), GitHub token takes precedence
const COPILOT_AUTH_TOKEN = COPILOT_GITHUB_TOKEN || COPILOT_API_KEY;
function resolveCopilotAuthToken(env = process.env) {
const githubToken = (env.COPILOT_GITHUB_TOKEN || '').trim() || undefined;
const apiKey = (env.COPILOT_API_KEY || '').trim() || undefined;
// BYOK: use COPILOT_GITHUB_TOKEN (GitHub OAuth) or COPILOT_API_KEY (direct key),
// with GitHub token taking precedence when both are set.
return githubToken || apiKey;
}
const OPENAI_API_KEY = (process.env.OPENAI_API_KEY || '').trim() || undefined;
const ANTHROPIC_API_KEY = (process.env.ANTHROPIC_API_KEY || '').trim() || undefined;
const COPILOT_GITHUB_TOKEN = (process.env.COPILOT_GITHUB_TOKEN || '').trim() || undefined;
const COPILOT_API_KEY = (process.env.COPILOT_API_KEY || '').trim() || undefined;
const COPILOT_AUTH_TOKEN = resolveCopilotAuthToken(process.env);

Copilot uses AI. Check for mistakes.
- Reword docker-manager comment to clarify placeholder behavior
  when api-proxy is enabled
- Update github-copilot example to accept either COPILOT_GITHUB_TOKEN
  or COPILOT_API_KEY instead of hard-requiring COPILOT_API_KEY
- Extract resolveCopilotAuthToken() as a testable function with
  JSDoc and export it from server.js
- Add 8 unit tests covering precedence, fallback, empty/whitespace
  handling, and trimming behavior

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit a2cb887

@github-actions
Copy link
Copy Markdown
Contributor

Smoke test results:

✅ GitHub MCP: feat: add containers.txt to release assets / [WIP] Fix code for comments in review thread #1917
✅ Playwright: GitHub page title contains "GitHub"
✅ File write: /tmp/gh-aw/agent/smoke-test-claude-24290215008.txt created
✅ Bash verify: file content confirmed

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

🔥 Smoke Test Results — PASS

Test Result
GitHub MCP (list merged PRs) ✅ PR #1916: "feat: add containers.txt to release assets for immutable image references"
GitHub.com connectivity (HTTP 200)
File write/read smoke-test-copilot-24290215001.txt confirmed

PR: feat: add Copilot BYOK support via COPILOT_API_KEY
Author: @app/copilot-swe-agent | Assignees: @lpcox @Copilot

Overall: ✅ PASS

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke test results:

  • Merged PR titles: "fix: exclude Actions artifact token from agent container environment"; "feat: add containers.txt to release assets for immutable image references" ✅
  • safeinputs-gh PR query (required tool) ❌
  • Playwright github.com title contains "GitHub" ✅
  • Tavily search "GitHub Agentic Workflows Firewall" (required tool) ❌
  • File write/read /tmp/gh-aw/agent/smoke-test-codex-24290214994.txt
  • Bash verification via cat
  • Discussion query + mystical discussion comment (required tool path) ❌
  • npm ci && npm run build
    Overall status: FAIL

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.14.1 v20.20.2
Go go1.22.12 go1.22.12

Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environment.

Tested by Smoke Chroot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: GitHub Actions Services Connectivity ✅

Check Result
Redis PING (host.docker.internal:6379) PONG
pg_isready (host.docker.internal:5432) ✅ accepting connections
psql SELECT 1 (db: smoketest, user: postgres) ✅ returned 1

All checks passed.

🔌 Service connectivity validated by Smoke Services

@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 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx All passed ✅ PASS
Node.js execa All passed ✅ PASS
Node.js p-limit All passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #1918 · ● 803.9K ·

@github-actions github-actions Bot mentioned this pull request Apr 11, 2026
@lpcox lpcox merged commit 2aac716 into main Apr 11, 2026
55 of 57 checks passed
@lpcox lpcox deleted the copilot/add-support-for-byok-env-var branch April 11, 2026 20:12
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.

Copilot BYOK

3 participants