JIT
← Notebook
Field notes AI AgentsSecuritySecrets Management

Een AI-agent veilig de sleutels geven

Onze identity-agent koppelen aan een secrets manager zonder hem het hele koninkrijk te geven — read-only by default, functiescheiding, en writes die je echt moet menen.

We draaien een kleine vloot AI-agents in de homelab — systemen, netwerk, security, identity. Elk is een dunne schil rond een set skills, waarbij een skill een tooldefinitie is plus de code die een echte backend aanroept. Deze week kreeg de identity-agent er een nieuwe bij: toegang tot Infisical, onze secrets manager.

Die zin zou elke auditor doen samenkrimpen. Een AI-agent met reikwijdte in het ene systeem waarvan de enige taak is om net de dingen te bewaren die je het hardst wil beschermen? Het interessante werk was niet de integratie. Het was de integratie iets maken waar je je handtekening écht onder zou zetten.

De noodzaak

De opdracht was makkelijk gezegd en moeilijker waargemaakt:

  • Read-only by default. De agent observeert; hij wijzigt niets tenzij een mens het zegt.
  • Least privilege. Geen admin-token, geen gedeelde “god”-credential.
  • Functiescheiding. De identiteit die secrets leest, mag niet dezelfde zijn die ze schrijft.
  • Geen lekken. Secret-waarden belanden nooit per ongeluk in een transcript, een log of een samenvatting.

Niets hiervan is nieuw. Het is exact dezelfde set controles die je van een menselijke operator zou eisen. De agent krijgt er geen korting op.

De structuur

De skill is bewust een dunne REST-client, geen vendor-SDK — de officiële trok een volledige cloud-SDK binnen die we nooit zouden gebruiken, dus hielden we de dependency en het aanvalsoppervlak klein.

De toegang is opgesplitst over twee machine-identiteiten:

IdentiteitRol in InfisicalGebruikt voor
ReadViewer (read-only)secrets, mappen en audit logs oplijsten en lezen
Writescoped write-rolcreate / update / delete, niets anders

De read-identiteit kan niets wijzigen. De write-identiteit wordt enkel ooit gebruikt voor expliciete wijzigingen, en de code valt nooit stilletjes van de ene op de andere terug. Is er geen aparte write-identiteit geconfigureerd, dan wordt elke write gewoon geweigerd.

Boven op de identiteiten zit een gelaagde guard, elke laag bewust goedkoop en saai:

  1. Kill switch — writes staan uit tot ze bewust ingeschakeld worden.
  2. Two-phase confirm — elke wijziging geeft eerst een dry-run-preview terug (“PERMANENTLY delete secret X [env=prod]”) en voert niets uit.
  3. Blast-radius-bevestiging — onomkeerbare acties vragen een tweede, expliciete goedkeuring.
  4. Audittrail — elke poging wordt gelogd, met secret-waarden geredigeerd.
  5. Reveal gate — waarden zijn standaard gemaskeerd; platte tekst tonen vraagt een aparte, expliciete opt-in.

Defence in depth betekent dat de agent dit allemaal moet passeren én server-side nog steeds geautoriseerd moet zijn. De guard zit boven op Infisicals eigen rechten, niet in de plaats ervan.

Het resultaat

Een werkende integratie die we end-to-end tegen de live instance verifieerden:

  • Reads liepen op de Viewer-identiteit; elke mutatie liep op de aparte write-identiteit — bevestigd in de logs.
  • Het volledige wijzigingspad — aanmaken, teruglezen, updaten, verwijderen, controleren dat het weg is — werkte, elke stap gated door preview en bevestiging.
  • Secret-waarden bleven de hele tijd geredigeerd, zelfs vlak nadat ze geschreven waren.
  • Een offline testsuite (een dozijn checks) bewijst dat de guards houden voor er één netwerkcall gebeurt — zo is de veiligheidslogica testbaar zonder ooit een echte secret aan te raken.

De eerlijke conclusie heeft bijzonder weinig met AI te maken. Het is een oud auditprincipe — least privilege en functiescheiding — toegepast op een nieuw soort operator. Geef automatisatie exact de toegang die ze nodig heeft, splits lezen van schrijven, maak destructieve acties bewust, en houd de bewijzen bij. Dat de operator toevallig een AI-agent is, maakt de controles niet zachter. Het maakt ze net onbespreekbaar.