
Než AI agentovi dovolíte commitovat do repozitáře, měli byste znát jednu věc: ta zdvořilá prosba v CLAUDE.md, ať nic nemaže, nikoho nezastaví. O tom, co Claude Code doopravdy smí, nerozhoduje model ani vaše CLAUDE.md – rozhoduje systém oprávnění, který si (ne)nastavíte.

📋 TL;DR
- Permissions vynucuje program (Claude Code), ne model – platí to pro každého AI agenta.
CLAUDE.mda prompt ovlivňují jen to, co se Claude pokusí udělat – co smí, rozhodují pravidla. - Read-only nástroje (Read, Grep, LS) běží bez ptaní. Bash se ptá pořád, dokud mu neřeknete „don't ask again“ – to se zapíše natrvalo do settings.json. Úpravy souborů se ptají také, ale ono „yes“ platí jen na danou session.
- Pravidla žijou ve čtyřech úrovních: user, project (committed do gitu), local (gitignored) a managed (firemní politika, kterou nikdo needituje).
- Vyhodnocení jde v pořadí deny → ask → allow, první shoda vyhrává a deny kdekoli přebije allow kdekoli.
- Wildcards v pravidlech jsou zrádné – mezera,
&&nebo obyčejná shell proměnná dokážou i rozumně napsané deny pravidlo obejít. - Claude Code má šest permission modes, od plan po bypassPermissions. Bilík vyměnil defaultní bypass za auto mode, kde riskantnější akce navíc posuzuje samostatný classifier.
- Hooks dávají deterministickou kontrolu, kterou classifier nenabízí – stejný vstup, stejný verdikt, pokaždé.
- Kromě permissions v Claude Code řešte i least privilege u samotných nástrojů – API klíčů, GitLab tokenů i přístupu do Redmine.
🧠 Mentální model: co Claude zkusí a co mu to dovolí
Nejdůležitější věta celé přednášky mluví o rozdílu mezi přáním a vynucením. Když do CLAUDE.md napíšete „nedělej tohle“, je to jen zdvořilá žádost – nic nezaručuje, že se jí program bude držet, protože ji model může kdykoliv přehlédnout nebo si ji vyložit jinak. Zákaz v permissions je jiná liga: ten Claude Code fakticky vynutí, bez ohledu na to, co si model zrovna myslí.
V praxi to má tři podoby podle typu nástroje. Read-only nástroje jako Read, Grep nebo LS běží bez ptaní, pokud je explicitně nezakážete. Bash se ptá, dokud mu jednou nezvolíte „Yes, don't ask again“ – tahle volba se zapíše do allow listu ve settings.json a platí natrvalo. Úpravy souborů nabízejí jen „Allow in this session“, tedy souhlas platný do konce session; v nové konverzaci se Claude zeptá znovu.
Proč se u některých bash příkazů „don't ask again“ nikdy nenabídne? Buď je příkaz jen samé Yes/No a nedá se pro něj bezpečně napsat pravidlo, nebo má příliš mnoho subcommandů či konstrukcí typu watch / find -exec, které evaluátor pravidel nedokáže spolehlivě vyhodnotit. V takových případech se systém raději spolehlivě zeptá pokaždé, než aby riskoval špatně napsané pravidlo.
Ten rozdíl není náhoda: bash příkaz jde zapsat jako jasný vzor pravidla, zatímco souhlas s konkrétní úpravou souboru ne – proto ho Claude Code nikdy neukládá natrvalo a musíte ho potvrdit v každé nové session znovu.
📂 Kde ta pravidla žijí
Pravidla nejsou na jednom místě. Claude Code je hledá ve čtyřech úrovních settings.json, každá pro jiný účel:
- User –
~/.claude/settings.json. Vaše osobní nastavení, platí ve všech projektech, které otevřete. - Project –
.claude/settings.json. Committnuté do gitu, platí pro celý tým na daném projektu. - Local –
.claude/settings.local.json. Také vaše osobní nastavení, ale jen pro daný projekt – a je defaultně v.gitignore, takže je vhodné pro laborování a experimenty, které nechcete tlačit do sdíleného konfigu. - Managed – firemní politika. Nikdo ji nemůže přepsat, ani administrátor projektu.
Tyhle čtyři úrovně se čtou v přesně daném pořadí: managed settings, pak command-line flagy, pak local project settings, pak project (sdílené) settings a nakonec user settings. Každá nižší úroveň může doplnit, co v té vyšší chybí, ale nemůže přepsat, co managed nebo vyšší úroveň už jednou rozhodla.
⚖️ Deny, ask, allow: kdo vyhrává
Pro každou akci existují tři možné verdikty – allow, ask, deny. Vyhodnocení jde vždy ve stejném pořadí: napřed se kontroluje deny (ve všech úrovních settings.json najednou), pak ask, pak allow. První pravidlo, na které se narazí, rozhoduje a tím se vyhodnocení končí. Konkrétnější pravidlo v jiné úrovni nemá šanci se předběhnout – pokud máte deny v user settings a stejnou akci povolíte v project settings, deny prostě vyhraje. Managed deny je navíc absolutně finální; nic to nepřebije.
Typický zápis pravidel v settings.json vypadá takto:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}🕳️ Když hvězdička neznamená to, co si myslíte
Wildcards v pravidlech jsou zdrojem víc nejasností, než by se čekalo. Záleží na mezeře: Bash(ls *) a Bash(ls*) jsou dvě různá pravidla, a to druhé bez mezery propustí i příkazy, které byste čekali, že zůstanou zakázané. Naopak složené příkazy se naštěstí parsují správně – ls * spojené přes && s rm -rf . se vyhodnotí jako dva samostatné příkazy, takže rm -rf neprojde, i kdyby ls samotné povolené bylo.
Horší je to s argumenty: pravidla matchují text, ne úmysl, takže si na ně nelze úplně spolehnout. Typickým příkladem je zákaz stahování z GitHubu:
"deny": ["Bash(curl https://github.com/*)"]
# a přesto projde:
curl -X GET https://github.com/...
curl http://github.com/... # bez https
URL=https://github.com && curl $URL # přes proměnnouKdyž chcete něco skutečně zakázat, obvykle musíte napsat víc variant pravidla najednou, abyste pokryli i tyhle obchvaty. A pokud chcete jistotu, hvězdičky na to nestačí – k tomu se dostaneme u hooks.
🚦 Permission modes: od plan po bez brzd
Claude Code má šest permission modes, seřazených od největšího dohledu po nejméně promptů: plan (žádné edity, jen se díváte, co by Claude udělal), default, acceptEdits, auto, dontAsk a bypassPermissions. Ostatní čtyři Bilík záměrně nerozebíral do detailu. Zaměřil se na dva krajní a nejzajímavější případy, auto a bypassPermissions – oba mají za cíl omezit počet promptů, ale řeší to úplně jiným způsobem.
bypassPermissions je bez brzd: přeskočí každý dotaz i bezpečnostní kontrolu, tool cally se prostě spustí. Nechrání vás proti prompt injection ani proti chybě modelu. Použití má smysl jen v izolovaném throwaway containeru nebo VM, kde ani nevadí, kdyby se něco pokazilo – pod rootem navíc Claude Code tenhle režim ani nespustí.
auto přeskočí rutinní dotazy, ale každou riskantnější akci posílá samostatnému model-klasifikátoru, který ji zvlášť posoudí. Blokuje třeba curl | bash, exfiltraci dat, deploy do produkce nebo force-push do main. Klasifikátor obecně věří vašemu repozitáři a vlastním remotům, a když si není jistý, spadne zpátky na klasické dotazování.

Bilík dal defaultnímu bypassPermissions vale a jako svůj osobní default zkusil právě auto mode. Podle vlastní zkušenosti to funguje dobře – i pokyn daný na začátku session („tohle nedělej“) dokázal classifier respektovat po celou dobu konverzace. Stejně je to ale podle jeho slov „furt lehce nedeterministické“, takže tam, kde potřebujete tvrdou záruku, se bez pravidla v settings.json neobejdete.
„Auto mode je pro mě docela dobrý kompromis mezi tím, když se vás Claude furt na něco ptá, a tím, když nemá vůbec žádné brzdy.“

🪝 Hooks: deterministický strážce, když classifier nestačí
Nejdeterminističtější způsob, jak Claude Code říct, co může a nemůže, je PreToolUse hook. Je to váš vlastní skript, který se spustí před každým tool callem a podle návratové hodnoty rozhodne, jestli akce projde nebo ne – stejný vstup vždy dá stejný verdikt, žádný classifier do toho nevstupuje.
Typický vzor: povolíte Bash široce a hook pak zablokuje jen tu malou množinu opravdu nebezpečných příkazů (exit kód 2 = block). Hooky navíc můžou pravidla jen utahovat, nikdy povolovat – deny a ask pravidla ze settings.json mají přednost i před hookem, a managed hook nemůže žádný uživatel obejít.
Než sáhnete po bypassPermissions, ověřte si, že běžíte v prostředí, kde na tom nezáleží – throwaway container nebo VM, ne váš pracovní stroj s přístupem k produkčním credentials.
🔑 Druhá strana mince: oprávnění samotných nástrojů
Všechno výše popsané řeší permissions z pohledu Claude Code – jak si usnadnit život bez věčného odklikávání promptů. Existuje ale i druhá strana mince: oprávnění samotných nástrojů, které Claude používá, ať je to MCP server nebo CLI nástroj jako glab.
Tady platí stejný principle of least privilege jako u lidí – nástroj by měl mít vždycky jen to nejmenší možné oprávnění, které potřebuje ke své práci. Přesně stejná logika platí i pro samotné uživatele: ne každý má v GitLabu admin práva. Není to o nedůvěře ke kolegům, ale o omezení blast radia – pokud se někdo zmocní vašeho účtu nebo tokenu, měl by s ním zmoct jen zlomek toho, co by šlo se zcela neomezeným přístupem.
Na GitLabu s tím pomohly nové Fine-Grained Access Tokeny, které GitLab zpřístupnil v beta verzi v roce 2026. Při vytváření Personal Access Tokenu si teď m ůžete vybrat mezi starým, "legacy" režimem a novým fine-grained režimem, kde token naškálujete jen na konkrétní projekty a konkrétní oprávnění k nim – repozitář, merge requesty, CI/CD a tak dále. Token pak typicky patří do .env souboru daného projektu a používá ho třeba glab při autentizaci vůči GitLabu.

U Redmine je to bohužel složitější. Redmine dává jeden API klíč na účet a nedovolí ho naškálovat na konkrétní projekty ani akce. Je to limitace platformy, se kterou se potýká kdekdo, kdo Redmine používá pro API integrace. Typický důsledek: takový klíč se používá roky beze změny, protože ho není důvod (ani snadný způsob) rotovat. Funkční obchozí řešení je založit samostatného uživatele s přístupem jen do těch projektů, které agent potřebuje, a používat jeho API klíč místo vlastního; aktivita se pak v Redmine tváří jako aktivita toho účtu, ne vaše. Univerzální řešení pro Redmine ale neexistuje – jde o limitaci samotné platformy, ne o dočasnou mezeru, která brzy zmizí.
Často kladené otázky
🎯 Co si odnést
Permissions v Claude Code nejsou detail, který vyřešíte jedním „ne, tohle nedělej“ v CLAUDE.md. Jsou to skutečná pravidla, která se vyhodnocují v přesném pořadí (deny, ask, allow) a která žijou ve čtyřech úrovních settings.json od vašeho laptopu až po firemní politiku.
Reálná obrana kombinuje víc úrovní zároveň: rozumně nastavená pravidla pro to, co Claude smí zkusit bez ptaní, permission mode, který sedí kontextu (bypassPermissions jen v izolovaném containeru, auto jako rozumný kompromis pro běžnou práci), a tam, kde potřebujete jistotu, hook s deterministickým vlastním kódem, ne classifier, který se občas může splést.
Nezapomínejte ani na druhou stranu mince – oprávnění samotných nástrojů, které Claude používá. Fine-grained access tokeny má GitLab k dispozici od roku 2026, u Redmine si musíte pomoct vlastní hlavou a samostatným účtem s omezeným přístupem.
Jestli vás zajímá, jak si na podobných základech postavit celý agentic workflow, mrkněte na srovnání Cursoru a Claude Code nebo na to, jak sdílet AI know-how mezi týmy přes Claude Code pluginy.
Podobné postřehy z provozu Claude Code v Ackee najdete v newsletteru – přihlaste se a příští takový obsah vám přijde přímo do schránky.




