Skip to content

docs: update architecture docs with three-component overview#1340

Merged
Mossaka merged 7 commits intomainfrom
docs/update-architecture-docs
Mar 17, 2026
Merged

docs: update architecture docs with three-component overview#1340
Mossaka merged 7 commits intomainfrom
docs/update-architecture-docs

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Mar 17, 2026

Summary

  • Rewrites CLAUDE.md/AGENTS.md project overview to accurately describe the three-container architecture (Squid proxy, Agent, API Proxy sidecar)
  • Adds a Three Container Components section with static IPs, roles, and required-vs-optional status for each container
  • Fixes outdated iptables description: setup now runs in the awf-iptables-init init container (not inside the agent entrypoint)
  • Documents that squid.conf is injected via AWF_SQUID_CONFIG_B64 env var (not a file bind mount) to support Docker-in-Docker
  • Makes AGENTS.md a symlink to CLAUDE.md so all coding agents read the same, up-to-date guidance
  • Rewrites README "What it does" → "How it works" with a concise three-container summary for public-facing clarity

Test plan

  • Verify AGENTS.md symlink resolves correctly: readlink AGENTS.mdCLAUDE.md
  • Confirm README renders correctly on GitHub

🤖 Generated with Claude Code

- Rewrite CLAUDE.md/AGENTS.md project overview to accurately describe the
  three-container architecture (Squid, Agent, API Proxy sidecar)
- Add "Three Container Components" section with IPs, roles, and
  required-vs-optional status for each container
- Fix outdated iptables description: setup now runs in a separate
  awf-iptables-init init container, not inside the agent entrypoint
- Document that squid.conf is injected via AWF_SQUID_CONFIG_B64 env var
  (not a file bind mount) to support Docker-in-Docker
- Add API Proxy Sidecar as a documented third component
- Update traffic flow diagram to show full lifecycle including init
  container, optional API proxy path, and cleanup
- Make AGENTS.md a symlink to CLAUDE.md so all agents share the same docs
- Rewrite README "What it does" → "How it works" with concise three-container
  description for public-facing clarity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 17, 2026 20:41
@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 16b08e9

Copy link
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

Updates project documentation to describe the current three-container runtime architecture (Squid proxy, Agent, optional API proxy sidecar) and consolidates agent guidance by making AGENTS.md point to CLAUDE.md.

Changes:

  • Rewrite README “How it works” section to summarize the 3-container model and roles.
  • Expand CLAUDE.md architecture overview with container roles, static IPs, and updated operational details (iptables init container, Squid config injection).
  • Replace AGENTS.md content with a pointer/symlink to CLAUDE.md to keep agent guidance in one place.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.

File Description
README.md Updates top-level “How it works” explanation to a 3-container summary.
CLAUDE.md Rewrites architecture section to document the three-component design and updated implementation details.
AGENTS.md Converts to a pointer/symlink targetting CLAUDE.md for a single source of agent guidance.

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

CLAUDE.md Outdated
Comment on lines +213 to +215
- Config passed via `AWF_SQUID_CONFIG_B64` env var (base64-encoded); entrypoint decodes to `/etc/squid/squid.conf`
- **Why base64?** Docker-in-Docker: the Docker daemon cannot access host filesystem paths, so file bind mounts don't work. See memory notes on DinD issue.
- Exposes port 3128 for proxy traffic (intercept mode — no HTTP_PROXY env var needed in agent)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in subsequent commits: CLAUDE.md now describes Squid as a standard forward proxy (http_port 3128, not intercept mode), with HTTP_PROXY/HTTPS_PROXY always set in the agent environment. The iptables DNAT on ports 80/443 is described as a defense-in-depth fallback for proxy-unaware tools.

CLAUDE.md Outdated
1. `setup-iptables.sh`: Configures iptables NAT rules to redirect HTTP/HTTPS traffic to Squid (agent container only)
2. `entrypoint.sh`: Drops NET_ADMIN capability, then executes user command as non-root user
- Based on `ubuntu:22.04`; can also use GitHub Actions parity image (`act` preset)
- Mounts entire host filesystem at `/host` (read-only) + writable volume at `/host$HOME`
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: the "entire host filesystem" wording has been replaced with an accurate description of the selective bind mount model — system binaries (/usr, /bin, /sbin, /lib, /lib64, /opt, /sys, /dev) read-only; workspace and /tmp read-write; empty home volume with only whitelisted $HOME subdirs (.cache, .config, .local, .anthropic, .claude, .cargo, .rustup, .npm, .copilot); select /etc files — not /etc/shadow.

README.md Outdated
- **API Proxy Sidecar**: Optional Node.js-based proxy for secure LLM API credential management (OpenAI Codex, Anthropic Claude) that routes through Squid
`awf` runs three Docker containers for each invocation:

- **Squid proxy** — enforces domain allowlist filtering; all HTTP/HTTPS traffic is transparently redirected here via iptables DNAT
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: README now says iptables DNAT rules redirect port 80/443 traffic that bypasses proxy env vars to Squid, and the description makes clear that HTTPS_PROXY/HTTP_PROXY env vars are the primary path (with DNAT as enforcement/fallback).

README.md Outdated
# Agentic Workflow Firewall

A network firewall for agentic workflows with domain whitelisting. This tool provides L7 (HTTP/HTTPS) egress control using [Squid proxy](https://www.squid-cache.org/) and Docker containers, restricting network access to a whitelist of approved domains for AI agents and their MCP servers.
A network firewall for agentic workflows. `awf` wraps any command in a Docker-based sandbox that enforces L7 (HTTP/HTTPS) domain whitelisting via [Squid proxy](https://www.squid-cache.org/), while giving the agent transparent access to the host filesystem.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: "transparent access to the host filesystem" replaced in both the README and CLAUDE.md overview. The README now says "access to the host workspace and selected system paths via selective bind mounts", and CLAUDE.md enumerates the exact mount list.

HTTPS uses HTTPS_PROXY env var (explicit CONNECT method).
HTTP falls through to iptables DNAT since lowercase http_proxy is
intentionally not set (httpoxy mitigation on Ubuntu 22.04).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions bot mentioned this pull request Mar 17, 2026
Mossaka and others added 5 commits March 17, 2026 20:48
…TLS error

Squid is a forward proxy; HTTPS without HTTPS_PROXY hits Squid via
iptables DNAT but the TLS handshake fails (Squid expects CONNECT).
Traffic is still blocked, just with a connection error not a 403.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… host FS

The agent uses granular bind mounts (system binaries ro, workspace rw,
whitelisted HOME subdirs rw) not a blanket host filesystem mount.
Sensitive paths like /etc/shadow and non-whitelisted home dirs are excluded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Expand selective bind mounts list to include all mounted paths:
  /sbin, /lib64, /sys, /dev, /tmp, .anthropic, .rustup, group,
  nsswitch.conf, ld.so.cache, alternatives
- Fix "transparent proxy, no HTTP_PROXY env needed" — HTTP_PROXY and
  HTTPS_PROXY are always set; iptables DNAT is defense-in-depth fallback
- Fix API proxy port notation "10000–10002" → "10000, 10001, 10002, 10004"
  (discrete ports, 10003 is never bound)
- Clarify port 10001 example is Anthropic-specific, not the generic sidecar address
- Fix README "iptables rules block" → "redirect" (DNAT redirects to Squid,
  not a flat block)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…view

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Mossaka Mossaka merged commit 5ee62d3 into main Mar 17, 2026
27 of 28 checks passed
@Mossaka Mossaka deleted the docs/update-architecture-docs branch March 17, 2026 20:59
@github-actions
Copy link
Contributor

Smoke Test Results — Run 23216067932

✅ GitHub MCP — Last 2 merged PRs:

✅ Playwright — github.com title contains "GitHub"
✅ File write — /tmp/gh-aw/agent/smoke-test-copilot-23216067932.txt created
✅ Bash — file content verified

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1340

@github-actions
Copy link
Contributor

Smoke Test Results

GitHub MCP: #1340 docs: update architecture docs with three-component overview / #1066 feat(proxy): add token-based rate limiting via response parsing
Playwright: github.com title contains "GitHub"
File Write: /tmp/gh-aw/agent/smoke-test-claude-23216067915.txt created
Bash verify: File content confirmed

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1340

@github-actions

This comment has been minimized.

@github-actions
Copy link
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 #1340 ·

@github-actions
Copy link
Contributor

🔮 The ancient spirits stir; the smoke test agent has walked these halls.
PR titles: docs: update architecture docs with three-component overview; fix: skip safe dependency update PR when existing PR is open
GitHub MCP review: ✅
safeinputs-gh PR query: ❌
Playwright title check: ✅
Tavily search: ❌
File write + cat verify: ✅
Build (npm ci && npm run build): ✅
Discussion oracle comment: ❌
Overall status: FAIL

🔮 The oracle has spoken through Smoke Codex

Warning

⚠️ Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

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.

2 participants