Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ release gates. Stable promotion and publication require approval of the exact te

### Beta development notes

- Clarify that the network tool's policy is advisory in `/sudo` direct-host threads, with no
OS-level egress cutoff. Ordinary proxy-mode container enforcement is unchanged.

- Ship the documentation favicon so handbook pages no longer request a missing asset.

- Revoke pending identity-link proofs for a recovered administrator, preventing an older proof
Expand Down
3 changes: 3 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3725,6 +3725,9 @@ A categorized catalog of what's shipped. Cross-linked to `TEST-PLAN.md` checks.
`run_config` event records `networkEnforced` and `egress` beside `networkPolicy` so an operator
reading it after an incident cannot mistake one for the other. `NETWORK_POLICY_ENFORCED` in
`src/engines/network-policy.js` is now `true`; every surface asks `networkEnforcedFor(target)`.
The shared `set_channel_network` tool description also explicitly distinguishes ordinary
proxy-mode enforcement from legacy bridge/raw-socket policy and `/sudo` direct-host policy,
which has no OS-level egress cutoff. This description does not change runtime enforcement.
→ TEST-PLAN: Sandbox boundaries; Egress proxy, placeholders and `--network none`.
- **Retired 2026-09-03 (Linux + containers only):** nothing replaces it — with no host sandbox there is no user namespace for AppArmor to restrict,
and rootless Podman brings its own uid mapping (`--userns=keep-id`, `/etc/subuid`). **Linux hosts keep their Bash sandbox under Ubuntu's AppArmor userns restriction**: Ubuntu 23.10+
Expand Down
12 changes: 12 additions & 0 deletions TEST-PLAN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# ChannelGate — Test Plan

## Network tool description and direct-host policy

Run `node --test test/channel-policy-audit.test.js test/network-policy.test.js
test/runtime-access-facts.test.js`. The registered `set_channel_network` description must distinguish
ordinary proxy-mode enforcement from advisory legacy bridge/raw sockets and `/sudo` direct-host
execution with no OS-level egress cutoff. Preserve public internet without a domain allowlist,
OFF access to engine endpoints and selected connectors, proxy denial of private/loopback/metadata
addresses, and no grant of host credentials or mounts. The schema regression does not exercise
or change network enforcement. Live MCP-DESCRIPTIONS-01 acceptance remains separate for Claude
and Codex: inspect the actual delivered tool description and resolved runtime facts without
changing the fixture's network setting or entering `/sudo`.

## Documentation favicon

Run `cd documentation && npm run build && npm test`. The output validator requires the
Expand Down
8 changes: 5 additions & 3 deletions src/mcp/tools/channel-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,12 @@ export function register(server, ctx) {
"set_channel_network",
{
description:
"ADMIN ONLY. Set this channel's allowed network policy. On permits internet use (any public host, " +
"ADMIN ONLY. Set this channel's allowed network policy. For ordinary proxy-mode containers, " +
"on permits internet use (any public host, " +
"no domain allowlist); off limits the channel to the engine endpoints and its selected connectors. " +
"Enforced by the gateway's egress proxy (the container has no network of its own) unless the gateway " +
"runs the legacy open-bridge egress mode or this channel was given raw sockets — then it is advisory. " +
"The gateway's egress proxy enforces this policy; the container has no network of its own. " +
"Legacy open-bridge egress or raw sockets make the policy advisory. In /sudo direct-host threads " +
"it is advisory, with no OS-level egress cutoff. " +
"Private, loopback and cloud-metadata addresses are never reachable through the proxy. It grants no " +
"host credential files or mounts. Takes effect on the next request.",
inputSchema: { enabled: z.boolean() },
Expand Down
14 changes: 14 additions & 0 deletions test/channel-policy-audit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ test("an environment-secret change stays in its own name-only audit and never du

// ── The MCP twins ─────────────────────────────────────────────────────────────────────────────

test("the network tool description distinguishes proxy enforcement from direct-host policy", () => {
const definitions = new Map();
const ctx = ctxFromClaims({ channelId: CHANNEL_ID, slug: entry.slug, authorId: ADMIN_ID, threadKey: "1700000000.000100", principalTrusted: true, engine: "claude" });
registerChannelAdmin({ registerTool: (name, definition) => definitions.set(name, definition) }, ctx);
const description = definitions.get("set_channel_network").description;
assert.match(description, /ordinary proxy-mode containers/i);
assert.match(description, /\/sudo direct-host.*advisory.*no OS-level egress cutoff/i);
assert.match(description, /legacy open-bridge.*raw sockets.*advisory/i);
assert.match(description, /any public host.*no domain allowlist/i);
assert.match(description, /off limits.*engine endpoints.*selected connectors/i);
assert.match(description, /Private, loopback and cloud-metadata.*never reachable through the proxy/);
assert.match(description, /no host credential files or mounts/);
});

test("the MCP set_channel_network handler logs the change with the Slack author", async () => {
const tools = new Map();
const ctx = ctxFromClaims({ channelId: CHANNEL_ID, slug: entry.slug, authorId: ADMIN_ID, threadKey: "1700000000.000100", principalTrusted: true, engine: "claude" });
Expand Down
Loading