Ugrás a fő tartalomra
OpenAI

Biztonságos, hatékony sandbox építése a Codex Windowsos működéséhez

Szerző: David Wiesen, a műszaki csapat tagja

Betöltés…

Amikor 2025 szeptemberében csatlakoztam a Codex mérnöki csapatához, a Codex for Windows még nem rendelkezett sandbox-megvalósítással, ami azt jelentette, hogy a Windows-felhasználóknak két rossz lehetőség közül kellett választaniuk az OpenAI kódoló ügynökeinek használatakor:

  1. Szinte minden parancs jóváhagyása (még az olvasási műveleteké is), amelyet egy kódoló ügynök futtatni akart, ami nem hatékony és bosszantó. A Codex használatának egyik fő előnye, hogy nem kell minden unalmas munkát saját magadnak elvégezned.
  2. A Full Access mód engedélyezése: lehetővé teszi, hogy a Codex minden parancsot jóváhagyás vagy korlátozás nélkül futtasson, ami csökkenti a súrlódást, de a felügyelet rovására.

Codex kódoló ügynökünk a fejlesztői laptopokon fut – akár a CLI-n, az IDE-bővítményen vagy az asztali alkalmazáson keresztül. Ez kezeli a billentyűzetnél ülő ember és egy felhőben futó, inferenciát végző modell közötti párbeszédet.

A Codex alapértelmezés szerint valódi felhasználói jogosultságokkal fut, ami azt jelenti, hogy mindent megtehet, amit a felhasználó is. Ez erőteljes, de potenciálisan veszélyes. A kódoló modell utasíthatja a környezetet, hogy helyben futtasson parancsokat – a tesztek futtatásától egy fájl olvasásán vagy szerkesztésén át egy Git-ág létrehozásáig –, ezért a Codex alapértelmezett módja az eredményesség és a biztonság közötti megfelelő egyensúly megtalálására törekszik. Ez az alapértelmezett mód lehetővé teszi, hogy a Codex szinte bárhol olvasson fájlokat, és a munkaterületeden belül írjon fájlokat (vagyis abban a könyvtárban, ahol a Codexet futtatod), internet-hozzáférés nélkül, hacsak külön nem kéred azt. Ahhoz, hogy a fájlírás és a hálózatelérés ilyen automatikus, biztonságos korlátozása megvalósuljon, a Codexnek olyan sandbox környezetre van szüksége, amely ezeket a korlátokat valóban kikényszeríti.

A sandbox korlátozott végrehajtási környezet. Amikor egy fejlesztő a Codex használja, a számítógép operációs rendszere csökkentett jogosultságokkal indít el egy parancsot, és ezek a korlátok továbbterjednek a folyamatfán. Minden Codex-parancs kezdettől fogva elkülönített környezetben fut, és minden leszármazott folyamat ugyanazon az elkülönítési határon belül marad.

Ábra a Codex sandbox operációsrendszer-szintű izolációs határairól.

A Codexnek a számítógép operációs rendszere által kikényszerített izolációs funkciókra van szüksége egy hatékony sandbox megvalósításához. Egyes operációs rendszerek ehhez jó segédeszközöket kínálnak (például a Seatbeltet MacOS-en, illetve a seccompot vagy a bubblewrapot Linuxon); a Windows azonban jelenleg nem biztosít ilyen képességet alapból.

Ahhoz, hogy a Codex Windowson is ugyanolyan biztonságosan és élvezetesen használható legyen, mint máshol, saját sandboxot kellett megvalósítanunk.

Ahol a meglévő Windows-eszközök kevésnek bizonyultak

A Windows kínál bizonyos izolációs eszközöket és primitíveket. Bár egyik sem felelt meg teljesen a követelményeinknek, számos lehetséges megoldást megvizsgáltunk — nevezetesen az AppContainert, a Windows Sandboxot és a Mandatory Integrity Control címkézést.

AppContainer

  • Mi ez: Az AppContainer a Windows natív sandboxa, egy képességalapú izolációs modell, amely olyan alkalmazásokhoz készült, amelyek előre pontosan tudják, mihez kell hozzáférniük.
  • Miért: Vonzó, mert valódi operációsrendszer-határt kínál, nem pedig csak „best effort” korlátozásokat.
  • Miért nem: A Codex nem egyetlen szűken körülhatárolt alkalmazás. Nyílt végű fejlesztői munkafolyamatokat hajt meg: shell-eket, Gitet, Pythont, csomagkezelőket, buildeszközöket és bármilyen más binárist, amelyről az ügynök úgy dönt, hogy szüksége van rá. A gyakorlatban emiatt az AppContainer nem illett megfelelően a problémához. Ez erős izolációt jelentett, de a munkaterhelések sokkal szűkebb körére vonatkozott, mint az, hogy „engedjük, hogy egy ügynök fejlesztőként működjön”.

Windows Sandbox

  • Mi ez: A Windows Sandbox a Microsoft eldobható, könnyű virtuális gépe. Friss Windows asztali környezetet kapsz erős izolációs határral, és bármit is teszel benne, az eltűnik a munkamenet végén.
  • Miért: Nyilvánvaló okokból érdekes volt — sokkal kompatibilisebb tetszőleges szoftverrel, mint az AppContainer, és biztonsági szempontból is sokkal erősebb megoldás.
  • Miért nem: A Codexnek közvetlenül a felhasználó tényleges checkoutján, eszközein és környezetében kell működnie, nem egy külön, eldobható asztali környezetben, amely külön beállítást és host/guest áthidalást igényelne. Emellett volt vele egy alapvető termékprobléma is: a Windows Sandbox még csak nem is érhető el a Windows Home SKU-kon.

Mandatory Integrity Control (MIC) integritási címkézés

  • Mi ez: A Windows rendelkezik egy „integritási szinteknek” nevezett fogalommal, például alacsony, közepes és magas szinttel, amelyek meghatározzák, hogy a rendszer mennyire bízik meg az objektumokban és folyamatokban. Az alapszabály az, hogy egy alacsonyabb integritású folyamat nem tud írni egy magasabb integritási szintű objektumba, még akkor sem, ha a normál ACL egyébként engedélyezné. Például egy alacsony integritási szintű folyamat kevésbé megbízhatónak minősül, ezért a Windows megakadályozza, hogy normál, közepes integritási szintű objektumokba írjon, kivéve ha ezeket az objektumokat kifejezetten úgy címkézik át, hogy ezt engedélyezzék számára.
  • Miért: A MIC papíron elegánsnak tűnt – futtassuk a Codexet alacsony integritással, címkézzük át az írható gyökérhelyeket alacsony integritásúra, és hagyjuk, hogy a Windows máshol minden írást megakadályozzon. Ez adott volna nekünk egy rendszergazdai jogosultságot nem igénylő megoldást, valódi operációsrendszer-szintű mechanizmussal a háttérben.
  • Miért nem: Az ACL-ekhez hasonlóan az integritási címkék is módosítják a gazdagép tényleges fájlrendszerét, és ebben az esetben a szemantikai változás különösen széles körű. Egy munkaterület alacsony integritásúként való megjelölése nem csupán azt jelenti, hogy „A Codex írhat ide.” Ez azt jelenti, hogy az alacsony integritású folyamatok általánosságban írhatnak oda. Egy valódi fejlesztői gépen ez a felhasználó tényleges munkapéldányát a gazdagép alacsony integritású nyelőpontjává teszi, ami sokkal kockázatosabb, mint gondosan célzott ACL-eket adni egyetlen sandbox-kialakításhoz. Még ha a közepes integritású fejlesztői eszközök továbbra is működnek is, a munkaterület mögöttes bizalmi modellje olyan módon változott meg, amely nehezen korlátozható, és még nehezebben indokolható.

Miután az összes lehetőséget zsákutcának értékeltük, elkezdtük megtervezni saját megoldásunkat, hogy jó Codex-élményt hozzunk a Windows-felhasználóknak.

Az első prototípus: a „nem emelt jogosultságú sandbox”

Az első működő prototípusunk Windows-fogalmak és -eszközök kombinációját használta a szükséges elkülönítés megvalósításához. Kezdettől fogva az volt az egyik cél, hogy ez jogosultságszint-emelés igénylése nélkül működjön, vagyis a Codexnek ne kelljen rendszergazdai jogosultságokat kérnie a felhasználótól pusztán a sandbox beállításához vagy futtatásához. Ez azt jelentette, hogy ki kellett találni, hogyan lehet ésszerű korlátokat szabni két dolognak: a fájlírási műveleteknek és a hálózati hozzáférésnek.

A fájlírás korlátozása

Ha egyáltalán nem korlátoztuk volna a fájlírást, biztonsági problémánk lett volna. Ha viszont túlzottan korlátoztuk volna, a sandbox rontotta volna a felhasználói produktivitást, mert folyamatos jóváhagyást kellett volna kérnie. A probléma megoldásához két fontos Windows-építőelemre támaszkodtunk: a SID-ekre és az íráskorlátozott tokenekre.

A SID-ekkel identitást adhattunk a sandboxnak

A SID, vagyis a biztonsági azonosító, az az identitás, amelyet a Windows a jogosultságokhoz társít. Minden felhasználónak van SID-je, a csoportoknak is vannak SID-jeik, és még egyetlen bejelentkezési munkamenet is saját SID-t kap. Például egy aktuális bejelentkezett munkamenet SID-je ilyen lehet: S-1-5-5-X-Y. A helyi rendszergazdák csoportjához rendelt SID a következő lehet: S-1-5-32-544.

A Windows azt is lehetővé teszi, hogy szintetikus SID-eket hozz létre, amelyek nem felelnek meg valódi felhasználónak, de mégis szerepelhetnek ACL-ekben (hozzáférés-vezérlési listákban), amelyek meghatározzák, ki olvashat/írhat/futtathat adott fájlokat vagy könyvtárakat. Ez hasznos primitívvé teszi a SID-eket a sandboxunk számára: létrehozhatunk kizárólag a Codex sandbox által használt SID-eket anélkül, hogy bármi mást zavarnánk a gépen.

Az íráskorlátozott tokenek korlátozzák, hol módosíthat a Codex fájlokat

A folyamat token olyan biztonsági objektumok a Windowsban, amelyek meghatározzák egy futó folyamat identitását és jogosultságait. Meghatározzák, hogy egy folyamat milyen műveleteket hajthat végre. Az íráskorlátozott token a folyamattokenek egy olyan típusa, amelynek hatására a Windows további hozzáférés-ellenőrzést hajt végre az írási műveleteknél.

Ahhoz, hogy egy írás sikeres legyen, két ellenőrzésnek kell megfelelnie:

  1. A normál felhasználói identitásnak (a token „tulajdonosának”) engedélyezettnek kell lennie erre
  2. A token korlátozott SID-listájában szereplő SID-ek közül legalább egynek szintén hozzáférést kell kapnia
„A sandboxba íráshoz normál felhasználói hozzáférés és sandbox-write SID-hozzáférés is szükséges” című ábra.

A gyakorlatban ezek az ellenőrzések lehetővé tették számunkra, hogy ACL-ekkel pontosan meghatározzuk, hol módosíthat a sandbox a fájlrendszerben, ami az írási műveletekhez szükséges részletességet biztosította.

A SID-ekkel és az íráskorlátozott tokenekkel a nem emelt jogosultságú sandboxunk így működött:

  1. A sandbox beállítása létrehozott egy sandbox-write nevű szintetikus SID-et.
  2. A(z) sandbox-write SID írási, végrehajtási és törlési hozzáférést kapott a következőhöz
    1. Az aktuális munkakönyvtár
    2. A config.toml fájlban konfigurált további writable_roots bejegyzések bármelyike.
  3. A sandbox beállítása kifejezetten megtagadta ugyanennek a SID-nek az írási hozzáférést az olyan „írható területen belül csak olvasható” helyekhez, mint például:
    1. <cwd>/.git
    2. <cwd>/.codex
    3. <cwd>/.agents
  4. A Codex olyan íráskorlátozott token alatt indított parancsokat, amelynek korlátozott SID-listája tartalmazta az Everyone csoportot, az aktuális bejelentkezett munkamenet SID-jét és a sandbox-write szintetikus SID-et.

Ez a folyamat gyakorlatilag megoldotta a fájlírás korlátozását, és ígéretesnek tűnt. Ezután a sandbox hálózati hozzáférésének korlátozására volt szükségünk.

A hálózati hozzáférés korlátozása

A hálózati hozzáférés korlátozása a sandbox fontos része; enélkül rosszindulatú kód adatokat szivárogtathatna ki a gépről az internetre. Mivel el akartuk kerülni a jogosultságemelést, korlátozottak voltak a lehetőségeink a hálózati forgalom erős blokkolására. Azok az eszközök, amelyeket használni szerettünk volna, például a Windows Firewall, általában nem telepíthetők adminisztrátori jogosultság nélkül.

Mivel a Windows tűzfal nem volt választható lehetőség, korlátoztuk, hogy mit tudunk szabályozni. Arra törekedtünk, hogy a gyermekkörnyezet a fejlesztők által ténylegesen használt hálózati eszközök esetében hiba esetén zárt, tiltó állapotú legyen, hogy a Git-parancsok, csomagtelepítők stb. meghiúsuljanak a sandboxban, és a felhasználónak jóvá kelljen hagynia minden internet felé irányuló műveletet. Az ötlet az volt, hogy használhatatlanná tegyék a nyilvánvaló menekülőutakat: a proxyt figyelembe vevő forgalmat egy halott végpontra irányítsák, a Git HTTP(S)-átvitelét ugyanerre kényszerítsék, a Git SSH-n keresztüli használatát pedig azonnal hibára futtassák. Ezenfelül egy kis denybin könyvtárat illesztettünk a PATH elejére, és átrendeztük a PATHEXT értékét, hogy a csonk SSH- és SCP-szkriptek a valódi binárisok előtt legyenek feloldva.

Például az alábbi konkrét környezeti felülírásokat használtuk a hálózati hozzáférés korlátozására:

  • HTTPS_PROXY=http://127.0.0.1:9
  • ALL_PROXY=http://127.0.0.1:9
  • GIT_HTTPS_PROXY=http://127.0.0.1:9
  • NO_PROXY=helyi gazdagép,127.0.0.1,::1
  • GIT_SSH_COMMAND=cmd /c exit 1
Ábra az emelt jogosultságú sandbox architektúrájáról tűzfalszabályokkal és dedikált Windows-felhasználóval.

Ez sok szokásos, eszközök által generált forgalmat megfogott, de továbbra is csak tanácsadó jellegű volt. Egy folyamat figyelmen kívül hagyhatta a környezetet, megkerülhette a PATH-ot, vagy egyszerűen közvetlenül nyithatott socketeket – ez túl kockázatos volt.

A nem emelt jogosultságú megközelítés kompromisszumokkal járt

Mint minden érdekes szoftverimplementáció esetében, az első prototípusnak is voltak előnyei és hátrányai. Bár néhány szabványos Windows-képességgel is működött, nagyon kifejezett és finoman szabályozható fájlrendszer-írásokat tett lehetővé, és nem emelt jogosultsággal futott – így a felhasználóknak nem kellett túlzott számú jogosultságemelési kérést elfogadniuk vagy adminisztrátornak lenniük a helyi gépükön –, voltak valódi hátrányai, amelyek közül néhány kizárta, hogy ez legyen a végleges tervünk:

  • A beállítás sebessége: a munkaterület ACL-jeinek alkalmazása drága lehet a munkaterület-könyvtár topológiájától függően.
  • Lábnyom: valódi ACL-eket alkalmaztunk a fejlesztő rendszerén, bár ez a lábnyom nem különösebben invazív, mert az összes alkalmazott ACL egy egyedileg létrehozott szintetikus SID-re vonatkozik, amelyet csak a sandbox használ.
  • Nehezen módosítható szemantika: Az ACL-ekre való támaszkodás a fájlalapú korlátozások esetében azt jelenti, hogy a sandbox szemantikájának módosítása költséges és összetett. Míg macOS-en dinamikusan módosíthatjuk, hogyan generáljuk a .sbpl -t a Seatbelt konfigurálásához használt fájl esetében a Windows sandbox lassú és erőforrás-igényes műveletet igényelhet az ACL-ek módosításához.
  • A hálózatvédelem gyenge. Ahogy korábban említettem, ez „tanácsadó jellegű” volt, bizonyos programok biztosan megkerülték volna, ha saját hálózati veremet valósítottak meg, és nem is arra tervezték, hogy ellenséges kóddal szemben helytálljon.

Az első három probléma velejárója egy olyan egyedi sandbox-megvalósításnak, amely elég rugalmas az ügynökalapú folyamatokhoz. A hálózati korlátozás története azonban más volt.

A hálózati korlátozás túl fontos

Amellett, hogy egy rosszindulatú ügynök könnyen megkerülhette a környezetalapú hálózati korlátozást, sok jó szándékú kód/bináris is megkerülte volna egyszerűen akkor, ha nem vette figyelembe a proxykörnyezeti változókat, vagy saját socketalapú hálózati kódot valósított meg. Úgy éreztük, hogy ez önmagában is elegendő ok arra, hogy jobb sandboxmódba fektessünk.

A jobb hálózati korlátozás érdekében a Windows Firewallt akartuk használni, amely lehetővé teszi a kimenő hálózati forgalom blokkolását felhasználók vagy programok számára. Sajnos azonban néhány okból nem tudtunk hatékonyan olyan működő tűzfalszabályt létrehozni, amely kizárólag a Codex harness által indított parancsokra vonatkozott:

  • A Windows nem teszi lehetővé, hogy egy tűzfalszabály egy korlátozott token nem elsődleges identitásához legyen egyeztetve. Ez azt jelenti, hogy nem tudtunk tűzfalszabályt alkalmazni „bármely olyan tokenre, amelynek korlátozott SID-listájában szerepel a mi szintetikus SID-ünk”.
  • Bár létrehozhattunk volna adott binárisra illeszkedő tűzfalszabályt, ezzel csak magának a codex.exe-nek a hálózatkezelését tudtuk volna korlátozni. Ez nem vonatkozna azokra a folyamatokra, amelyeket az ügynök a felhasználó nevében indít el, például a Git- vagy Python-folyamatokra.
  • Más tűzfal-illesztési dimenziók is nem megfelelő szerkezetűek voltak. A felhasználói hatókörű szabályok az emelt jogosultság nélküli kialakításban továbbra is a valódi Windows-felhasználóra illeszkedtek, nem csupán a korlátozott gyermekfolyamatra. A programútvonal-szabályok túl durva felbontásúak voltak: általánosságban blokkolhatták a(z) codex.exe vagy a(z) python.exe fájlt, de nem ezt az egy, homokozóban futtatott python.exe-meghívást. A port- vagy címalapú szabályok szintén teljesen helytelen szabályozási irányelvnek bizonyultak. Például nem a 443-as port blokkolása volt a célunk; hanem az, hogy ennél a konkrét korlátozott folyamatfánál blokkoljuk a tetszőleges kimenő hozzáférést.

Ahhoz, hogy a tűzfalszabályt kifejezetten a sandboxolt parancsainkra alkalmazzuk, külön elsődleges identitásként kellett futtatnunk őket, nem a „valódi” felhasználóként. Ez a megközelítés új útra terelt minket, amelyben feladtuk a „nincs jogosultságemelés” korlátot.

Az újratervezés: az „emelt jogosultságú sandbox”

A sandbox következő iterációja, amely a jelenlegi implementációnk, a beállítás során emelt szintű rendszergazdai jogosultságokat igényel. Ezért „emelt jogosultságú sandboxként” hivatkozom rá. A rendszer azon határpontján, ahol a Codex parancsot indít, az emelt jogosultságú sandbox ugyanolyannak látszik, mint a nem emelt jogosultságú. Továbbra is korlátozott token alatt futtatja a gyermekfolyamatokat – hasonlóképpen egy write_restricted tokent, amelynek ugyanaz a korlátozott SID-listája van: [Everyone, Logon, Synthetic]–, azonban ennek a tokennek a biztonsági főeleme már nem a tényleges Windows-felhasználó, hanem a Codex által létrehozott két helyi felhasználó egyike:

  • CodexSandboxOffline (erre vonatkoznak a tűzfalszabályok)
  • CodexSandboxOnline (erre nem vonatkoznak a tűzfalszabályok)

Ez az elsőre aprónak tűnő részlet valójában nagy hatással van a sandboxra, arra, hogy ki tudja használni, valamint a beállítás és a futásidejű végrehajtás bonyolultságára.

Ábra a nem emelt jogosultságú sandbox hálózati környezeti felülírásairól.

Vizuálisan hasonlít a nem emelt jogosultságú prototípusra, azzal a különbséggel, hogy megjelennek a tűzfalszabályok és egy dedikált Windows-felhasználó, aki ténylegesen futtatja a parancsokat. (Ezeknek az új fogalmaknak a bevezetése azonban azt is jelenti, hogy több előkészítő munkát kell elvégezni, mielőtt a sandbox ténylegesen el tudná kezdeni a parancsok futtatását és védelmét.)

Most már elsőrangú beállítási lépésre van szükségünk

A nem emelt jogosultságú sandbox kialakításának egyszerű beállítási lépése volt, de ez viszonylag kicsi volt:

  • Szintetikus SID létrehozása, ha szükséges
  • ACL-ek alkalmazása a sandbox-write szintetikus SID-re

Az emelt jogosultságú sandboxnak azonban többet kell tennie.

  • Szintetikus SID létrehozása, ha még nem jött létre
  • Az online és offline sandboxfelhasználók létrehozása, ha még nem léteznek
  • Az újonnan létrehozott felhasználók hitelesítő adatainak helyi tárolása és titkosítása a Windows Data Protection API (DPAPI) használatával olyan helyen, amelyet a sandboxfelhasználók ténylegesen nem tudnak olvasni
  • Hozz létre tűzfalszabályokat, amelyek blokkolják a CodexSandboxOffline felhasználó összes kimenő hálózati hozzáférését, vagy ha már léteznek, ellenőrizd, hogy helyesek-e.

A beállítási szakaszban van még egy további nehezítő tényező. A Codex sandbox-környezetének várhatóan a tényleges Windows-felhasználóéval egyenértékű olvasási hozzáféréssel kell rendelkeznie. A nem emelt jogosultságú sandboxban, ahol a korlátozott token elsődleges SID-je a Windows-felhasználó volt, ez megvalósult. Ez azonban nem jár automatikusan azzal, amikor a rendszerbiztonsági tag új CodexSandbox-felhasználóvá válik. Windows rendszeren számos releváns könyvtár olvasási/végrehajtási jogosultságokat ad a „Hitelesített felhasználók” csoportnak. Jó példa erre a felhasználó profilkönyvtára. Alapértelmezés szerint a Windows-felhasználók nem olvashatják más Windows-felhasználók profilkönyvtárait, ezért számos esetben még az egyszerű fájlolvasási műveletek is sikertelenek lennének.

Ennek kezelésére egy újabb réteget adtunk a sandbox beállítási folyamatához – olyat, amely olvasási ACL-eket ad a sandbox-felhasználóknak ott, ahol ilyen ACL-ek esetleg még nem léteznek. Például néhány gyakran használt Windows-könyvtárba:

  • C:\Users\<real-user>
  • C:\Windows\
  • C:\Program Files\
  • C:\Program Files (x86)\
  • C:\ProgramData\

Mivel ez a könyvtárlista csak „best effort”, és az ACL-ek telepítése mindegyiken meglehetősen költséges lehet, ezt a logikát aszinkron módon futtatjuk, hogy a felhasználókat blokkoló sandboxbeállítási lépésnek ne kelljen megvárnia ezek befejeződését.

A telepítési logikát részben azért helyeztük külön binárisba, hogy csak szükség esetén kelljen átlépni az UAC jogosultsági határát. A mélyebb ok azonban architekturális volt: a sandbox beállításának alapvetően más a feladata, mint a codex.exe-nek. Ha a sandboxbeállítási logikát külön binárisban tartjuk, a codex.exe normál, nem emelt jogosultságú harness maradhat; a csak Windowsra vonatkozó beállítási gépezet nem duzzasztja feleslegesen a codex.exe -t más platformokon; a hosszabb ideig futó beállítási munka leválasztható a fő folyamat élettartamáról; és egyetlen helyet kapunk a sandbox különböző beállítási útvonalainak kezelésére.

Ábra az elsőrangú emelt jogosultságú sandboxbeállítási lépésről.

A parancsfuttató egy új bináris, amely ténylegesen futtatja a felhasználói parancsokat

A Windows felhasználói és tokenes bejelentkezési határainak működése miatt nem tudtuk tovább ugyanúgy létrehozni a korlátozott tokent és alatta folyamatot indítani, mint a nem emelt jogosultságú sandboxban. Ahhoz, hogy valóban másik Windows-felhasználóként indítsunk parancsokat, első ötletünk a következő folyamat volt:

  • A codex.exe a tényleges Windows-felhasználóként fut. Ezután a Codex sorrendben:
    • Meghívja a LogonUserW(...) függvényt a sandbox-felhasználóhoz.
    • Meghívja a CreateRestrictedToken(...) függvényt az adott sandbox-felhasználói tokenen.
    • A korlátozott sandbox-felhasználói tokent használva meghívja a CreateProcessAsUserW(...) függvényt a végső gyermekfolyamat elindításához.

A gyakorlatban azonban ez a tervezett folyamat nem működött, mert a CreateProcessAsUserW(...) pontján jogosultsági akadályba ütközött. Ez azt jelenti, hogy a codex.exe létre tudott hozni egy korlátozott tokent a sandbox-felhasználó számára, de nem tudott megbízhatóan elindítani egy gyermekfolyamatot ezzel a tokennel a határ valós felhasználói oldaláról. Szükségünk volt egy olyan folyamatra, amely már a sandbox-felhasználóként futott – ez lehetővé tette, hogy a korlátozási lépés és a végső folyamatindítás a határ sandbox-felhasználói oldalán történjen, ne pedig a valódi felhasználói oldalon.

Ez a követelmény vezetett a codex-command-runner.exe létrejöttéhez, egy új binárishoz, amelynek egyetlen feladata, hogy korlátozott tokent hozzon létre, és elindítsa a kért parancsot. Ahelyett, hogy a codex.exe -t kértük volna a teljes folyamat önálló végrehajtására (valódi felhasználó → sandbox-felhasználó → korlátozott token → gyermekfolyamat), két részre osztottuk a folyamatot:

1. rész

  • A codex.exe meghívja a CreateProcessWithLogonW(...) -t, hogy elindítsa a codex-command-runner.exe -t sandbox-felhasználóként, egyelőre korlátozott token használata nélkül.

2. rész

  • A runnerben az OpenProcessToken(GetCurrentProcess(), ...) megnyitja a runner saját tokenjét, amely már a sandbox-felhasználóhoz tartozik.
  • A runner meghívja a GetTokenInformation(...) -t a sandbox bejelentkezési SID kinyeréséhez, majd a CreateRestrictedToken(...) -t a végső korlátozott token felépítéséhez.
  • Továbbra is a runneren belül meghívja a CreateProcessAsUserW(...) -t ezzel a korlátozott tokennel, hogy elindítsa a valódi gyermekfolyamatot.
Ábra a korlátozott parancsok indítására szolgáló parancsfuttató folyamatáról.

A teljes kép

Albert Einstein azt mondta: „A lehető legegyszerűbben közelítsünk meg mindent, de annál semmivel sem egyszerűbben.” Ennek szellemében a tervünk megfelelően megoldotta az egyes problémákat. A végső architektúrának négy rétege van, amelyeket korábban már áttekintettünk:

  • Maga a codex.exe
  • A codex-windows-sandbox-setup.exe, amely minden emelt jogosultságot igénylő beállítási munkát kezel
  • A codex-command-runner.exe, amely korlátozott token parancsokat futtat
  • A gyermekfolyamat

Amikor először közelítettem meg ezt a projektet, nem volt erős elképzelésem arról, hová fog kifutni. A megközelítésem az volt, hogy a sandboxolási képességet a Codex és az operációs rendszer közötti határba építem be. Ez a megközelítés szorosan megfelel annak, ahogyan a Codex sandboxa MacOS-en és Linuxon meg van valósítva.

Ahogy egyre többet tanultam a Windows által biztosított konkrét eszközökről, és ahogy tucatnyi döntést hoztunk a biztonság és a könnyű használat egyensúlyozására, a rendszer a jelenlegi formájára nőtt – több binárissal, egyedi felhasználókkal, tűzfalszabályokkal, emelt jogosultságú beállítási lépéssel, aszinkron folyamatokkal és még sok mással.

Nem különösebben egyszerű rendszer, de a komplexitás minden egyes elemét szükségszerűen adtuk hozzá, hogy olyan sandboxot építsünk, amely egyszerre biztonságos és amennyire lehet, nem áll a felhasználó útjába.

Ábra a végleges Windows-sandbox architektúrájáról.

A biztonság és a valódi használhatóság egyensúlya

Miközben azon dolgoztunk, hogy jó felhasználói élményt nyújtsunk a Codex Windows-felhasználóinak, az volt a célunk, hogy olyasmit készítsünk, ami biztonságos, de nem megy a használhatóság rovására – a Codex használatának egész lényege az, hogy az ügynökök képesek legyenek munkát végezni a folyamatos figyelmed nélkül.

A projekt egyik legnagyobb tanulsága az volt, hogy a Windows nem adott a kezünkbe egyetlen olyan primitívet sem, amely tisztán leképezhető lett volna a „biztonságos autonóm kódoló ügynökre”. Több eszközt és fogalmat kombináltunk, hogy valami koherenst építsünk. Néhány korai ötlet zsákutcának bizonyult. A végső terv korábbi prototípusok hibridje lett, amelyek mind a probléma egy-egy részét oldották meg.

A másik tanulság az volt, hogy egy kódoló ügynök biztonsága más természetű, mint a klasszikusabb alkalmazásbiztonság. A Codexnek valódi fejlesztői munkafolyamatokhoz kell működnie. A mérnöki munka arról szólt, hogyan egyensúlyozzuk az ügynökalapú munkaterhelésekkel való kompatibilitást a valódi kikényszeríthetőséggel. Ez a feszültség alakította a végső terv kompromisszumait.

Kíváncsi vagy, hogyan működik a Codex sandbox élesben? Próbáld ki.