Blog/Biztonság és megfelelés
Kódoló ügynökök és titkok: kulcsok a kontextuson, logokon és commitokon kívül
Hogyan szivárognak ki a titkok kódoló ügynökökön át, és mely kontrollok állítják meg: olvasási tiltás, sandbox, pre-commit, push-védelem, OIDC és kulcscsere.
Balázs Csorba··11 perc olvasás
- AI agents
- Secrets management
- Claude Code
- Pre-commit scanning
- CI security

A lényeg röviden
- Az ügynök bármit elolvashat, ami a projektmappában van, a munkakönyvtáron belüli olvasás pedig nem kér megerősítést. Tiltsd le a kontextusból kizárandó fájlokat olyan Read-szabállyal, mint a Read(.env).
- Az engedélyszabályok a fájleszközökre és a gyakori fájlparancsokra vonatkoznak, nem minden folyamatra. A sandboxot kapcsold be a shell-parancsokhoz, a sandbox.credentials beállítással pedig tiltsd le a hitelesítő fájlokat és tokeneket.
- A helyi hookokat ki lehet kerülni, ezért a pre-commit ellenőrzést és a GitHub push-védelmet együtt futtasd. A szerveroldali ellenőrzést egy helyi hook nem tudja kihagyni.
- A felhőhozzáféréshez a CI-ben OIDC-t használj, minden job csak a szükséges legkisebb jogosultsággal. Aki írási joggal rendelkezik egy tárolón, minden tárolótitkot el tud olvasni, ezért tartsd távol belőlük a hosszú életű kulcsokat.
- Ha egy titok átiratba, logba vagy commitba került, tekintsd kiszivárgottnak. Először cseréld le, utána takarítsd ki az előzményeket, mert a klónok és a gyorsítótárazott nézetek megőrzik a régi commitokat.
A kódoló ügynök olvassa a projektedet, futtatja a shellt és írja a commitjaidat, ezért a projektmappa minden titka egyetlen eszközhívásnyira van a modell kontextusablakától. Egyetlen beállítás sem oldja meg ezt. Tiltsd le a nem kívánt olvasásokat, sandboxold a shellt, ellenőrizd a commitok előtt, hagyd, hogy a szerver utasítsa vissza a titkot tartalmazó pusholásokat, a CI-nek pedig adj rövid életű tokeneket. Ezek közül több alapértelmezés szerint ki van kapcsolva.
Öt út, amelyen a titkok az ügynökön át kiszivárognak
Ezek a szivárgások többsége alapértelmezett beállításokból ered, nem támadóból, ezért könnyű őket figyelmen kívül hagyni.
- A projektfájlok. A munkakönyvtáron belüli olvasáshoz a Claude Code engedélyekről szóló oldala szerint nem kell jóváhagyás, ezért a projektben lévő
.envfájl kérés nélkül olvasható, és azután a beszélgetésben marad. - A shell. Az olyan parancsok, mint az
envvagy aprintenv, értékeket írnak az eszköz kimenetébe, a Claude Code sandboxa pedig alapértelmezés szerint a környezetet a titkokkal együtt továbbadja a parancsoknak. - Az átirat. A Claude Code a munkamenet-átiratokat alapértelmezés szerint 30 napig sima szövegként tárolja a
~/.claude/projects/mappában, így minden, amit az ügynök kiírt, a lemezen marad. - A commit.
git add -Aaz indexet a munkafához igazítja: hozzáad, módosít és eltávolít bejegyzéseket. Az ignorált fájlokat kihagyja, így a.envfájl, ha nincs a.gitignore-ban, abban a pillanatban bekerül az indexbe, amikor az ügynök lefuttatja a parancsot. Egy hibás teszt javítására kért ügynök egy konfigurációs értéket akár be is másolhat egy fixture-be, és commitolhatja. - Az eszközök. Egy MCP-szerver mindent megtehet, amit a tokenje enged, az MCP biztonsági útmutatója pedig arra kéri a klienseket, hogy figyelmeztessenek: a helyi szerverek ugyanazokkal a jogosultságokkal futnak, mint a kliens.
A kontextusablak a legkevésbé látható út. Egy fájl vagy parancskimenet a beszélgetés részévé válik, a beszélgetés pedig minden kéréssel a modellhez megy. A Claude Code adatkezelési dokumentációja szerint a promptok és a modell kimenetei TLS-en keresztül jutnak el a modell API-jához. A TLS a kapcsolatot védi, nem azt, amit a modell lát, ezért a titkot már az olvasás előtt kell megállítani.
Minden útnak saját kontroll kell, és a rendszerprompt egy sora nem ilyen kontroll. Az OWASP szerint a prompt-injekció megkerülheti az olyan utasításokat, mint a titkok kiírásának tiltása, ezért az érzékeny adatokhoz való hozzáférést a legkisebb jogosultság elve szerint korlátozd.
Először az olvasási tiltás: engedélyszabályok és a sandbox
Kezdd a fájleszközökkel. Egy Read-tiltó szabály megakadályozza, hogy megnyissák az útvonalat. A szintaxis a gitignore szabályait követi, így a .env a munkakönyvtár bármilyen mélységében egyezik, az ~/ kezdetű útvonal pedig a saját főkönyvtáradhoz kötődik. A szabályokat tiltás, majd kérdés, végül engedélyezés sorrendben ellenőrzi a rendszer, így a tiltás mindig nyer az engedélyezéssel szemben.
{
"permissions": {
"deny": [
"Read(.env)",
"Read(secrets/**)",
"Read(~/.aws/**)",
"Read(~/.ssh/**)"
]
}
}A .claude/settings.json fájllal oszthatsz meg szabályt a csapattal, a ~/.claude/settings.json pedig a saját gépedre vonatkozik. Minden hatókör tiltó szabályait az engedélyező szabályok előtt értékeli ki a rendszer. A felhasználói beállításokban használj ~/ vagy // útvonalat, hogy minden projektet elérj, mert a vezető perjel a beállítási fájlhoz képest értendő.
Két korlát számít. A szabályok a Read-eszközre, a Bash-on futtatott fájlparancsokra, például a cat, head, tail, sed és tee parancsokra, valamint a Bash-átirányításokra vonatkoznak. Nem vonatkoznak olyan parancsra, amely fájlokat olvas anélkül, hogy megnevezné őket, például a grep -r pattern ., és nem vonatkoznak a Python- vagy Node-szkriptre sem, amely maga nyit meg fájlokat. A .claudeignore fájlnak pedig nincs hatása, ezért vidd át a bejegyzéseit Read-tiltó szabályokba.
A sandbox a második réteg, és alapértelmezés szerint ki van kapcsolva. Kapcsold be a /sandbox paranccsal, vagy állítsd a sandbox.enabled értékét true-ra. macOS-en a Seatbelt, Linuxon és WSL2-n a bubblewrap érvényesíti a szabályokat, és csak a shell-parancsokat fedi le: a fájleszközök, az MCP-szerverek és a hookok kívül futnak. Az alapértelmezései szélesek. Az olvasás a gép nagy részét lefedi, a ~/.ssh és a ~/.aws/credentials is beleértve, a környezeti változókat pedig örökli. A credentials blokk zárja be ezeket a réseket.
{
"sandbox": {
"enabled": true,
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}Ez a példa a Claude Code sandbox-dokumentációjából származik. Blokkolja az AWS-hitelesítő fájl és az SSH-könyvtár olvasását, a sandboxolt parancsok környezetéből pedig eltávolítja a GITHUB_TOKEN és az NPM_TOKEN változót. Tartsd a ~/.claude/settings.json fájlban – a projektbeállítások nem kapcsolhatják ki a fájlrendszer-izolációt. Az a PreToolUse hook, amely 2-es kóddal lép ki, a hívást még azelőtt blokkolja, hogy az engedélyszabályok lefutnának. A hookok a sandboxon kívül futnak, ezért a szkriptjeiket megbízható kódként kezeld.
A Codexnél ugyanez a rés más formában jelentkezik, a CLI-t pedig a Codex-ismertetőmben mutatom be. A sandbox_mode lehet read-only, workspace-write vagy danger-full-access, a hálózati hozzáférés pedig kikapcsolva marad, amíg be nem kapcsolod. A shell környezete megtartja a nevükben KEY, SECRET vagy TOKEN szót tartalmazó változókat, mert az ignore_default_excludes alapértéke true. Állítsd false-ra, hogy a saját szűrőid lefutása előtt kiessenek:
[shell_environment_policy]
inherit = "core"
ignore_default_excludes = false
[shell_environment_policy.filters]
"AWS_*" = "exclude"Átiratok, visszajelzések és CI-logok
Az átiratok az a szivárgás, amelyet az emberek elfelejtenek. A Claude Code sima szövegként tárolja őket a ~/.claude/projects/ mappában alapértelmezés szerint 30 napig, a megőrzési időt pedig a cleanupPeriodDays beállítás módosítja. A kereskedelmi fiókokra ugyanez a 30 napos alapmegőrzés vonatkozik, a minősített Enterprise-fiókoknál pedig elérhető a nulla adatmegőrzés (zero data retention). A /feedback, a /bug és a /share parancs elküldi az Anthropicnak a beszélgetési előzményeid másolatát, a kódodat is beleértve, és ezeket a jelentéseket öt évig őrzik. Az átiratban lévő személyes adat ott is személyes adat marad, ahol van, ezért a törlési rutinodnak ki kell terjednie rá.
A Claude Code hibajelentései ismert titokmintákat maszkolnak, de ezek az eszköz saját belső hibáira vonatkoznak, nem a promptjaidra, fájljaidra vagy átiratodra. A CI-logokra saját szabályok vonatkoznak. A GitHub csak akkor maszkolja az értéket, ha a runner ismeri azt, a maszkolás pedig nagyrészt pontos egyezésen alapul, ezért a JSON-ba csomagolt titok átcsúszhat. Minden értékhez külön titkot hozz létre, és vedd fel a származtatott értékeket is, például az aláírt vagy kódolt változatot.
Ellenőrzés a commit előtt
Három nyílt forráskódú átvizsgáló fedi le szinte mindazt, amit futtatnék. Abban különböznek, hogy hogyan döntik el, mi számít titoknak, és ez fontosabb, mint a funkciólista.
| Eszköz | Hogyan működik | Miben jó | Mire figyelj |
|---|---|---|---|
| gitleaks | Jelszavakat, API-kulcsokat és tokeneket talál git-tárolókban. A pre-commit hook minden commitot átvizsgál, a gitleaks git pedig az előzményeket. | Egy eszköz a hookhoz és az előzmények átvizsgálásához. | A helyi hook a SKIP=gitleaks beállítással kihagyható. |
| detect-secrets | Baseline-fájl alapján vizsgál. A baseline rögzíti az ismert titkokat, a későbbi átvizsgálások pedig csak az újakat jelzik. | Olyan tárolóhoz, amely már titkokat tartalmaz. | A baseline elfogadja a meglévő titkokat, ezért commitolás előtt nézd át. |
| TruffleHog | Titokjelölteket talál, és az adott szolgáltató API-jával tesztelve ellenőrizheti őket, több mint 800 titoktípusnál. | Az élő hitelesítő adatok elkülönítése a már érvénytelenektől. | Az ellenőrzés minden jelöltet eljuttat a szolgáltatóhoz, ezért nézd meg, illik-e ez az adataidhoz. |
Én a gitleaksszel kezdeném, mert a hookja néhány sor YAML, és az előzményeket is átvizsgálja. A kiadási oldal a v8.30.1-et jelöli meg legújabbként, ezért a konfiguráció ezt a verziótagot rögzíti. Olyan tárolónál, amely már tartalmaz titkokat, a baseline-okkal kapcsolatban nézd meg a detect-secrets-ismertetőmet.
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaksA pre-commit install parancsot klónonként egyszer futtasd. A gitleaks README-je a kiskaput is leírja, a SKIP=gitleaks git commit parancsot, ezért a helyi hook a véletlen hibákat fogja meg, a szervernek pedig saját ellenőrzés kell.
Push-védelem: az ellenőrzés, amelyet a helyi hook nem tud kihagyni
A GitHub push-védelme blokkolja a felismert titkokat a parancssorból indított pusholásokban, a GitHub felületén készült commitokban, a fájlfeltöltésekben, a REST API-kérésekben és a GitHub MCP-szerverével folytatott interakciókban – utóbbit a dokumentáció csak nyilvános tárolókra korlátozza. Egy ügynök ezek közül többen keresztül is elérheti a távoli tárolót, a szerver pedig mindegyiket látja.
Két részlet dönti el, mennyire véd. A felhasználói push-védelem alapértelmezés szerint be van kapcsolva, de csak a GitHub.com nyilvános tárolóin. A tárolói push-védelemhez a GitHub Secret Protection kell, és addig ki van kapcsolva, amíg egy adminisztrátor be nem kapcsolja. Aki írási joggal rendelkezik, indoklással megkerülheti a blokkolást, és minden megkerülés riasztást és naplóbejegyzést hoz létre. A delegált megkerülés korlátozza, kik tehetik ezt meg.
CI: rövid életű tokenek a tárolt kulcsok helyett
A legolcsóbb titok, amely nem szivárog ki, az, amelyet soha nem tárolnak. OIDC-vel a workflow egy jobhoz kér tokent a GitHubtól, a felhőszolgáltató pedig a beállított bizalmi szabályokkal veti össze az alanyt és a többi claimet. A kiadott hozzáférési token csak arra a jobra érvényes. Az OWASP titokkezelési útmutatója ugyanerre mutat: a rövid életű vagy dinamikus titkokat részesítsd előnyben. A tokenkéréshez a workflow egyetlen jogosultságra van szüksége:
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkoutA GitHub referenciája szerint a id-token: write csak arra jogosítja a jobot, hogy lekérje az OIDC-tokent, és nem ad írási hozzáférést más erőforrásokhoz. Hagyd meg a contents: read beállítást, hacsak a job nem pusholja a kódot. A titkok nem jutnak el a forkból indított workflowkhoz, a GITHUB_TOKEN kivételével. Az igazi kockázat a pull_request_target és a workflow_run eseményeknél van: a keményítési útmutató szerint ezek megbízhatatlan pull request-kód checkoutjával kombinálva írási jogot és titkokat adhatnak annak a kódnak, és ezzel a tároló átvehető.
Az ügynököket a CI-ben ugyanolyan gyanakvással kell kezelni. Az az ügynök, amely egy issue-t vagy egy review-kommentet olvas, olyan szöveget olvas, amelyet valaki más írhatott, ezért ne tartson olyan titkot, amelyre nincs szüksége. A GitHub szerint bármely írási jogosultsággal rendelkező felhasználó el tudja olvasni az összes tárolótitkot. A környezeti titkokhoz kötelező átnézőket lehet rendelni. A sandbox oldalát illetően lásd az AI-ügynökök sandbox-ellenőrzőlistáját.
MCP-szerverek: szűk tokenek és csak olvasási hozzáférés
Az MCP-szerver hitelesítő adatot tart, és az eszközeit felajánlja az ügynöknek, ezért a tokenje a valódi határ. Az MCP biztonsági útmutatója tiltja a tokenátengedést (token passthrough), vagyis azt, hogy a szerver olyan tokent fogadjon el, amelyet kifejezetten neki adtak ki, és a legkisebb jogosultságú hatókörmodellt kéri. Azt is felsorolja, hogy a naplókba kerülő titkok az egyik módja annak, hogy egy támadó széles hatókörű tokenhez jusson. Az identitás oldalát az AI-ügynökök mint identitások című cikk tárgyalja.
A Claude Code oldalán a .mcp.json támogatja a ${VAR} behelyettesítést, amelyet a dokumentáció az érzékeny értékekhez, például API-kulcsokhoz ajánl, így a tárolóban hivatkozás áll a titok helyett. A dokumentáció emellett csak olvasási jogú adatbázis-felhasználót javasol, hogy a Claude által futtatott lekérdezések ne módosíthassanak adatot. Ha egy projektben ki akarsz kapcsolni minden MCP-eszközt, a mcp__* tiltó szabály eltávolítja őket a kontextusból. A Codex hálózati proxyja a dokumentációja szerint nem szűri az MCP-szerverkapcsolatokat.
Kiszivárgás után: először cseréld le, utána takarítsd ki
Az előzmények átírása takarítás, nem megoldás. A GitHub útmutatója szerint átírás és force push után a commitok elérhetők maradhatnak klónokon és forkokon, a gyorsítótárazott nézetekben szereplő SHA-1 hash-eken és az őket hivatkozó pull requesteken keresztül. Az átírás minden későbbi commit hash-ét megváltoztatja, és egy kolléga, aki egy régi klónt pusholva visszahozhatja a titkot. Először cseréld le.
- Vond vissza vagy cseréld le a hitelesítő adatot a szolgáltatónál, mielőtt bármi mást tennél.
- Nézd át a szolgáltató naplóját a kiszivárgás óta tartó használatra, és minden magyarázhatatlan használatot kezelj incidensként.
- Töröld a CI-futás logját, amely kiírta az értéket, a GitHub javaslata szerint, és minden olyan átiratot, amely tartalmazza.
- Ha a tárolónak nem szabad megőriznie az értéket, írd át az előzményeket a git-filter-repo eszközzel, majd kérd meg minden klón tulajdonosát, hogy klónozza újra.
- Vedd fel a mintát a pre-commit szkennerbe és a push-védelembe, hogy a következő szivárgást elutasítsák.
Ellenőrzőlista
| Kontroll | Hol található | Mit állít meg | Hogyan ellenőrizd |
|---|---|---|---|
| Olvasási tiltás | permissions.deny a settings.json fájlban | Az ügynök fájleszközei, valamint a titkokat olvasó cat, head vagy tail parancsok | Kérd meg egy tesztmunkamenetben, hogy olvassa el a .env fájlt, és várj blokkolást |
| Sandbox a hitelesítő adatok tiltásával | sandbox.enabled és sandbox.credentials | Shell-olvasás a ~/.aws és ~/.ssh mappákból, öröklött tokenek | Futtasd a /sandbox parancsot, és erősítsd meg, hogy be van kapcsolva |
| Codex környezeti szűrő | shell_environment_policy a config.toml fájlban | A parancsokhoz eljutó KEY-, SECRET- és TOKEN-változók | Ellenőrizd, hogy az ignore_default_excludes értéke false |
| Pre-commit átvizsgálás | gitleaks hook a .pre-commit-config.yaml fájlban | Titkok a helyi commitokban | Commitolj egy hamis kulcsot egy ágon, és várj elutasítást |
| Push-védelem | A tároló biztonsági beállításai | Titkok pusholásokban, felületi commitokban, feltöltésekben és MCP-hívásokban | Ellenőrizd, hogy be van kapcsolva, és a megkerülés korlátozott |
| OIDC a felhőhozzáféréshez | id-token: write és a felhős bizalmi szabályzat | Hosszú életű felhőkulcsok a tároló titkaiban | Töröld a felhőkulcsokat, amint a bizalmi kapcsolat működik |
| Legkisebb jogosultságú token | permissions blokk minden workflow-ban | A GITHUB_TOKEN visszaélése | Alapértelmezés: contents: read |
| Naplóhigiénia | Származtatott értékek felvéve, JSON-ba csomagolt titkok nélkül | Titkok a CI-naplókban | Keress rá egy tesztértékre egy futtatási naplóban |
| Kulcscsere-runbook | A szolgáltató konzolja és naplói | Élő értékek kiszivárgás után | Gyakorolj egy kevésbé fontos kulcson |
Mit tennék először
- Adj Read-tiltó szabályokat a .env fájlra, a titkokat tartalmazó mappákra, valamint a ~/.aws és a ~/.ssh mappára. Töröld azokat a .claudeignore fájlokat, amelyekre eddig támaszkodtál.
- Kapcsold be a sandboxot, és vegyél fel credentials-bejegyzéseket azokhoz a változókhoz és fájlokhoz, amelyeket ténylegesen használsz.
- Telepítsd a gitleaks-et pre-commit hookként, és kapcsold be a push-védelmet minden olyan tárolón, amelyet egy ügynök elérhet.
- Állítsd át a CI felhőhozzáférését OIDC-re, és minden workflow jogosultságait állítsd a minimumra.
- Írd meg a kulcscsere-runbookot, mielőtt szükséged lenne rá, és gyakorolj egy kevésbé fontos kulcson.
Ehhez nincs szükség platformra. Az alapértelmezéseket kell átállítani, a tárolóban néhány konfigurációs fájl kell, és az a szokás, hogy minden titoknál megkérded: el tudná-e olvasni, kiírni vagy commitolni az ügynök.
Források
- Claude Code: engedélyek
- Claude Code: sandboxolt Bash
- Claude Code: hookok
- Claude Code: adathasználat
- Claude Code: beállítások
- Claude Code: MCP-szerverek
- Codex: konfigurációs referencia
- Codex: ügynöki jóváhagyások és biztonság
- Codex: speciális konfiguráció
- GitHub: a push-védelemről
- GitHub: biztonsági keményítés OIDC-vel
- GitHub: OpenID Connect referencia
- GitHub: titkok használata az Actionsben
- GitHub: biztonságos használat referenciája
- GitHub: érzékeny adatok eltávolítása
- gitleaks: README és legújabb kiadás
- TruffleHog: README
- detect-secrets: README és legújabb kiadás
- Model Context Protocol: biztonsági legjobb gyakorlatok
- OWASP: titkkezelési puskalap
- OWASP: LLM02, érzékeny információk kiszivárgása
- Git: a git-add dokumentációja
Gyakori kérdések
Megakadályozhatom, hogy a Claude Code olvassa a .env fájlomat?
Igen. A permissions.deny listában megadott Read(.env) szabály blokkolja a fájleszközöket, és ugyanez a szabály fedi a fájlparancsokat is, például a cat, a head és a tail parancsot, amelyek a Bash-en keresztül futnak. Nem állítja meg azt a szkriptet, amely maga nyit meg fájlokat, ezért kapcsold be a sandboxot is.
Távol tartja a titkokat a Claude Code-tól a .claudeignore fájl?
Nem. A Claude Code engedélyekről szóló dokumentációja szerint a .claudeignore fájlnak nincs hatása, ezért vidd át a bejegyzéseit Read-tiltó szabályokba.
Elküldi a modellnek a titkokat, amelyeket az ügynök olvas?
Amit az ügynök elolvas, az a beszélgetés részévé válik, a beszélgetés pedig minden kéréssel a modell API-jához megy. Az Anthropic adatkezelési dokumentációja szerint a promptok és a modell kimenetei TLS-en keresztül utaznak, a munkamenet-átiratokat pedig alapértelmezés szerint 30 napig helyben, titkosítatlan szövegként tárolják.
Mit tegyek, ha egy kulcs commitba került?
Először cseréld le a kulcsot. Az előzmények átírása önmagában nem elég, mert a klónok, a forkok, a gyorsítótárazott nézetek és a pull requestek továbbra is őrizhetik a commitot. A GitHub támogatása csak akkor segít az érzékeny adatok eltávolításában, ha a hitelesítő adat cseréje nem tudja csökkenteni a kockázatot.