Ajoin koodausagenttiani repossa. Tehtävä oli yksinkertainen: selvittää, miten voisimme ottaa joukon Bash-ohjattua operatiivista logiikkaa ja paketoida sen enemmän Kubernetes-natiivilla tavalla. Tylsää työtä – juuri sellaista, jonka voi antaa agentin hoidettavaksi. Käynnistin sen siis ja jäin seuraamaan tilannetta, tarkistaen edistymisen silloin tällöin.
Steffen Petersen
CNCF Kubestronaut | Senior DevOps Consultant
Steffen is an experienced consultant in the Cloud Native/AI space. A true jack of most trades, master of some, being Eficode's first Kubestronaut and pushing the frontier of agentic engineering practices. If you're looking for sharp and strong opinions, he is the guy you go to.
Sitten huomasin, että kubectl-komentoja suoritettiin. Tuotantoklusteria vastaan. Mitään ei oikeasti mennyt pieleen. Silti tuntui siltä kuin olisi mennyt, koska agenttini olisi voinut itsenäisesti vuotaa klusterin salaisuuksia ulos. Sillä oli pääsy niihin.
Asia on niin, että se oli tavallaan oma syyni. Agentti ei toiminut virheellisesti. Se ei lähtenyt omille teilleen. Se yritti kerätä mahdollisimman paljon kontekstia käsillä olevasta tehtävästä. Se tarkasteli oikeaa klusteria ymmärtääkseen, minkä kanssa se työskenteli. Täysin järkevää. Ongelma oli siinä, että olin jättänyt avaimet pöydälle, ja uteliaan taaperon tavoin sillä oli kädet, joilla tarttua niihin.
Kun käynnistät tekoälypohjaisen koodausagentin terminaalistasi, se perii koko ympäristösi: SSH-avaimesi, pilvitunnuksesi, kubeconfigisi ja kaikki levyllä olevat projektihakemistot. Ei siksi, että olisit tehnyt tämän päätöksen, vaan siksi, että prosessi toimii käyttäjätunnuksellasi. Käyttöjärjestelmä ei erota sinua käyttäjätunnuksellasi toimivasta prosessista. Sillä ei ole käsitettä siitä, että "tämä prosessi on agentti, ja sitä pitäisi käsitellä eri tavalla". Sama käyttäjä, sama luottamus.
Tämä ei ole haavoittuvuus. Se ei ole agentin virhe. Näin vain käy, kun jätät asioita sellaisen ulottuville, joka ei tiedä, ettei niihin pitäisi koskea. Taapero ei tiedä eroa lelun ja passisi välillä. Se tarttuu siihen, mikä on saatavilla.
Eksplisiittinen ennen implisiittistä
Luottamus ei synny järjestelmäsuunnittelussa oletuksena. Se on päätös. Päätät, mitkä järjestelmät voivat kommunikoida keskenään. Päätät, mitä dataa liikkuu minnekin. Päätät, millaisia rajoja on olemassa ja miksi. Nämä päätökset ovat konfiguraatioissa, käytännöissä ja auditointilokeissa – paikoissa, joissa voit lukea, tarkistaa ja muuttaa niitä.
Agentin käyttöoikeusmallin pitäisi toimia samalla tavalla. Ei näin: "agentti perii pääsyn kaikkeen, minkä se voi tavoittaa, ja toivomme, ettei mitään mene pieleen." Vaan näin: "Olemme päättäneet eksplisiittisesti ja kirjallisesti, mihin agentti saa päästä käsiksi, ja kaikki muu on suunnittelun vuoksi saavuttamattomissa."
Tämä on vähimpien oikeuksien periaate, joka on ollut tietoturvan perusta jo vuosikymmeniä. Se on myös eksplisiittisen ennen implisiittistä -periaatteen soveltamista agenttipohjaisten järjestelmien luottamukseen: oletuksena ei ole pääsyä mihinkään. Pääsy myönnetään eksplisiittisellä, kirjallisella ja tarkistettavalla päätöksellä. Agentin maailma määritellään paperilla ennen sen käynnistämistä.
Juuri tämä eksplisiittisyys tuottaa suurimman osan arvosta. Ei siksi, että se estää päättäväiset hyökkääjät – vaikka estääkin – vaan koska se pakottaa kysymään olennaisen kysymyksen: mitä tämä agentti oikeasti tarvitsee? Ei sitä, mitä se voisi haluta, vaan mitä se tarvitsee. Kun vastaat tähän ja näet eron verrattuna perusasetuksiin, saat selville, mitä oma järjestelmäsi todella tekee.
Rajojen tekeminen todellisiksi
Linuxissa lukko, joka todella pitää, on Landlock LSM, ytimen tietoturvamoduuli, jonka avulla tavalliset prosessit voivat asettaa itselleen peruuttamattomia käyttöoikeusrajoituksia. Root-oikeuksia ei tarvita. Ei daemonia. Ydin valvoo sääntöjä ennen kuin prosessi edes käynnistyy, eikä niitä voi soveltamisen jälkeen laajentaa tai poistaa. Jokainen aliprosessi perii samat rajoitukset aina ketjun loppuun asti. Niitä ei voi ohittaa kehotteilla.
nono-kaltaiset työkalut käyttävät Landlockia tämän eksplisiittisen päätöksen toimeenpanoon. Agentti kommunikoi verkon kautta vain välityspalvelimen kautta, jota valvoja hallitsee. Se pääsee vain niihin tiedostojärjestelmän polkuihin, jotka käytäntö sille eksplisiittisesti sallii. Valvoja kirjoittaa auditointijäljen – mitä agentti teki, mitä se yritti tavoittaa ja mikä estettiin. Agentti ei voi muokata omaa lokiaan. Se ei voi jättää kubectl-kutsua pois. Se ei voi siivota jälkiään.
Hiekkalaatikko tekee eksplisiittisen käytännön rikkomisesta mahdotonta. Agentti ei voi vahingossa tavoitella jotain, mitä et ole päättänyt antaa sille. Vielä hyödyllisempää on, että kun se yrittää, saat siitä signaalin. Raja ei ole vain turvaverkko. Se on havainto.
Saatavilla olevasta päättäminen
Eksplisiittinen päätös edellyttää, että tiedät aidosti, mitä agenttisi tarvitsee.
nono learn (tai vastaava työkalu) jäljittää todelliset käyttömallit: luetut polut, kirjoitetut polut ja kontaktoidut isännät. Tuloksena on JSON-katkelma, jonka voit muuttaa suoraan käytännöksi. Et arvaa, mitä agentti saattaisi tehdä. Seuraat sitä ja kirjaat ylös, mitä näet.
nono profile diff default my-agent
Tämä diff näyttää käyttöoikeusmallin ensimmäistä kertaa selkeästi. Kaikki, mitä agentti tarvitsee, lueteltuna ennen kuin annat sille avaimet. Ei koko talon avaimia, vaan tietyn avaimen niihin tiettyihin huoneisiin, joihin pääsyä todella tarvitaan.
Käytäntöasiakirjasta tulee eksplisiittinen dokumentaatio: tämä agentti, tämä tehtävä, nämä käyttöoikeusrajat. Voit lukea ja tarkistaa sen sekä antaa sen jonkun muun luettavaksi. Se säilytetään paikassa, jossa voit tarkastella muutoksia, versioida ja auditoida sitä.
Kun agentti tarvitsee perustellusti pääsyn johonkin oletuksena estettyyn kohteeseen, myönnät pääsyn eksplisiittisesti:
Molemmat kentät ovat suunnittelun vuoksi pakollisia. Eston poistaminen ilman eksplisiittistä myöntöä johtaa käytäntöön, joka näyttää tiukalta mutta ei ole sitä. Kaksivaiheisuus on turvaominaisuus. Jokainen poikkeus tehdään tietoisesti, kirjataan ylös ja näkyy diffissä.
Mitä näin
kubectl-tapauksen jälkeen aloin ajaa sessioita hiekkalaatikon suojassa. Sama agentti, samat repositoriot, eri tehtävät. Erona oli se, että pystyin nyt näkemään, mitä rajalla tapahtui.
Estettyjen yritysten määrä yllätti minut. Ei kubectl-komennot tuotantoa vastaan – se on aika ilmeistä. Vaan hiljaisemmat tapaukset: Bash-komennot ja lukukutsut törmäsivät estoihin työn aikana, joka näytti ulkopuolelta täysin rutiininomaiselta. Riippuvuuksien selvitys kosketteli polkuja, joiden lähellä sillä ei ollut mitään syytä olla. Tiedostoskannaukset ajautuivat kohti tunnistetietotiedostoja. Ei mitään dramaattista. Ei mitään, mikä olisi näkynyt tulosteessa tai vaikuttanut epätavalliselta toiminnalta. Vain tasainen taustalla oleva ulottuminen, joka oli aina ollut olemassa jokaisessa sessiossa – näkymättömänä, koska mikään ei ollut koskaan ollut tiellä.
Kyse ei ollut siitä, että agentti olisi tehnyt jotain väärin. Useimmiten se ei tehnyt. En vain ollut tiennyt, mihin tavallinen sessio todella yritti päästä käsiksi, koska minulla ei ollut koskaan ollut mitään, mikä olisi näyttänyt sen. Sandbox ei muuttanut agentin toimintaa. Se vain teki altistuksen näkyväksi ensimmäistä kertaa.
Hiljaisista riskeistä kannattaa huolestua. Lukuoperaatio kohteeseen ~/.aws/credentials näennäisen tiedostoskannauksen aikana. Riippuvuuksien ratkaisuvaihe, joka koskee kubeconfigiasi. Bash-komento, joka tarkistaa ympäristömuuttujan. Mikään näistä ei näy agentin tulosteessa. Mikään niistä ei tunnu tietoturvapoikkeamalta. Mutta ne ovat mahdollisia kohteita tietojen ulossiirrolle myöhempien prompt injection -hyökkäysten kautta, kun ne ovat agentin konteksti-ikkunassa.
Raja on signaali. Kyse ei ole siitä, että ”jotain vaarallista tapahtui”, vaan siitä, että ”jokin yritti päästä pidemmälle kuin käytäntö salli”. Ilman rajaa et saa tätä signaalia. Saat vain prosessin, joka teki kaiken, mihin sillä oli pääsy, ilman tietoa siitä, missä se kävi.
Määritä, mihin avaimiin saa päästä käsiksi
kubectl-tapaus oli ilmeinen, koska satuin seuraamaan sitä. Useimmiten kyse ei ole mistään ilmeisestä. Kyse on tavallisilta vaikuttavista komennoista, jotka lukevat hiljaa asioita, joita niiden ei olisi tarvinnut lukea, sessioissa, joita et seurannut tarkasti. Taustalla on jatkuva pääsy, josta ei koskaan tehty päätöstä. Se on vain aina kuulunut siihen, mitä käyttäjätunnuksellasi ajaminen tarkoittaa.
Mutta sen ei tarvitse jatkua näin. Periaate on selkeä: eksplisiittinen ennen implisiittistä. Agentin käyttöoikeuksien pitää olla tietoinen päätös, dokumentoitu, rajalla valvottu ja lokitiedoista auditoitavissa.
Kun seuraavan kerran ajat tekoälyagentin terminaalistasi, tee päätös selkeästi. Päätä, mitä se todella tarvitsee. Kirjaa se ylös. Valvo sitä sandboxilla. Seuraa sitten, mitä estetään. Sandbox ei muuta sitä, mitä agentti yrittää tehdä. Sen avulla näet ensimmäistä kertaa, mikä on aina ollut ulottuvillasi – ja saat ensimmäistä kertaa todellisen mahdollisuuden päättää, mitkä avaimet jätät tiskille.
Avaimet ovat sinun. Myös päätöksen niiden myöntämisestä pitäisi olla sinun.
- AI
- Security
Subscribe to our newsletter
Related blogs