Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8c2f58d
feat: sign relayed remote MCP names and hold their headers daemon-side
tbiyss Sep 26, 2026
f79af57
feat: relay header-bearing remote MCPs over the daemon socket
tbiyss Sep 26, 2026
6792e64
feat: give containerized Claude runs relayed remote MCPs, not tokens
tbiyss Sep 26, 2026
806bf96
feat: relay Codex's remote MCPs in containers; bundle holds only the …
tbiyss Sep 26, 2026
294b58c
feat: SSH sessions get relayed remote MCPs and a capability-only Code…
tbiyss Sep 26, 2026
63d069b
chore: bump the image spec to 1.6.0 for the remote-mcp bridge contract
tbiyss Sep 26, 2026
e8ed11b
feat(egress): add placeholders, grant rules and the response scrubber
tbiyss Sep 26, 2026
f73c6bd
feat(egress): add the destination policy with pinned, SSRF-checked ad…
tbiyss Sep 26, 2026
1a9f8cb
feat(egress): issue X.509 certificates and keep a per-deployment egre…
tbiyss Sep 26, 2026
9ee7c37
docs: record the remote MCP relay in features, test plan and operations
tbiyss Sep 26, 2026
77c403c
docs: name the remote MCP relay modules in the contributor contract
tbiyss Sep 26, 2026
7b0509a
fix: refuse an unauthorized remote-mcp hello with the fixed sentence …
tbiyss Sep 26, 2026
e44fb5a
feat(egress): add the TLS-terminating egress proxy core
tbiyss Sep 26, 2026
583ea19
merge: stack the remote MCP relay (P1) under the egress proxy branch
tbiyss Sep 26, 2026
c816747
fix: route containerized Codex Composio SDK sessions through the comp…
tbiyss Sep 26, 2026
45e70af
fix: release relay grants with their users and drop only a bad server
tbiyss Sep 26, 2026
6a26d5b
fix: harden remote-mcp hellos: early hang-up, dial cap, crafted fields
tbiyss Sep 26, 2026
e5e3ed9
fix: never forward upstream transport error text into a container
tbiyss Sep 26, 2026
25362f8
docs: record relay grant lifetimes, the dial cap and the new refusals
tbiyss Sep 26, 2026
ff61180
feat(egress): add placeholder grants, liveness and the secret rule ca…
tbiyss Sep 26, 2026
16e427d
feat: run channel containers with --network none behind the egress proxy
tbiyss Sep 26, 2026
068146f
docs: record the egress proxy, placeholders and --network none
tbiyss Sep 26, 2026
2de6a06
merge: pick up the remote MCP relay review fixes (grant release, dial…
tbiyss Sep 26, 2026
cd02b98
feat(egress): add the cg-egress-connect SSH ProxyCommand helper
tbiyss Sep 26, 2026
fcf97fe
feat(ssh): run SSH and VS Code sessions on placeholders
tbiyss Sep 26, 2026
b1ff99a
docs: record SSH and VS Code sessions on placeholders
tbiyss Sep 26, 2026
b21a985
fix(egress): pin every request to the approved host and close scrub gaps
tbiyss Sep 26, 2026
f045b11
fix(egress): pause personal secrets for other authors and restore lis…
tbiyss Sep 26, 2026
9ef838d
docs: record the egress review fixes and the remaining raw engine keys
tbiyss Sep 26, 2026
86f5abf
merge: pick up the egress review fixes under the SSH placeholder branch
tbiyss Sep 26, 2026
a801f0f
feat(codex): relay the Codex login into containers behind the egress …
tbiyss Sep 26, 2026
41e6fbc
feat(egress): withhold unruled secrets by default on new installs
tbiyss Sep 26, 2026
f27a61e
chore: retire remote-secret-bridge and the mcp-remote runtime helper
tbiyss Sep 26, 2026
a83c513
feat(static-check): refuse secret-resolver values written under artif…
tbiyss Sep 26, 2026
b41275f
docs: record the Codex login relay, strict secrets and the static check
tbiyss Sep 26, 2026
14427c1
merge: pick up the egress review fixes under the engine auth broker b…
tbiyss Sep 26, 2026
f32b0eb
fix(egress): keep ab.chatgpt.com and oaiusercontent downloads reachab…
tbiyss Sep 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 84 additions & 28 deletions AGENTS.md

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,85 @@ product overview.

## Unreleased

- **Codex's sign-in no longer sits in every channel container.** Until now each channel container
had the gateway host's real Codex login file, refresh token included, mounted read-write, so one
channel could read it and every channel shared it. Behind the egress proxy a container now gets
its own access-only sign-in: a stand-in token the proxy swaps for the real one on OpenAI's and
ChatGPT's servers, and no refresh token at all. The gateway keeps the real login fresh with a
cheap Codex turn on the host when it is two days from expiring. Keep the host signed in with
`codex login` as before. Each channel container is recreated once on its next turn. The legacy
open-network mode and an API-key Codex login still mount the real file. Rebuild the image
(`npm run build:image`, still spec 1.6.0): `cg-init` now also removes an old copied Codex login
from a channel's home.
- **Secrets without an egress rule are withheld by default on new installs.** On a fresh install
*Withhold unprotected secrets* starts on: a secret with no built-in rule and no *Used on hosts* is
not given to channel containers. Existing installs keep their current behavior; turn it on in
Settings → Container runtime. `list_secrets` now ends with a **Finding** that names every secret
without a rule and says how to protect it.
- **A check keeps secrets out of the files channel containers can read.** `npm run check:static`
now fails when code writes a token, a relay's token or a resolved run environment into a
channel's artifact folder. The unused `remote-secret-bridge` helper is removed.

- **SSH and VS Code sessions hold placeholders, not secrets.** A developer's SSH session into a
channel container now gets the same `cgph_…` placeholders a turn gets, and Claude's login in the
session (and the editor's token file) is the channel's login placeholder. Nothing a session
writes holds a real protected value. Tools such as `gh` and `vercel` work as before through the
gateway's egress proxy. The proxy settings reach every SSH shell, VS Code terminal and your own
`agent-browser`. The editor token file is now also removed when the channel's last session ends.
- **Your personal secrets pause while someone else is attached.** While another person has an SSH
session open in a channel, your personal secrets stop working there. Everyone else's stop working
while you are attached. The agent's credential note says they are paused rather than failing
with an unexplained 403.
- **Outbound SSH from a session goes through the egress proxy.** The image ships
`/opt/channelgate/bin/cg-egress-connect`, an SSH `ProxyCommand` through the egress proxy. A
session's `GIT_SSH_COMMAND` already uses it (github.com only, with *Allow network* on). For your
own `ssh`, add `-o ProxyCommand='/opt/channelgate/bin/cg-egress-connect %h %p'`. The proxy
cannot supply an SSH key. `ssh -L` forwards to hosts outside the container no longer work;
forwards to the container's own ports and `-R` are unchanged. Rebuild the image
(`npm run build:image`, still spec 1.6.0) to get the helper.

- **Channel containers now reach the internet only through the gateway's egress proxy.** Every
channel container runs with no network of its own. A small forwarder inside it hands each
connection to the gateway, which enforces the channel's *Allow network* switch on every request
(off: only the AI engines and the channel's selected connectors; on: public hosts, never private,
loopback or cloud-metadata addresses) and logs every refused or blocked destination. The switch
is no longer advisory, and `/mode`, `/status` and the run record say so. A flip applies to the
next request without recreating anything.
- **Secrets become placeholders the container cannot use elsewhere.** A GitHub, Vercel, Supabase,
Make or Composio token, and any secret an admin marks with **Used on hosts**, reaches the
container as a `cgph_…` placeholder. The gateway swaps in the real value only on that secret's
hosts and only while the channel has work running; a personal secret only while its owner is the
one working, and never while another person's turn, background job or SSH session is active
there. The relayed Claude
login is a placeholder too. Rotation takes effect on the next request; removing a secret kills
its placeholder. Secrets without a rule are still injected as before and are marked
**unprotected** in `list_secrets`, the admin UI and the agent's own credential note. The new
*Withhold unprotected secrets* setting keeps them out of containers entirely.
- **New container settings.** Settings → Container runtime gains *Legacy open network (no egress
proxy)* — off by default; on restores the old open bridge network and raw secrets — and
*Withhold unprotected secrets*. The admin API accepts `rawNetwork` (a channel that needs raw
sockets beside the proxy) and `egressRawHosts` (hosts whose SSH/Postgres ports are tunnelled).
If the proxy cannot start, container runs stop with the reason instead of running unprotected.
After a restart, containers that kept running get their network back immediately. Avoid
multi-tenant host suffixes such as `*.vercel.app` in *Used on hosts*. A Qwen provider key and a
daemon `CODEX_API_KEY` are still given to containers as real values, and a self-hosted Qwen
endpoint on a private address cannot be reached in proxy mode.
TLS clients in the container trust the gateway's own CA through the usual CA variables; a tool
that reads none of them needs `/run/channelgate/egress-ca.pem`. After updating, run
`npm run build:image` (image spec 1.6.0 now also ships the forwarder; the updater does this for
you).
- **Fix: Codex in Composio SDK mode works in containers.** A Codex run in a channel container with
Enterprise SDK-mode Composio started its Composio connection without the run's grant, so the
gateway refused it and Codex had no Composio tools. It now connects like the other relayed
servers.
- **Composio and toolbox tokens no longer enter a channel container.** In a container, the
`composio-user`, `composio-agent`, MakeItFuture toolbox and Make toolbox connections are now
reached through the gateway itself: the engine holds only its signed run grant, and the daemon
dials the service with the real token and relays the tools. Before, the token sat in a file in
the channel's run folder that any process in the container could read. This applies to Claude
and Codex turns and to SSH sessions. Direct-host `/sudo` threads are unchanged. A rotated token
still restarts the warm Claude process. After updating, run `npm run build:image` (image spec
1.6.0; the updater does this for you).
- **Agents can now explain how to set up a channel's VPN.** The chat operating manual has a
channel VPN page. It covers who may turn the VPN on or off, read its status or query the
database. It also has the host-operator runbook for another channel, with the exact
Expand Down
Loading
Loading