DEV Community

Patrick Robinson
Patrick Robinson

Posted on

Project Gleipnir

Gleipnir: confining AI coding agents on a home Linux workstation

A home-lab writeup by Patrick Robinson. Industrial electrician and automation tech moving into OT/ICS network security; CompTIA Network+ verified badge, Security+ in progress.

What I built

I 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.

The goals were simple to state and took real work to meet:

  1. Each agent is protected from the other.
  2. I'm protected from either agent misbehaving.
  3. All three of us still share one knowledge base (my study notes), because that's the whole point.

How it works (the layers)

  • Separate identities. Each agent runs as its own Linux user, never as me.
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.

How I work

  • 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.
  • 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.
  • 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.
  • Verified installs. Software comes from signed packages or is verified against published signatures and checksums before it runs.

Three things I learned

  1. Test the door, not the sign. A setting that says "deny" isn't a control until you've watched the system actually refuse.
  2. 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.
  3. 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.

What's next

The 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.

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.

Top comments (1)

Collapse
 
autenai profile image
Auten •

"Test the door, not the sign" is the right rule, and it suggests one more door worth attacking: the desktop session.

Hiding other users' homes takes away ~/.Xauthority, but X11 also listens on an abstract Unix socket (@/tmp/.X11-unix/X0). Abstract sockets live in the network namespace, not the filesystem, so ProtectHome/read-only paths don't touch them and nftables doesn't see them. If the session ever ran xhost +SI:localuser:<agent> (some setup guides suggest it for GUI tools), the agent user can connect, and X11 has no isolation between clients: it can read every window and every keystroke, including your password manager. Same family: the D-Bus session bus and an ssh-agent socket if their paths leak through.

A quick test in your style: as the agent user, run xdotool getactivewindow getwindowname and ss -xl | grep X11. You want to watch the first one get refused. PrivateNetwork=yes (or a separate network namespace per agent, with only the proxy reachable) closes the abstract socket for good.