← Tillbaka till bloggen ← Back to the blog
Agentisk AI · Sandlådan, del 3
Agentic AI · The sandbox, part 3

Vem håller i nycklarna?

Who holds the keys?

Sista delen i serien om sandlådan för AI-agenter handlar om nycklarna. En agent som ska leverera på riktigt måste kunna pusha kod och öppna pull requests — och då krävs autentisering. Frågan är inte om det behövs en nyckel, utan vem som ska hålla i den.

The final part of the AI-agent sandbox series is about the keys. An agent that's going to deliver for real has to push code and open pull requests — and that takes authentication. The question isn't whether a key is needed, but who gets to hold it.

Problemet med en token i miljön

The problem with a token in the environment

Det enkla upplägget är att lägga en access-token i agentens miljövariabler. Det fungerar — och det är också problemet. Allt som kör i lådan kan läsa den, och en promptinjektion kan missbruka den fullt ut inom dess behörigheter. Miljövariabler har dessutom en tendens att hamna i loggar och felrapporter. Första försvarslinjen är därför snålhet: en token med minsta möjliga behörighet, som injiceras enbart i de sessioner som faktiskt ska pusha — inte i containerns grundmiljö där varenda process ser den.

The simple setup is to put an access token in the agent's environment variables. It works — and that's also the problem. Anything running in the box can read it, and a prompt injection can abuse it to the full extent of its scope. Environment variables also have a habit of ending up in logs and error reports. The first line of defence is therefore stinginess: a token with the narrowest possible scope, injected only into the sessions that actually push — not into the container's base environment where every process sees it.

Idealet: agenten har inga nycklar alls

The ideal: the agent holds no keys at all

Det riktiga svaret är att lyfta ut nyckeln ur agenten helt och hållet. Låt agentens git-fjärr peka på en liten proxy i sandlådan; proxyn håller alla tokens och lägger på rätt Authorization-huvud mot rätt tjänst — en GitHub-token mot GitHubs API, en Azure DevOps-PAT mot Azure DevOps. Reglerna bor i en vanlig JSON-fil, så en ny tjänst är en konfigurationsändring snarare än ny kod. Och eftersom agenten aldrig ser nyckeln spelar dess livslängd ingen roll — SSO-tokens som roterar varje timme fungerar lika bra som långlivade personliga tokens.

The real answer is to lift the key out of the agent entirely. Point the agent's git remote at a small proxy inside the sandbox; the proxy holds every token and adds the right Authorization header for the right service — a GitHub token for the GitHub API, an Azure DevOps PAT for Azure DevOps. The rules live in plain JSON, so adding a service is configuration rather than code. And since the agent never sees the key, its lifetime stops mattering — SSO tokens that rotate hourly work just as well as long-lived personal access tokens.

En agent kan inte läcka det den aldrig har fått.
An agent can't leak what it was never given.

Störst utdelning när agenterna blir fler

The payoff grows with the fleet

Mönstret betalar sig på riktigt först när man kör flera sandlådor parallellt, en per uppgift. Då kan varje låda hållas helt nyckellös, medan proxyn mappar varje uppgift till den smalaste behörighet som duger — och en uppgift som bara ska läsa och undersöka får ingen nyckel alls. Ett förgiftat repo i en låda kan inte läcka en annan uppgifts push-rättigheter, för där injektionen landar finns inget att stjäla.

The pattern really pays for itself once you run several sandboxes in parallel, one per task. Each box can then be kept entirely keyless, while the proxy maps each task to the narrowest scope that will do — and a task that only reads and investigates gets no key at all. A poisoned repo in one box can't leak another task's push rights, because where the injection lands, there is nothing to steal.

Sista spärren är en människa

The final gate is a human

Oavsett vem som håller nyckeln gäller en regel utan undantag: agenten öppnar pull requests men slår aldrig ihop dem. Och grindvakten ska vara teknisk, inte bara en instruktion — grenskydd som kräver mänsklig granskning, eller där det inte finns, ett ännu striktare upplägg: agenten jobbar som ett maskinkonto utan skrivrättigheter i det riktiga repot och pushar till sin egen fork. En sak till, vid själva granskningen: agentens egen beskrivning av ändringarna — PR-texten, commit-meddelandena — är skriven av samma process som kan ha blivit lurad. Granska diffen, inte sammanfattningen.

Whoever holds the key, one rule has no exceptions: the agent opens pull requests but never merges them. And the gate should be technical, not just an instruction — branch protection that requires human review, or where that's unavailable, an even stricter arrangement: the agent works as a machine account with zero write access to the real repository, pushing to a fork of its own. One more thing, at review time: the agent's own description of its changes — the PR text, the commit messages — was written by the same process that may have been fooled. Review the diff, not the summary.

Serien i sin helhet

The series in full

Det här avslutar serien: introduktionen, del 1 om isolering, del 2 om nätverket och den här delen om nycklarna. Isolera, filtrera, injicera — och låt sista ordet vara mänskligt.

That wraps the series: the introduction, part 1 on isolation, part 2 on the network, and this part on the keys. Isolate, allowlist, inject — and keep the last word human.