Secure GitHub Copilot CLI
The GitHub Copilot CLI is a coding agent like Codex or Claude Code, but it has three traits that need a dedicated profile rather than the generic codex one:
- It keeps a local SQLite session store under
~/.copilot/*.db, which needsunlink/renamefor journal cleanup. The generic seccomp baseline deniesfilesystem.delete, so SQLite would fail withdisk I/O error. - It talks to real GitHub hosts (
github.com,api.github.com) that you usually do not want to MITM, alongside the Copilot API hosts. - Because it reaches non-intercepted hosts, the sandbox CA store must contain the system roots in addition to firma-ca — otherwise the agent hits
UnknownIssueron the real GitHub TLS.
The built-in copilot profile handles all three automatically. You opt in with firma run --profile copilot (or firma run -- copilot, which auto-selects it).
What the copilot profile does
Section titled “What the copilot profile does”| Concern | Generic profile | Copilot profile |
|---|---|---|
filesystem.delete | denied | permitted (SQLite session store) |
| GitHub hosts | intercepted / denied | added to https_mitm.bypass_hosts (real upstream TLS) |
| Sandbox CA trust store | firma-ca only (Sole) | system roots + firma-ca (AppendSystemRoots) |
| Auth | none | passes through GITHUB_TOKEN, GH_TOKEN, GH_COPILOT_TOKEN |
The seccomp baseline and CA-append behavior come from the built-in profile, so you do not configure them by hand. firma config --profile copilot writes the matching mapping and the https_mitm.bypass_hosts entries.
Step 1: Scaffold the config
Section titled “Step 1: Scaffold the config”firma config --profile copilot --posture devThis selects the copilot mapping (CONNECT classification for the Copilot and GitHub hosts) and seeds https_mitm.bypass_hosts with github.com, api.github.com, and uploads.github.com so those hosts pass through untouched while firma-ca still covers any intercepted host.
The generated firma.toml keeps MITM enabled (the bypass list alone keeps [sidecar.interceptor.https_mitm].enabled = true) and lists mappings/copilot.toml under rules_paths.
Step 2: Run Copilot
Section titled “Step 2: Run Copilot”GITHUB_TOKEN=ghp_... \firma run --config .firma/firma.toml --profile copilot -- copilotfirma run -- copilot auto-selects the profile from the command name, so --profile copilot is optional when you invoke the standalone copilot binary. The token is passed through to the sandboxed agent; the SQLite session store lives on the per-session runtime home and is not persisted to the host.
Sharp edges
Section titled “Sharp edges”gh copilotvscopilot. Auto-selection keys off the first command word. The standalonecopilotbinary is detected; thegh copilotextension is not (the command word isgh). Forgh copilot, pass--profile copilotexplicitly.- bwrap only. The profile is validated on Linux
bwrap. macOSvzand Windows/WSL2wsl2are proxy-only compatibility backends and are not validated for Copilot. - CA append is opt-in. Only the copilot profile sets
AppendSystemRoots; every other profile keeps theSolefirma-ca trust store unchanged.
What’s next
Section titled “What’s next”- Wrap an agent with firma run — the full runtime wrapper reference.
- Secure a local coding agent — the same model for Claude Code and Codex.
- Enable HTTPS MITM — how interception and bypass interact.