Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a0ea649
Add comprehensive gVisor firewall comparison workflow
lpcox Jun 18, 2026
d97caca
Address PR review feedback
lpcox Jun 18, 2026
0454937
Fix gVisor workflow: Add proper health checks for Squid and Envoy
lpcox Jun 18, 2026
44877bf
Fix Squid config: Remove duplicate domain entries
lpcox Jun 18, 2026
0103439
Fix health checks: Use simple TCP port check instead of full proxy test
lpcox Jun 18, 2026
a836557
Add comprehensive security tests to gVisor workflow
lpcox Jun 18, 2026
4eeab32
Fix health checks: Use netcat instead of /dev/tcp
lpcox Jun 18, 2026
caffabd
Fix HTTP status code handling in blocked domain tests
lpcox Jun 18, 2026
d9dbec4
ci: add adversarial egress-enforcement equivalence experiment
lpcox Jun 19, 2026
0dffeba
ci: run adversarial egress experiment on its feature branch
lpcox Jun 19, 2026
f6b3087
ci: fix baseline exec-bit, A6 dig scoring, L3 proxy-DNS check
lpcox Jun 20, 2026
082f530
ci: make A7/A8 DNAT-honest to avoid false 'stricter' claims
lpcox Jun 20, 2026
2f37e5f
Merge main into fix/gvisor-workflow-healthchecks
Copilot Jun 20, 2026
5f801f1
feat: add --network-isolation topology egress mode (no iptables/sudo)
lpcox Jun 20, 2026
aedc29d
Merge remote-tracking branch 'origin/main' into fix/gvisor-workflow-h…
Copilot Jun 20, 2026
141b0f1
docs: add network-isolation topology + mcpg reachability design note
lpcox Jun 22, 2026
31834d9
docs: ARC supported only with DinD; fail-stop otherwise
lpcox Jun 22, 2026
bd9cb74
Merge origin/main into fix/gvisor-workflow-healthchecks
Copilot Jun 22, 2026
024f85c
test(adversarial): cover dual-homed mcpg gateway + DIFC topology
lpcox Jun 22, 2026
e8fa63c
fix(adversarial): serve sidecar marker from mounted file via cat
lpcox Jun 23, 2026
38d0037
feat: add topology-attach + fail-stop preflight to network-isolation
lpcox Jun 23, 2026
bf95af7
test: cover topology-attach branches to fix coverage gate
lpcox Jun 23, 2026
9866901
feat: add network.isolation + topologyAttach to config schema and spec
lpcox Jun 23, 2026
4e5d4a0
ci: exclude flaky opentelemetry.io specs link from lychee check
lpcox Jun 23, 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
3 changes: 3 additions & 0 deletions .github/lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ exclude = [
"^https://docs\\.github\\.com/en/github/site-policy/github-bug-bounty",
"^https://www\\.sei\\.cmu\\.edu/",
"^https://platform\\.openai\\.com/docs/api-reference/authentication$",
# opentelemetry.io intermittently drops connections from CI runners
# (returns 200 interactively but "error sending request" in Actions)
"^https://opentelemetry\\.io/docs/specs/otel/",
# LOGGING.md is referenced but doesn't exist yet (planned doc)
"LOGGING\\.md",
]
Expand Down
777 changes: 777 additions & 0 deletions .github/workflows/test-egress-enforcement-adversarial.yml

Large diffs are not rendered by default.

381 changes: 344 additions & 37 deletions .github/workflows/test-gvisor-firewall-comparison.yml

Large diffs are not rendered by default.

41 changes: 24 additions & 17 deletions containers/agent/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,24 +136,31 @@ wait_for_iptables() {
# The awf-iptables-init container shares our network namespace and runs
# setup-iptables.sh, then writes a ready signal file. This ensures the agent
# container NEVER needs NET_ADMIN capability.
echo "[entrypoint] Waiting for iptables initialization from init container..."
INIT_TIMEOUT=300 # 300 * 0.1s = 30 seconds
INIT_ELAPSED=0
while [ ! -f /tmp/awf-init/ready ]; do
if [ "$INIT_ELAPSED" -ge "$INIT_TIMEOUT" ]; then
echo "[entrypoint][ERROR] Timed out waiting for iptables init container after 30s"
if [ -f /tmp/awf-init/output.log ]; then
echo "[entrypoint] Init container output:"
cat /tmp/awf-init/output.log
else
echo "[entrypoint] No init container output log found"
#
# In network-isolation (topology) mode there is no iptables-init container —
# egress is enforced by Docker network topology — so skip the handshake.
if [ "${AWF_NETWORK_ISOLATION:-}" = "1" ]; then
echo "[entrypoint] Network-isolation mode: skipping iptables init container wait"
else
echo "[entrypoint] Waiting for iptables initialization from init container..."
INIT_TIMEOUT=300 # 300 * 0.1s = 30 seconds
INIT_ELAPSED=0
while [ ! -f /tmp/awf-init/ready ]; do
if [ "$INIT_ELAPSED" -ge "$INIT_TIMEOUT" ]; then
echo "[entrypoint][ERROR] Timed out waiting for iptables init container after 30s"
if [ -f /tmp/awf-init/output.log ]; then
echo "[entrypoint] Init container output:"
cat /tmp/awf-init/output.log
else
echo "[entrypoint] No init container output log found"
fi
exit 1
fi
exit 1
fi
sleep 0.1
INIT_ELAPSED=$((INIT_ELAPSED + 1))
done
echo "[entrypoint] iptables initialization complete"
sleep 0.1
INIT_ELAPSED=$((INIT_ELAPSED + 1))
done
echo "[entrypoint] iptables initialization complete"
fi
}

check_service_health() {
Expand Down
2 changes: 2 additions & 0 deletions docs/awf-config-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ AWF settings MAY be supplied via config files, including stdin (`--config -`).
- `network.blockDomains[]` → `--block-domains <csv>`
- `network.dnsServers[]` → `--dns-servers <csv>`
- `network.upstreamProxy` → `--upstream-proxy`
- `network.isolation` → `--network-isolation` *(experimental; enforces egress via Docker network topology instead of host iptables)*
- `network.topologyAttach[]` → `--topology-attach <name>` *(repeatable; requires `network.isolation: true`)*
- `apiProxy.enabled` → `--enable-api-proxy`
- `apiProxy.enableTokenSteering` → `--enable-token-steering`
- `apiProxy.anthropicAutoCache` → `--anthropic-auto-cache`
Expand Down
32 changes: 31 additions & 1 deletion docs/awf-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,38 @@
"upstreamProxy": {
"type": "string",
"description": "Upstream HTTP proxy URL (e.g. \"http://proxy.corp.example.com:8080\"). When set, the AWF Squid proxy forwards traffic through this proxy."
},
"isolation": {
"type": "boolean",
"description": "Experimental: enforce egress via Docker network topology (an internal network with no internet route plus a dual-homed Squid proxy) instead of host iptables. Requires no sudo/NET_ADMIN, so it works inside ARC/Kubernetes DinD runners. Not yet supported together with dnsOverHttps or enableHostAccess. Maps to the --network-isolation CLI flag."
},
"topologyAttach": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names of externally-launched trusted containers (e.g. an MCP gateway or DIFC proxy) to attach to the internal topology network so the agent can reach them without granting them their own egress path. Requires network.isolation to be true. Maps to repeated --topology-attach CLI flags."
}
}
},
"allOf": [
{
"if": {
"required": [
"topologyAttach"
]
},
"then": {
"required": [
"isolation"
],
"properties": {
"isolation": {
"const": true
}
}
}
}
]
},
"apiProxy": {
"type": "object",
Expand Down
Loading
Loading