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:

Terminal z pytaniem o uprawnienia agenta, obok kłódka i klucz sprzętowy na biurku
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 — bez instalowania jakichkolwiek zależności na macOS. 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"]
    }
  }
}

Granice izolacji: sandbox dotyczy tylko narzędzia Bash — Read, Write, Edit i WebFetch są poza nim (rządzi nimi permissions.deny). Domyślnie pozwala też czytać cały komputer, łącznie z poświadczeniami AWS i kluczami SSH — izolacja ogranicza zapis i sieć, ale nie odczyt — a komendy dziedziczą zmienne środowiskowe rodzica razem z sekretami w env. Dlatego dwie flagi z konfiguracji powyżej są obowiązkowe: allowUnsandboxedCommands: false, inaczej agent może sam wyłączyć sandbox, gdy komenda zawiedzie, oraz failIfUnavailable: true, dzięki której Claude Code w ogóle nie wystartuje, gdy sandbox jest niedostępny — zamiast cicho przejść w tryb bez izolacji. Na natywnym Windows używaj WSL2 (sudo apt-get install bubblewrap socat) albo Dockera.

Blokada poświadczeń — sandbox.credentials

Nie ma wbudowanej listy blokad odczytu, więc ścieżki z sekretami blokujesz jawnie. Od wersji 2.1.187 służy do tego dedykowany blok sandbox.credentials: w files wpisujesz ścieżki do zablokowania odczytu, w envVars — zmienne do skasowania, każdy wpis z "mode": "deny". Wpisy z różnych zakresów się sumują, a jedyny dozwolony tryb to deny — żaden zakres nie poluzuje blokady. To czytelniejsze niż rozrzucanie blokad po filesystem.denyRead czy regułach Read w permissions.deny:

{
  "sandbox": {
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }]
    }
  }
}

Zmienne środowiskowe możesz też strippować globalnie — CLAUDE_CODE_SUBPROCESS_ENV_SCRUB usuwa poświadczenia Anthropic i providerów chmurowych ze wszystkich subprocesów.

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. 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.

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 / Wdrożenie · Warstwy miękkie i checklista

Warstwy miękkie, self-audit i checklista projektu.

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

## 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 — commitujesz wersję przykładową 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

Self-audit prompt

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 — łącznie z komendami DNS z sekcji 02 (CVE-2025-55284).
  • Sandbox włączony, z obiema flagami wymuszenia z sekcji 03; 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. Audyt 90 minut wystarczy, żeby sprawdzić, czy ma to u Was sens.