Claude Code'da İzin Kuralları (Permissions): Kapsamlı Rehber

Daha önce Auto Mode ve Sandbox yazılarında Claude Code'un onay yorgunluğunu azaltan iki katmanını ele almıştım — sınıflandırıcı tabanlı otomatik onay ve işletim sistemi düzeyinde izolasyon. Ama ikisinin de temelinde, çok daha eski ve çok daha temel bir mekanizma var: izin kuralları (permission rules). Hangi Bash komutunun sorulmadan çalışacağını, hangi dosyaların okunamayacağını, hangi alan adlarına fetch atılabileceğini ve hangi MCP araçlarının tamamen devre dışı bırakılacağını belirleyen sistem budur. Auto Mode bir sınıflandırıcıyla karar verirken, izin kuralları tamamen deterministiktir: settings.json dosyanıza yazdığınız allow/ask/deny listeleri, modelin ne düşündüğünden bağımsız olarak Claude Code tarafından zorunlu kılınır. Bu yazıda resmi dokümantasyona dayanarak bu kural söz dizimini, araca özel davranışları, wildcard tuzaklarını ve yönetilen (managed) dağıtım senaryolarını adım adım inceliyorum.

İzin Sistemi Nasıl Çalışır?

Claude Code, güç ile güvenliği dengelemek için katmanlı bir izin sistemi kullanır. Manuel modda (varsayılan mod) her araç tipi için onay gerekip gerekmediği şöyledir:

Araç tipi Örnek Onay gerekir mi? "Evet, bir daha sorma" davranışı
Salt okunur Dosya okuma, Grep Hayır (çalışma dizini ve ek dizinler içinde) Yok
Bash komutları Kabuk çalıştırma Evet, yerleşik salt-okunur komutlar hariç Repo + komut başına kalıcı
Dosya değişikliği Edit/write Evet Oturum sonuna kadar
Web fetch WebFetch Evet, önceden onaylı dokümantasyon alan adları hariç Repo + alan adı başına kalıcı
Web arama WebSearch Evet Repo başına kalıcı

"Evet, bir daha sorma" seçip onay kalıcı olarak kaydedildiğinde (bir Bash komutu ya da WebFetch alan adı gibi), Claude Code kuralı git deponun kök dizinindeki .claude/settings.local.json dosyasına yazar (worktree'ler ana checkout'a çözülür). Bu kural, alt dizinlerde ve worktree'lerde başlatılan oturumlar dahil, o depodaki gelecekteki tüm oturumlara uygulanır. Dosya değişikliği onayı ise dosyaya kaydedilmez — tablodaki gibi yalnızca oturum sonuna kadar geçerlidir. Bazı onay istemleri yalnızca tek seferlik kabul sunar, "bir daha sorma" seçeneği yoktur; Claude Code bu seçenekleri yalnızca istemin izin vereceği her şeyi gösterebildiği durumlarda sunar.

İzin Modları

Claude Code, araç çağrılarının nasıl onaylanacağını kontrol eden birkaç modu destekler. Oturumların hangi modda başlayacağını settings dosyalarınızdaki defaultMode anahtarıyla belirlersiniz:

Mod Açıklama
default Her aracın ilk kullanımında onay ister. CLI'da "Manual" olarak etiketlenir; manual takma adı da kabul edilir.
acceptEdits Çalışma dizini veya additionalDirectories içindeki yollar için dosya düzenlemelerini ve mkdir, touch, mv, cp gibi yaygın dosya sistemi komutlarını otomatik kabul eder.
plan Claude dosyaları okur, salt-okunur kabuk komutları çalıştırır ama kaynak dosyaları düzenlemez; Auto Mode etkinse sınıflandırıcı onaylı komutlar da çalışır.
auto Arka planda güvenlik kontrolleriyle araç çağrılarını otomatik onaylar (bkz. Auto Mode yazım).
dontAsk /permissions veya permissions.allow ile önceden onaylanmadıkça araçları otomatik reddeder.
bypassPermissions Hiçbir modun otomatik onaylamadığı birkaç eylem dışında tüm izin istemlerini atlar.

bypassPermissions modu .git ve .claude gibi korumalı yollara yazma dahil izin istemlerini atlar; bu yüzden yalnızca Claude Code'un zarar veremeyeceği izole ortamlarda (konteyner, VM) kullanılmalıdır. Bu modun ya da Auto Mode'un hiç kullanılamamasını istiyorsanız herhangi bir settings dosyasında permissions.disableBypassPermissionsMode veya permissions.disableAutoMode anahtarını "disable" yapabilirsiniz — bunlar özellikle yönetilen (managed) ayarlarda geçersiz kılınamayacakları için değerlidir.

/permissions Komutuyla Kural Yönetimi

/permissions komutu tüm izin kurallarını ve her kuralın hangi settings.json dosyasından geldiğini listeler. Oturum sırasında da açılabilir; bir kural eklediğinizde ya da kaldırdığınızda Claude Code değişikliği aynı turda Claude'un bir sonraki araç çağrısından itibaren uygular. Üç kural tipi vardır:

  • Allow: belirtilen aracın manuel onay olmadan kullanılmasına izin verir.
  • Ask: belirtilen araç her denendiğinde onay ister.
  • Deny: belirtilen aracın kullanılmasını engeller.

Kurallar her zaman deny, sonra ask, sonra allow sırasıyla değerlendirilir; bu sırada ilk eşleşen kural sonucu belirler ve kuralın spesifikliği bu sırayı değiştirmez. Bash(aws *) gibi geniş bir deny kuralı, Bash(aws s3 ls) gibi daha dar bir allow kuralıyla eşleşen çağrıları da bloke eder — yani deny kuralına allowlist istisnası eklenemez. Aynı öncelik ask ile allow arasında da geçerlidir.

Deny kuralları, bir aracı adlandırıp adlandırmadığına göre farklı davranır. Bash gibi çıplak bir araç adı, aracı Claude'un bağlamından tamamen kaldırır — Claude o aracı hiç görmez. Bash(rm *) gibi kapsamlı bir kural ise aracı kullanılabilir bırakır, yalnızca eşleşen çağrıları engeller. Önemli bir not: izin kuralları modelin kendisi tarafından değil Claude Code tarafından zorunlu kılınır — prompt'unuzdaki veya CLAUDE.md'deki talimatlar Claude'un ne denemek istediğini şekillendirir ama Claude Code'un neye izin vereceğini değiştirmez.

Kural Söz Dizimi

İzin kuralları Tool veya Tool(specifier) biçimini izler.

Tüm Kullanımları Eşleştirme

Bir aracın tüm kullanımlarını eşleştirmek için parantezsiz yalnızca araç adını yazın: Bash tüm Bash komutlarını, WebFetch tüm web fetch isteklerini, Read tüm dosya okumalarını eşleştirir. Bash(*), Bash ile eşdeğerdir.

Specifier ile İnce Ayar

Belirli araç kullanımlarını eşleştirmek için parantez içine bir specifier eklersiniz:

Kural Etki
Bash(npm run build) Yalnızca tam npm run build komutunu eşleştirir
Read(./.env) Geçerli dizindeki .env dosyasının okunmasını eşleştirir
WebFetch(domain:example.com) example.com'a fetch isteklerini eşleştirir

Parametreye Göre Eşleştirme

Deny ve ask kuralları, herhangi bir yerleşik araçtaki üst düzey bir girdi parametresini Tool(param:value) biçimiyle eşleştirebilir — örneğin Agent(model:opus) Opus modelini isteyen Agent çağrılarını, Bash(run_in_background:true) arka planda çalışan Bash çağrılarını eşleştirir. Kurallar şu şekilde çalışır:

  • Parametre adı aracın girdisinin doğrudan bir alanı olmalıdır; iç içe geçmiş alanlar eşleştirilemez.
  • Her kural tek bir parametreyi adlandırır; hem model hem isolation üzerinde koşul koymak için iki ayrı kural yazılır.
  • Değer, herhangi bir karakter dizisiyle eşleşen * joker karakterini destekler.
  • Modelin atladığı bir parametre asla eşleşmez.
  • Değer, herhangi bir normalizasyondan önce Claude'un gönderdiği ham girdiyle karşılaştırılır.

Bash için command, Read/Edit/Write için file_path, Grep/Glob için path, WebFetch için url gibi bir aracın birincil içerik alanı bu şekilde eşleştirilemez — Bash(command:rm *) gibi bir kural birleşik bir komutla kolayca aşılabileceği için Claude Code onu yok sayar ve başlangıçta bir uyarı gösterir. Bunun yerine Bash(rm *), Read(./path) veya WebFetch(domain:host) kullanılır.

Wildcard Desenleri

Bir Bash kuralındaki *, boşluklar dahil her metni eşleştirir. Joker karakteri alt komuttan sonra koymak kritiktir: git log --oneline main komutunda git program, log alt komuttur. Claude Code ilk *'a kadar olan kısmı olduğu gibi eşleştirir, yani Bash(git log *) yalnızca git log komutlarına izin verirken Bash(git *) her git komutuna izin verir. Claude Code, alt komuttan önce joker karakter bulunan bir allow kuralı için başlangıçta uyarı gösterir.

Yazdığınız Eşleşenler Eşleşmeyenler
Bash(npm run build) npm run build npm run build --watch
Bash(npm run *) npm run build, npm run test --watch, npm run npm install
Bash(git log * main) git log --oneline main, git log -5 main git log main, git push origin main
Bash(git * main) git merge main, git push origin main git log
Bash(ls *) ls -la, ls lsof
Bash(ls*) ls -la, lsof

Sondaki *'tan önceki boşluk kuralın bir parçasıdır: Bash(ls *) ls'den sonra boşluk gerektirdiği için lsof'u eşleştirmez, Bash(ls*) boşluksuz olduğu için eşleştirir. :* soneki, sondaki boşluklu joker karakterin eşdeğeridir, yani Bash(ls:*) ile Bash(ls *) aynı komutları eşleştirir.

Aşağıdaki yapılandırma, Claude'un npm script'lerini ve git commit'lerini onaysız çalıştırmasını sağlar, git push'u reddeder:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

Bash argümanlarını kısıtlamaya çalışan desenler kırılgandır. Örneğin Bash(curl http://github.com/ *) curl'ü GitHub URL'leriyle sınırlamayı amaçlar ama curl -X GET http://github.com/... gibi seçenek-önce kullanımları, https:// protokol farkını, kısa bir URL'nin GitHub'a yönlendiren bir redirect'i ya da URL=... && curl $URL gibi değişken kullanımını yakalayamaz. Daha güvenilir bir filtreleme için curl/wget'i deny ile engeleyip izinli alan adları için WebFetch(domain:...) kullanmak, ya da URL'leri doğrulayan bir PreToolUse hook'u yazmak önerilir.

Araç Adı Joker Karakterleri

Deny ve ask kuralları, araç-adı konumunda da glob desenlerini kabul eder: "*" her aracı, "mcp__*" tüm sunuculardaki her MCP aracını eşleştirir. Allow kuralları ise araç-adı glob'unu yalnızca değişmez bir mcp__<sunucu>__ önekinden sonra kabul eder — mcp__puppeteer__* puppeteer sunucusunun tüm araçlarını eşleştirir, ama "*" veya "mcp__*" gibi çapasız bir allow glob'u uyarıyla birlikte atlanır ve hiçbir şeyi otomatik onaylamaz. Tüm MCP araçlarını reddetmek için:

{
  "permissions": {
    "deny": [
      "mcp__*"
    ]
  }
}

Araca Özel İzin Kuralları

Bash

Claude Code shell operatörlerinin farkındadır, bu yüzden Bash(safe-cmd *) gibi bir kural, safe-cmd && other-cmd komutunu çalıştırma izni vermez. Tanınan komut ayırıcılar &&, ||, ;, |, |&, & ve satır sonlarıdır; bir kural her alt komutu ayrı ayrı eşleştirmelidir. Bileşik bir komutu "Evet, bir daha sorma" ile onayladığınızda Claude Code, tüm bileşik dize için tek bir kural yerine onay gerektiren her alt komut için ayrı bir kural kaydeder — böylece git status && npm test onayı, önünde ne olursa olsun gelecekteki npm test çağrılarını da tanır (tek bir bileşik komut için en fazla 5 kural kaydedilebilir).

Eşleştirmeden önce Claude Code, timeout, time, nice, nohup, stdbuf gibi bir dizi sabit sarmalayıcıyı (wrapper) ve zsh'nin noglob'unu ayıklar, yani Bash(npm test *) kuralı timeout 30 npm test'u da eşleştirir. Bu liste yapılandırılamaz ve direnv exec, devbox run, npx, docker exec gibi ortam çalıştırıcıları listede değildir — bunlar argümanlarını komut olarak çalıştırdığı için Bash(devbox run *) gibi bir kural devbox run rm -rf . dahil run'dan sonra gelen her şeye izin verir. Belirli bir çağrıyı onaylamak için hem çalıştırıcıyı hem iç komutu içeren tam bir kural yazmak gerekir, örneğin Bash(devbox run npm test).

Claude Code; ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd ve salt-okunur git formlarını içeren yerleşik bir salt-okunur komut kümesini her modda onaysız çalıştırır; bu küme yapılandırılamaz. Bu komutlar bile find, sort, sed, git gibi yazma yeteneği olan bayraklarla birlikte tırnaksız glob içeriyorsa, ya da komut ayrıştırılamayacak kadar karmaşıksa (10.000 karakteri aşan komutlar dahil) manuel modda yine sorar. Bir çıktı yönlendirmesi (>, >>, 2>) hedefi, bir dosya yazma işlemi olarak kontrol edilir; /dev/null hedefi kontrol edilmez.

Read ve Edit

Claude'un dosya araçlarının bir dosyayı veya dizini okumasını engellemek için o yola bir Read deny kuralı eklenir, örneğin Read(./.env) veya Read(./secrets/**). Edit kuralları, dosya düzenleyen tüm yerleşik araçlara uygulanır. Read ve Edit kuralları dört farklı desen tipini kullanır:

Desen Anlamı Örnek
//path Dosya sistemi kökünden mutlak yol Read(//Users/alice/secrets/**)
~/path Ev dizininden göreli yol Read(~/Documents/*.pdf)
/path Ayar kaynağına göreli yol Edit(/src/**/*.ts)
path veya ./path Geçerli dizine göreli yol Read(*.env)

Dikkat: /Users/alice/file gibi tek eğik çizgili bir desen mutlak yol değildir — tek başına gelen eğik çizgi, dosya sistemi kökü yerine ayar kaynağının bulunduğu yere çapalanır. Gerçek mutlak yol için //Users/alice/file kullanılmalıdır. Bir Read deny kuralı aynı yoldaki Edit ve Write araçlarını da (o yolda yeni dosya oluşturmak dahil) engeller, ama NotebookEdit bu kapsamda değildir; not defterlerini de korumak için ayrı bir Edit deny kuralı gerekir. Simgesel bağlar (symlink) için allow ve deny kuralları farklı davranır: bir allow kuralı, hem symlink yolu hem hedefi eşleştiğinde uygulanır (biri dışarıdaysa yine sorar), bir deny kuralı ise ikisinden biri eşleştiğinde bile bloke eder.

WebFetch

WebFetch kuralları bir domain: öneki kullanır ve istenen URL'nin hostname'iyle eşleşir; eşleştirme büyük/küçük harf duyarsızdır ve * joker karakterini destekler. WebFetch(domain:*.example.com) herhangi bir alt alan adını eşleştirir ama example.com'un kendisini eşleştirmez. Boş (domain'siz) WebFetch kuralı ile WebFetch(domain:*) arasında önemli bir fark vardır: ikisi de allow listesinde her URL'yi kapsar, ama yalnızca domain: formu sandbox'ın izinli/engelli alan adı listesini de günceller. Boş kuralı deny listesine koymak aracı Claude'un bağlamından tamamen kaldırırken, WebFetch(domain:*) deny olarak aracı bırakır ama her fetch'i reddeder.

MCP, Agent ve Cd

MCP kuralları, Claude Code'da yapılandırılan sunucu adını, isteğe bağlı olarak da bir araç adını kullanır: mcp__puppeteer o sunucunun tüm araçlarını, mcp__puppeteer__puppeteer_navigate ise yalnızca belirli bir aracı eşleştirir. Agent(AgentName) kuralları hangi subagent'ların kullanılabileceğini kontrol eder — Agent(Explore) yerleşik Explore subagent'ını, Agent(my-custom-agent) özel bir subagent'ı devre dışı bırakır:

{
  "permissions": {
    "deny": ["Agent(Explore)"]
  }
}

Cd kuralları ise /cd komutunun hangi dizinlere taşınabileceğini kontrol eder; bu bir model-çağrılabilir araç değildir, yalnızca siz /cd'yi çalıştırdığınızda devreye girer. Herhangi bir Cd allow kuralı eklemek /cd'yi allowlist moduna geçirir: hedef dizin bir allow kuralıyla eşleşmelidir, aksi halde komut reddedilir.

Hook'larla İzinleri Genişletme

PreToolUse hook'ları, Claude Code her araç çağrısı yaptığında (EndConversation hariç) izin istemi öncesinde çalışan özel kabuk komutlarıdır ve çalışma zamanında izinleri değerlendirebilir; çıktısı aracı reddedebilir, onay istemini zorlayabilir ya da onayı atlayarak çağrının geçmesine izin verebilir. Ama hook kararları izin kurallarını geçersiz kılmaz: Claude Code deny ve ask kurallarını hook'un sonucundan bağımsız değerlendirir, yani hook "allow" veya "ask" dönse bile eşleşen bir ask kuralı yine sorar. Tersine, çıkış koduyla 2 dönen engelleyici bir hook izin kuralları değerlendirilmeden aracı durdurur — bu yüzden allow kuralı olan bir araç bile hook tarafından bloke edilebilir. Pratik bir kalıp: tüm Bash komutlarını onaysız çalıştırmak isteyip yalnızca birkaçını bloke etmek için allow listesine "Bash" eklemek ve o birkaç komutu reddeden bir PreToolUse hook'u kaydetmek.

Çalışma Dizinleri

Varsayılan olarak Claude, Claude Code'u başlattığınız dizindeki dosyalara erişebilir. Bu erişimi üç yolla genişletebilirsiniz: başlangıçta --add-dir <path> bayrağıyla, oturum sırasında /add-dir komutuyla, ya da kalıcı olarak settings dosyalarındaki additionalDirectories listesine ekleyerek. Ama bu iki yöntem eşdeğer değildir: yalnızca --add-dir//add-dir ile eklenen dizinler ek bir yapılandırma kökü gibi davranır — o dizindeki .claude/skills, .claude/commands ve .claude/agents dosyaları yüklenir (skill'ler canlı yeniden yükleme ile). additionalDirectories ayarına eklenen dizinler ise yalnızca dosya erişimi sağlar, hiçbir yapılandırma yüklemez.

Oturumu farklı bir birincil çalışma dizinine taşımak için /cd <path> kullanılır (v2.1.169+). Bu, konuşmayı korur, yeni dizinin CLAUDE.md'sini yükler ve daha önce çalışılmamış bir dizinse workspace trust istemi gösterir. Taşındıktan sonra Claude Code yeni dizinin proje ayarlarını, izin kurallarını, hook'larını, .mcp.json sunucularını, eklentilerini, skill'lerini ve subagent'larını uygular; önceki dizinin proje ve local-scope MCP sunucularının bağlantısını keser.

Permissions ile Sandbox'ın İlişkisi

Permissions ve Sandbox tamamlayıcı güvenlik katmanlarıdır. Permissions hangi araçların kullanılabileceğini ve hangi dosya/alan adlarına erişilebileceğini kontrol eder — Bash, Read, Edit, WebFetch, MCP dahil neredeyse her araca uygulanır. Sandbox ise yalnızca Bash aracını ve alt süreçlerini kapsar, işletim sistemi düzeyinde dosya sistemi ve ağ erişimini kısıtlar. İkisi birlikte savunma derinliği sağlar: izin deny kuralları Claude'un erişmeye çalışmasını bile engellerken, sandbox sınırları bir prompt injection Claude'un karar mekanizmasını atlatsa bile Bash komutlarının tanımlı sınırların dışına çıkmasını önler. Sandbox açıkken ve autoAllowBashIfSandboxed varsayılan true değerindeyken, sandboxlı Bash komutları çıplak bir Bash ask kuralınız olsa bile sormadan çalışır — sandbox sınırı, o geniş istemin yerini alır. Bash(git push *) gibi içerik bazlı ask kuralları ve açık deny kuralları bu durumda bile geçerliliğini korur.

Organizasyonlar için Yönetilen Ayarlar

Merkezi kontrol gereken organizasyonlar için yöneticiler, kullanıcı ve proje ayarlarının geçersiz kılamayacağı yönetilen (managed) ayarlar dağıtabilir. Bu anahtarlardan biri olan allowManagedPermissionRulesOnly, yönetilen ayarları izin kurallarının tek kaynağı hâline getirir. disableBypassPermissionsMode genellikle yönetilen ayarlara konur ama aslında herhangi bir kapsamdan ayarlanabilir — bir kullanıcı kendi ayarlarında bunu true yaparak kendini bypass modundan mahrum bırakabilir.

İzin kuralları, tüm diğer Claude Code ayarlarıyla aynı öncelik sırasını izler; yönetilen ayarlar en üsttedir ve komut satırı argümanları dahil hiçbir seviye yönetilen bir izin kuralını geçersiz kılamaz. Bir araç herhangi bir seviyede reddedilmişse başka hiçbir seviye onu izin veremez — örneğin yönetilen bir deny, --allowedTools ile aşılamaz, ama --disallowedTools yönetilen ayarların ötesinde ek kısıtlamalar ekleyebilir. Aynı kural kapsamlar arasında da geçerlidir: kullanıcı ayarları bir izni verirken proje ayarları onu reddederse deny kazanır; tersi de doğrudur, çünkü herhangi bir kapsamdaki deny kuralları allow kurallarından önce değerlendirilir.

Gerçek Dünya Örneği: Bir Node.js Projesi için settings.json

Diyelim ki bir takım projesinde çalışıyorsunuz; Claude Code'un testleri, lint'i ve build script'lerini onaysız çalıştırmasını, küçük commit'ler atmasını istiyorsunuz — ama git push'u, gizli dosyaların okunmasını ve tanımadığı alan adlarına fetch atmasını istemiyorsunuz. Projenizin .claude/settings.json dosyasına şunu ekleyebilirsiniz:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(npm test *)",
      "Bash(git commit *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "WebFetch(domain:docs.npmjs.com)",
      "WebFetch(domain:github.com)"
    ],
    "ask": [
      "Bash(npm publish *)"
    ],
    "deny": [
      "Bash(git push *)",
      "Read(./.env)",
      "Read(./secrets/**)",
      "Read(~/.ssh/**)"
    ],
    "additionalDirectories": ["../shared-lib"]
  }
}

Bu yapılandırmayla Claude test ve build script'lerini, küçük commit'leri sormadan çalıştırabilir; ../shared-lib dizinindeki dosyaları da çalışma dizinindeymiş gibi okuyup düzenleyebilir. npm publish her seferinde onay ister, git push ise tamamen reddedilir. .env, secrets/ ve SSH anahtarları hem Read hem (deny kapsamı gereği) Edit/Write araçlarından korunur — hatırlatmak gerekir ki bu koruma yalnızca Claude'un yerleşik dosya araçlarına ve Bash'te tanınan cat/sed gibi komutlara uygulanır; dosyaları kendi başına açan bir Python veya Node script'ini engellemez. İşletim sistemi düzeyinde tam izolasyon için Sandbox devreye sokulmalıdır.

Sorun Giderme

Sorun Neden / Çözüm
Yazdığım allow kuralı beklenenden çok daha fazlasını onaylıyor Joker karakter alt komuttan önce yazılmış olabilir (Bash(git * main) gibi). Claude Code başlangıçta bunun için uyarı gösterir; joker karakteri alt komuttan sonra taşıyın.
Bir dosyayı Read ile engelledim ama Claude yine de üzerine yazabiliyor Kural yalnızca Write, NotebookEdit, Glob veya eski MultiEdit için mi yazıldı? Dosya izinleri yalnızca Edit(path) ve Read(path) kurallarına bakılarak kontrol edilir; not defterleri için ayrıca bir Edit deny kuralı gerekir.
Bir MCP aracının tek bir parametresini reddetmek istiyorum ama kural yok sayılıyor MCP araçlarında parametreye göre eşleştirme desteklenmez; parantez içeren mcp__ kuralları settings dosyasından yüklenirken atlanır. Bunun yerine --disallowedTools CLI bayrağı kullanılmalıdır.
curl komutunu belirli bir alan adıyla sınırlamaya çalıştım ama kural aşılıyor Bash argüman kısıtlamaları yapısal olarak kırılgandır (redirect, değişken, boşluk varyasyonları). curl/wget'i deny edip WebFetch(domain:...) kullanın veya bir PreToolUse hook'u yazın.
MCP sunucusu için yazdığım geniş bir allow kuralı hiçbir şeyi onaylamıyor Allow kuralları araç-adı glob'unu yalnızca değişmez bir mcp__<sunucu>__ önekinden sonra kabul eder. Çapasız "*" veya "mcp__*" gibi bir allow deseni uyarıyla birlikte atlanır.

Sıkça Sorulan Sorular (SSS)

Aynı komutla bir allow, bir de deny kuralı çakışırsa hangisi kazanır?

Kurallar her zaman deny, sonra ask, sonra allow sırasıyla değerlendirilir; ilk eşleşen kural sonucu belirler ve kuralın ne kadar spesifik olduğu bu sırayı değiştirmez. Bash(aws *) gibi geniş bir deny kuralı, daha dar bir allow kuralıyla eşleşen çağrıları da bloke eder.

Bash(git *) gibi geniş bir allow kuralı yazarsam git push da onaysız mı çalışır?

Evet, joker karakter alt komuttan önce gelirse kural düşündüğünüzden fazlasını kapsar. Doğru kullanım joker karakteri alt komuttan sonra koymaktır: Bash(git commit *) yalnızca commit'i kapsar, git push için ayrı bir deny kuralı yazılmalıdır.

Bir dosyaya Read deny kuralı koyarsam Edit ve Write araçları da engellenir mi?

Evet, aynı yoldaki Edit ve Write araçlarını da (o yolda yeni dosya oluşturmak dahil) engeller. Ancak NotebookEdit bu kapsamda değildir; ayrıca bir Edit deny kuralı gerekir.

Boş WebFetch kuralı ile WebFetch(domain:*) arasındaki fark nedir?

İkisi de allow listesinde her URL'yi kapsar ama yalnızca domain: formu sandbox'ın izinli alan adı listesini de günceller. Deny listesinde ise boş kural aracı bağlamdan tamamen kaldırırken domain:* aracı bırakır ama her fetch'i reddeder.

Bir PreToolUse hook'u, allow kuralı olan bir aracı yine de engelleyebilir mi?

Evet. Çıkış koduyla 2 dönen engelleyici bir hook, izin kuralları değerlendirilmeden aracı durdurur. Tersine hook kararları deny/ask kurallarını geçersiz kılamaz — hook "allow" dese bile eşleşen bir ask kuralı yine sorar.

additionalDirectories ile --add-dir arasındaki fark nedir?

Yalnızca --add-dir//add-dir ek bir yapılandırma kökü gibi davranır ve o dizindeki skill/command/subagent dosyalarını yükler. settings.json'daki additionalDirectories listesi ise yalnızca dosya erişimi sağlar, hiçbir yapılandırma yüklemez.

Özet

Claude Code'un izin sistemi, üç basit ama kesin kuraldan oluşur: deny her zaman kazanır, ask allow'dan önce gelir, ve joker karakter alt komuttan sonra yazılmalıdır. Bu üç kuralı içselleştirdikten sonra settings.json'a yazacağınız allow/ask/deny listeleri, Auto Mode'un sınıflandırıcısından bağımsız, tamamen öngörülebilir bir güvenlik katmanı oluşturur — komut satırından takıma, takımdan tüm organizasyona kadar aynı söz dizimiyle ölçeklenir. Pratikte en sağlam kurulum üç katmanı birlikte kullanmaktır: rutin komutlar için allow kuralları, riskli komutlar için deny/ask, ve gerçek bir güvenlik sınırı için (Bash özelinde) Sandbox. Kalan her şey için de Auto Mode'un sınıflandırıcısı devreye girer. Bu üç yazıyı birlikte okuduğunuzda Claude Code'un izin mimarisinin tam resmine sahip olursunuz.

Bu yazı Ahmet Bilgiç tarafından ahmetbilgic.com için yazılmıştır. Diğer yazılar için: medium.com/@ahmet_bilgic07