{"slug": "project-gleipnir", "title": "Project Gleipnir", "summary": "Patrick Robinson, an industrial electrician and automation tech, built Gleipnir, a home-lab sandbox that confines AI coding agents like Anthropic's Claude Code and OpenAI's Codex on a Linux workstation. Each agent runs under its own Linux user with systemd sandboxing, per-agent nftables egress rules routed through a filtering proxy, and ACL-controlled access to a shared notes filesystem, with hourly Git snapshots and tested encrypted backups. Robinson reports that controls only count once an attack has been watched failing, and that stacked sandbox layers can mask whether the deepest wall was ever actually tested.", "body_md": "# \n  \n  \n  Gleipnir: confining AI coding agents on a home Linux workstation\n\n*A home-lab writeup by Patrick Robinson. Industrial electrician and automation tech moving into OT/ICS network security; CompTIA Network+ [verified badge](https://www.credly.com/badges/27c9a173-0630-4b4e-96b4-aa2d8a346cde/public_url), Security+ in progress.*\n\n## \n  \n  \n  What I built\n\nI use two AI coding agents (Anthropic's Claude Code and OpenAI's Codex) to help me study and build. Agents like these can run commands, read files, and reach the internet, so I didn't want them running as *me*. Gleipnir is the environment I built so they can be genuinely useful on my workstation while staying inside walls that I control and have tested.\n\nThe goals were simple to state and took real work to meet:\n\n1. Each agent is protected from the other.\n2. I'm protected from either agent misbehaving.\n3. All three of us still share one knowledge base (my study notes), because that's the whole point.\n\n## \n  \n  \n  How it works (the layers)\n\n- \n**Separate identities.** Each agent runs as its own Linux user, never as me.\n- \n**Sandboxed launch.** Agents start through systemd with sandboxing: read-only system directories, other users' homes hidden, and only explicitly listed paths writable. Resource limits keep a runaway process from taking the machine down.\n- \n**Controlled network egress.** Per-agent firewall rules (nftables) only let an agent talk to a local filtering proxy, and the proxy only allows that agent's AI provider. Each agent's launcher checks that this wall is in place and**refuses to start** if it isn't.\n- \n**Policy as a second layer, not the only one.** The agents' own permission settings also deny the sensitive areas, but I treat those as a sign on the door. The kernel-level controls above are the door.\n- \n**A shared knowledge base with real permissions.** My notes live on their own filesystem. Group ownership, setgid directories and default ACLs make the study area writable by everyone, while project records, paid course material and app configuration stay read-only or invisible to the agents.\n- \n**Recovery built in.** Hourly Git snapshots of the shared notes (so any deleted or mangled note can be restored), plus nightly encrypted backups with a restore I've actually tested.\n\n## \n  \n  \n  How I work\n\n- \n**Staged changes, each reviewed.** Every change is drafted, cross-checked by the other agent, and approved by me. Every privileged change is performed by me, by hand, one step at a time.\n- \n**Testing by trying to break it.** I run structured tests where each control is attacked on purpose: write where you shouldn't, read what's hidden, slip through a symlink or hardlink, reach the network directly. A control only counts once I've watched it refuse, with the exact error recorded.\n- \n**Honest records.** A findings register, daily logs, and a policy changelog with the checksum of everything installed. Results that couldn't be fully proven are labeled that way instead of being called a pass.\n- \n**Verified installs.** Software comes from signed packages or is verified against published signatures and checksums before it runs.\n\n## \n  \n  \n  Three things I learned\n\n1. \n**Test the door, not the sign.** A setting that says \"deny\" isn't a control until you've watched the system actually refuse.\n2. \n**Stacked layers hide each other.** In one round of tests, two sandbox layers stopped everything before the deepest wall was ever reached. That's good security, but it meant the tests proved the outer layers, not the inner one. I learned to record exactly*which* layer each test proves.\n3. \n**Recovery steps don't belong at the end of a runbook.** I once followed a procedure top to bottom and ran its rollback section by accident. I recovered cleanly using a restore tool I'd built for exactly that, and since then recovery steps always live in a separate file.\n\n## \n  \n  \n  What's next\n\nThe same discipline, applied to networking: a dedicated virtualization host with isolated lab segments (isolation proven with firewall drop counters, not just failed pings), then physical networking (managed switching, VLAN segmentation, a dedicated firewall, traffic capture), and finally an OT segment with PLC/HMI equipment and industrial protocols. That's where my electrical and automation background meets security.\n\n*The live configuration stays private by design because it contains operational details that don't need to be public. The architecture, controls, testing methodology, and reasoning behind them are documented here. I'm happy to walk through the implementation in detail.*", "url": "https://wpnews.pro/news/project-gleipnir", "canonical_source": "https://dev.to/probinson/project-gleipnir-3557", "published_at": "2026-10-18 01:36:23+00:00", "updated_at": "2026-10-18 01:39:48.848379+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "ai-tools"], "entities": ["Patrick Robinson", "Anthropic", "Claude Code", "OpenAI", "Codex", "Gleipnir", "Linux", "nftables"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/project-gleipnir", "markdown": "https://wpnews.pro/news/project-gleipnir.md", "text": "https://wpnews.pro/news/project-gleipnir.txt", "jsonld": "https://wpnews.pro/news/project-gleipnir.jsonld"}}