Sandboxing Agents at the API Layer Instead of the OS Layer
proxy policy pattern maps to scoped API access for system-bus pi sessions — per-function credential boundaries without OS-level sandboxing
The Astro team built flue as a sandbox agent framework that wraps OpenCode sessions — connecting full coding agents to CI workflows with a structured permission model. It’s experimental and still moving fast, but the core architectural patterns are worth stealing regardless of whether the project reaches v1.
The standout piece is the proxy policy system. Instead of trying to lock down an agent at the OS or container level, you define proxies with explicit allow/deny rules keyed on HTTP method, path, body content, and rate limits. anthropic() gets full access. github({ policy: 'read-only' }) constrains the agent to non-mutating operations only. The agent calls real APIs through the proxy, and the proxy enforces the boundary. No network namespace gymnastics, no seccomp profiles — just a typed policy object sitting between the agent and the outside world.
Typed result extraction with Valibot schemas is the other pattern worth pulling. flue.skill() returns results validated against a schema with retry logic baked in — you define the shape you expect and the framework runs the retry/validation loop before your workflow code ever sees the output. FlueEvent normalizes telemetry across what would otherwise be scattered async agent output into a unified event stream. These two things together — typed outputs with retry + normalized telemetry — solve the “what did the agent actually do” problem that makes agentic CI workflows painful to debug.
The joelclaw mapping is direct. The proxy policy pattern is exactly the missing piece for constraining pi sessions running as workers in the system-bus — scoped API access per function rather than ambient credentials for everything. ADR-0144 already pushes toward interface-bounded dependencies; this adds a runtime enforcement layer on top of the compile-time interface boundary. The FlueEvent telemetry normalization mirrors the OTEL emission pattern in @joelclaw/telemetry. The Cloudflare Workers + Containers runtime adapter is also interesting as an eventual escape hatch away from self-hosted k8s for certain workloads.
Key Ideas
- Proxy policies over OS sandboxing — method + path + body + rate limit rules in a typed policy object, no container magic required
- Per-proxy credential scoping —
github({ policy: 'read-only' })vsanthropic()gives different trust levels to different external APIs in the same workflow - Valibot schema validation with retry —
flue.skill()extracts typed results from LLM output and retries on schema mismatch, separating “did the agent do the thing” from “did I get the output I expected” FlueEventtelemetry normalization — unified event stream across shell output, LLM responses, and workflow state transitions; maps to OTEL emission in@joelclaw/telemetryflue.skill()as named capability invocation — structured prompt dispatch with typed args and return; similar to thestep.invokepattern in Inngest but with schema validation baked in- Cloudflare Workers + Containers adapter — positions flue for distributed execution on Cloudflare’s infrastructure when Colima/k8s isn’t the right host
- Built by Astro team — signals this will get production-grade attention; OpenCode integration means it benefits from the same AI coding session improvements that terminal-adjacent tooling is getting
Links
- flue repo
- OpenCode — the AI coding agent flue wraps
- OpenCode repo (sst/opencode)
- Valibot — schema validation library used for typed result extraction
- Cloudflare Workers + Containers — runtime adapter target
- Astro — the web framework team building flue
- flue GitHub Actions deploy guide
- flue Cloudflare deploy guide
- joelclaw ADR-0144 — Gateway hexagonal architecture