Isolering i lager
Isolation in layers
I förra inlägget beskrev jag en sandlåda för AI-agenter i tre idéer: isolera, filtrera, injicera. Det här är den första fördjupningen — om vad ”en egen isolerad miljö” faktiskt betyder, och varför den byggs i lager snarare än som en enda hög mur.
The previous post described an AI-agent sandbox as three ideas: isolate, allowlist, inject. This is the first deep dive — into what “an isolated environment of its own” actually means, and why it's built in layers rather than as one tall wall.
Ingen spärr får bära allt ensam
No single control carries it all
Grundregeln är lånad från klassisk säkerhetsdesign: räkna med att varje enskild spärr kan fallera, och se till att det inte räcker. För att komma åt en fil på värddatorn, eller nå ut på nätet på egna villkor, måste kod inne i lådan ta sig förbi vartenda lager — inte bara ett. Det gör också felbedömningar billigare: en lucka i ett lager är ett fynd att åtgärda, inte en katastrof.
The ground rule is borrowed from classic security design: assume any single control can fail, and make sure failing one isn't enough. To touch a file on the host, or reach the network on its own terms, code inside the box has to get past every layer — not just one. That also makes mistakes cheaper: a gap in one layer is a finding to fix, not a catastrophe.
Lagren, inifrån och ut
The layers, inside out
Innerst bor agenten som en helt vanlig, opriviligerad process. Runt den:
At the centre, the agent runs as a perfectly ordinary, unprivileged process. Around it:
En egen värld. Namnrymder ger containern egna processer, egna monteringspunkter och ett eget nätverk. Värddatorns processer och diskar syns helt enkelt inte inifrån — de finns inte i agentens värld.
A world of its own. Namespaces give the container its own processes, its own mounts and its own network. The host's processes and disks simply aren't visible from inside — they don't exist in the agent's world.
Tak på resurserna. Gränser för minne, processorkraft och antal processer gör att en skenande byggprocess eller en fork-bomb stannar i lådan i stället för att sänka datorn den kör på.
Caps on resources. Limits on memory, CPU and process count mean a runaway build or a fork bomb stays inside the box instead of taking down the machine it runs on.
Ett stängt privilegiestaket. Containern startar med alla särskilda rättigheter bortplockade och kan aldrig skaffa nya under körning. Farliga systemanrop filtreras bort innan de når kärnan.
A closed privilege fence. The container starts with every special capability dropped and can never acquire new ones at runtime. Dangerous system calls are filtered out before they reach the kernel.
Ett filsystem med ett enda skrivbart fönster. Rotfilsystemet är skrivskyddat; det enda agenten kan skriva till är projektmappen som monterats in och en temporär yta som töms när lådan slängs. Den temporära ytan är dessutom markerad så att inget som hamnar där går att köra — nedladdad kod kan sparas, men inte startas därifrån.
A filesystem with a single writable window. The root filesystem is read-only; all the agent can write to is the mounted project directory and a temporary area that's wiped when the box is discarded. That temporary area is also flagged non-executable — downloaded code can be saved there, but never launched from there.
Varje lager får anta att de andra redan har fallit.
Every layer gets to assume the others have already failed.
Hur tjock ska väggen vara?
How thick should the wall be?
Allt ovanför är detsamma oavsett hur stark själva kärngränsen är — och där finns tre nivåer att välja på. En vanlig container delar kärna med värddatorn: snabbast och enklast. gVisor lägger en medlande minikärna emellan som fångar systemanropen. En mikro-VM ger till sist agenten en helt egen kärna. Mitt råd är att börja med en vanlig container men bygga så att bytet är en enda rad konfiguration — då blir uppgraderingen ett policybeslut, inte en ombyggnad. Ska agenten jobba mot kod man inte litar på är gVisor rätt läge att växla upp till.
Everything above stays identical regardless of how strong the kernel boundary itself is — and there are three tiers to choose from. A plain container shares the host's kernel: fastest and simplest. gVisor inserts a mediating mini-kernel that intercepts system calls. A microVM finally gives the agent a kernel of its own. My advice is to start with a plain container but build so the swap is a single line of configuration — then upgrading is a policy decision, not a rebuild. If the agent is going to work on code you don't trust, gVisor is the tier to step up to.
Slit och släng är en säkerhetsfunktion
Disposability is a security feature
Det sista lagret är inget tekniskt, utan ett förhållningssätt: miljön är en engångsartikel. När uppgiften är klar rivs containern, den temporära ytan töms och det enda som överlever är projektmappen — där allt arbete ändå ska hamna som granskningsbara ändringar. Har agenten ställt till något på vägen försvinner det med lådan. Att kunna slänga miljön utan att tveka är i sig ett skydd: ingen städning, inga kvarglömda bakdörrar, ingen ackumulerad röra.
The final layer isn't technical at all — it's a stance: the environment is disposable. When the task is done the container is torn down, the temporary area is wiped, and the only thing that survives is the project directory — where all the work should end up anyway, as reviewable changes. Whatever mess was made along the way goes with the box. Being able to throw the environment away without hesitation is itself a control: no cleanup, no forgotten backdoors, no accumulated residue.
Nästa del
Next up
I del 2 tittar jag på nätverket — ett nät utan väg ut, en proxy med kort tillåtelselista och varför även DNS behöver en egen spärr.
In part 2 I look at the network — a network with no way out, a proxy with a short allowlist, and why DNS needs a control of its own.