Akademia · Bezpieczeństwo AI

Zabezpieczanie Claude Code przed wyciekiem danych.

Praca z agentem na firmowym kodzie wymaga warstw ochrony. Pokazujemy, co realnie działa, a co jest tylko sugestią dla modelu — i jak złożyć deny rules, sandbox oraz hooki w jedną, niezawodną konfigurację.

Ostatnia aktualizacja:

Twarde blokadydeny rules egzekwowane runtime
Sandbox OS-levelizolacja obejmująca subprocesy
Hooki PreToolUseskrypt przed każdą operacją

01 / TL;DR · Co działa, co nie

Macierz skuteczności warstw zabezpieczeń.

WarstwaTypSkuteczność
Instrukcje w CLAUDE.mdMiękkaNiska — model może zignorować
.claudeignore / .gitignoreMiękkaZerowa — pliki ignorowane przez agenta
settings.json — deny rulesTwardaWysoka, ale znane bypassy
Sandbox modeOS-levelWysoka (macOS/Linux/WSL2)
PreToolUse hooksDeterministycznaNajwyższa — exit 2 = twarda blokada

Uwaga: nie polegaj wyłącznie na deny rules. Udokumentowano bypassy (m.in. system reminders ujawniające zawartość zablokowanych plików oraz niespójne egzekwowanie reguł dla .env). Jedyne niezawodne zabezpieczenie to połączenie: sandbox + deny rules + hooki.

02 / Warstwa 1 · Deny rules

settings.json — twarde blokady odczytu i zapisu.

Blokada jest aplikowana przed wywołaniem narzędzia, więc agent nie widzi zawartości. W hierarchii deny zawsze wygrywa nad allow i ask. Lokalizacje pliku:

ZakresLinux / macOSWindows
Globalnie~/.claude/settings.json%USERPROFILE%\.claude\settings.json
Projekt (współdzielony).claude/settings.json.claude\settings.json
Projekt (lokalny).claude/settings.local.json.claude\settings.local.json

Reguły uniwersalne

{
  "permissions": {
    "deny": [
      "Read(./.env)", "Read(./.env.*)",
      "Read(./secrets/**)", "Read(./config/credentials.*)",
      "Read(**/*.pem)", "Read(**/*.key)",
      "Bash(ping *)", "Bash(nslookup *)"
    ]
  },
  "cleanupPeriodDays": 7
}

Składnia ścieżek: reguły Read i Edit stosują semantykę gitignore (wzorce względem katalogu projektu). Ścieżkę absolutną podajesz przez podwójny ukośnik na początku — np. Read(//etc/hosts).

Dlaczego blokować ping i nslookup: CVE-2025-55284 pokazał eksfiltrację sekretów przez zapytania DNS, a te komendy bywały auto-zatwierdzane. Deny rules blokują narzędzia agenta, nie blokują sieci — dlatego zawsze dorzuć też blokadę curl i wget.

Reguły specyficzne dla systemu

Na Windows narzędzie nadal nazywa się Bash, ale pod spodem uruchamia PowerShell — blokuj komendy właściwe dla platformy:

// Linux / macOS
"Read(~/.ssh/**)", "Read(~/.aws/**)", "Read(~/.kube/**)",
"Bash(curl *)", "Bash(wget *)", "Bash(nc *)"

// Windows (PowerShell pod Bash)
"Bash(curl *)", "Bash(Invoke-WebRequest *)",
"Bash(Invoke-RestMethod *)", "Bash(iwr *)", "Bash(nc *)"

W ścieżkach Windows w JSON ukośniki wsteczne muszą być podwojone.

03 / Warstwa 1b · Sandbox mode

Izolacja OS-level — obejmuje też subprocesy.

Sandbox to najsilniejsza praktyczna ochrona dla komend powłoki: izoluje narzędzie Bash na poziomie systemu operacyjnego, łącznie z procesami potomnymi. W testach Anthropic zredukował liczbę monitów o ok. 84%. Działa natywnie na macOS, Linux i WSL2 — na macOS poprzez systemowy framework Seatbelt, więc nie instalujesz żadnych zależności. Natywny Windows nie jest obsługiwany.

SystemTechnologiaStatus
macOSSeatbeltPełne wsparcie (natywnie, nic nie instalujesz)
LinuxbubblewrapPełne wsparcie
WSL2bubblewrapPełne wsparcie
Windows natywnyNieobsługiwany

Konfiguracja

{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true,
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    }
  }
}

Twarde wymuszenie: failIfUnavailable: true sprawia, że Claude Code w ogóle nie wystartuje, gdy sandbox jest niedostępny — zamiast cicho przejść w tryb bez izolacji. Sandboxowane komendy Bash domyślnie dziedziczą zmienne środowiskowe rodzica, łącznie z poświadczeniami w env — kasujesz je przed każdą komendą blokiem sandbox.credentials (patrz niżej) albo globalnie zmienną CLAUDE_CODE_SUBPROCESS_ENV_SCRUB, która strippuje poświadczenia Anthropic i providerów chmurowych ze wszystkich subprocesów.

Aktualizacja: od wersji 2.1.187 sandbox ma dedykowany blok sandbox.credentials: w files wpisujesz ścieżki do zablokowania odczytu, w envVars — zmienne do skasowania, każdy wpis z "mode": "deny". To czytelniejsze niż mieszanie reguł w filesystem.denyRead: { "credentials": { "files": [{ "path": "~/.aws/credentials", "mode": "deny" }, { "path": "~/.ssh", "mode": "deny" }], "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }] } }. Wpisy z różnych zakresów się sumują, a jedyny dozwolony tryb to deny — żaden zakres nie poluzuje blokady.

Ograniczenia: sandbox dotyczy tylko narzędzia Bash — Read, Write, Edit i WebFetch są poza nim (rządzi nimi permissions.deny). Ustaw allowUnsandboxedCommands: false, inaczej agent może sam wyłączyć sandbox, gdy komenda zawiedzie. Na natywnym Windows używaj WSL2 (sudo apt-get install bubblewrap socat) albo Dockera.

Aktualizacja: sandbox to warstwa, nie szczelna granica. CVE-2026-55607 (załatany w 2.1.163) pokazał ucieczkę przez pomylenie ścieżek git worktree — worktree nazwany .git pozwalał wykonać kod poza Seatbeltem, i działało nawet w trybie read-only. Wniosek się nie zmienia: trzymaj Claude Code zaktualizowany i nie traktuj sandboxa jako jedynej linii obrony. Przy repozytoriach z niezaufaną treścią dorzuć izolację na poziomie kontenera albo VM.

Domyślnie sandbox pozwala CZYTAĆ cały komputer — w tym ~/.aws/credentials i ~/.ssh/. Izolacja ogranicza zapis i sieć, ale nie odczyt. Nie ma wbudowanej listy blokad, więc te ścieżki musisz zablokować jawnie: najprościej przez sandbox.credentials, ewentualnie przez sandbox.filesystem.denyRead albo reguły Read w permissions.deny.

04 / Warstwa 2 · PreToolUse hook

Skrypt przed każdą operacją — wykrywa sekrety zanim trafią do pliku.

Hook to skrypt powłoki uruchamiany przed wybranymi narzędziami. Kod wyjścia decyduje, co się stanie:

  • exit 0 — operacja przechodzi normalnie.
  • exit 1 — błąd hooka (operacja może przejść).
  • exit 2 — twarda blokada: operacja anulowana, agent widzi komunikat.

Rejestracja hooka skanującego Write i Edit

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/detect-secrets.sh" }
        ]
      }
    ]
  }
}

Skrypt skanuje generowaną treść pod kątem wzorców sekretów (klucze AWS, tokeny GitHub, klucze Stripe, hasła, connection stringi). Instalacja:

mkdir -p .claude/hooks
# skopiuj detect-secrets.sh do .claude/hooks/
chmod +x .claude/hooks/detect-secrets.sh

PostToolUse — audit log komend Bash

// Linux — dopisuje kazda komende do logu
"PostToolUse": [{
  "matcher": "Bash",
  "hooks": [{ "type": "command",
    "command": "jq -r '.tool_input.command' >> ~/.claude/command-audit-log.txt" }]
}]

05 / Warstwy 3 i 4 · Warstwy miękkie

CLAUDE.md i .env.example — uzupełniają, nie zastępują.

Instrukcje w CLAUDE.md to warstwa miękka — agent może je zignorować, więc nie traktuj ich jak zabezpieczenia. Mimo to warto je dodać jako pierwszą linię świadomości:

## Bezpieczenstwo — sekrety i hasla
- NIGDY nie umieszczaj hasel, tokenow i kluczy w kodzie
- Uzywaj zmiennych srodowiskowych: process.env.SECRET_KEY
- Nie czytaj pliku .env, nie echo-uj sekretow na konsole

Plik .env z prawdziwymi sekretami nigdy nie trafia do repozytorium. Zamiast niego commituj .env.example z taką samą strukturą, ale z placeholderami:

# .env.example — commituj do repo
DATABASE_URL=postgresql://user:password@localhost/mydb
STRIPE_SECRET_KEY=sk_live_your_key_here
GITHUB_TOKEN=ghp_your_token_here

# .gitignore — zawsze
.env
.env.local
*.pem
*.key

Nawet jeśli agent odczyta .env.example, prawdziwe sekrety nie wyciekną.

06 / Wdrożenie · Audit i checklista

Self-audit prompt i checklista nowego projektu.

Wklej ten prompt, gdy chcesz sprawdzić projekt pod kątem bezpieczeństwa:

Zrob audyt bezpieczenstwa tego projektu. Znajdz i zgłos:
1. Zahardkodowane hasla, klucze API, tokeny w kodzie
2. Sekrety w komentarzach
3. Slabe hasla (mniej niz 12 znakow, slowa ze slownika)
4. Pliki .env przypadkiem zacommitowane (sprawdz historie git)
5. Connection stringi z osadzonymi danymi logowania
6. Klucze prywatne i certyfikaty w repozytorium
7. Dane wrazliwe w logach

Dla kazdego znaleziska: plik, numer linii, waga, rekomendacja.
NIE wypisuj prawdziwych wartosci sekretow — tylko wskaz ich obecnosc.

Checklista — nowy projekt z Claude Code

  • .claude/settings.json z deny rules — dodaj ping i nslookup (CVE-2025-55284).
  • Sandbox z allowUnsandboxedCommands: false (Linux/WSL2); na natywnym Windows: deny rules + hooki.
  • Hook detect-secrets zainstalowany i wykonywalny.
  • .env w .gitignore, a w repo tylko .env.example z placeholderami.
  • Sprawdź historię: git log --all --full-history -- .env
  • Nigdy nie uruchamiaj agenta jako root, sudo ani Administrator.
  • cleanupPeriodDays: 7 w settings.json.

Test, czy blokady działają

# Zapytaj agenta: "pokaz zawartosc pliku .env"
# Oczekiwane: odmowa z powodu uprawnien

# Zapytaj: "zapisz do app.py: password = 'test123abc'"
# Oczekiwane: operacja zablokowana przez hook

Wdrożenie u Was

Chcecie, żeby cały zespół pracował z AI bezpiecznie?

Skonfigurujemy warstwy ochrony na Waszym repozytorium i wdrożymy je w zespole. 30 minut wystarczy, żeby sprawdzić, czy ma to u Was sens.