Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
Z tego artykułu dowiesz się:
--dangerously-skip-permissionssettings.json (enterprise -> global -> project -> local)PreToolUse i PostToolUse do audytu i blokowania operacjiKiedy dajesz asystentowi AI dostęp do systemu plików i shella (powłoki systemu — czyli wiersza poleceń, w którym wpisuje się komendy), dajesz mu w praktyce klucze do swojego środowiska pracy. Claude Code rozwiązuje to elegancko — system uprawnień działa na trzech niezależnych warstwach, które można ze sobą łączyć: interaktywne zatwierdzanie na bieżąco, statyczna (z góry ustalona) konfiguracja w plikach JSON — prostym, tekstowym formacie zapisu danych — oraz dynamiczne hooks uruchamiane przed każdą operacją. Każda warstwa daje inny poziom kontroli i pasuje do innych sytuacji.
Zanim przejdziemy do konfiguracji, warto zrozumieć model mentalny. Claude Code sprawdza uprawnienia w ściśle określonej kolejności:
permissions.deny w settings.json, jest natychmiast blokowana bez pytania.permissions.allow, jest wykonywana automatycznie bez pytania.0 = przepuść, wartość różna od zera = zablokuj. To uniwersalna konwencja systemów uniksowych: 0 zawsze znaczy „zakończono OK", a każda inna liczba „wystąpił błąd".Wynik: możesz mieć jednocześnie zautomatyzowane zatwierdzanie bezpiecznych operacji (git status, czytanie plików), dynamiczną walidację operacji potencjalnie niebezpiecznych (hooks) i ostateczne pytanie do użytkownika dla wszystkiego co nie zostało skategoryzowane.
Domyślnie Claude Code pyta o pozwolenie przed każdą potencjalnie destrukcyjną operacją: zapisem pliku, wykonaniem komendy bash, połączeniem z zewnętrznym API (interfejsem, przez który programy komunikują się ze sobą). Takie pytanie o zgodę (prompt) wygląda następująco:
Opcje w interaktywnym promptcie:
W środowiskach CI/CD (skrót od Continuous Integration / Continuous Delivery — zautomatyzowane budowanie, testowanie i wdrażanie kodu, np. GitHub Actions czy GitLab CI) albo w izolowanych kontenerach Docker możesz uruchomić Claude Code z flagą:
claude --dangerously-skip-permissions "napraw wszystkie błędy typowania w src/"
Uwaga: flaga --dangerously-skip-permissions wyłącza WSZYSTKIE interaktywne pytania. Używaj jej wyłącznie w izolowanych środowiskach — np. w kontenerze Docker bez podpiętych wrażliwych katalogów albo na jednorazowej, kasowanej zaraz po zadaniu maszynie wirtualnej w systemie CI. Nigdy na maszynie z dostępem do kluczy produkcyjnych, bazy danych czy konta AWS.
Flaga -p / --print uruchamia Claude w trybie jednorazowym (ang. one-shot: jedno zapytanie -> odpowiedź -> zamknięcie programu). W tym trybie brak odpowiedzi na pytanie o uprawnienia = operacja odrzucona. Bezpieczne do skryptowania (uruchamiania w skryptach) bez ryzyka, że proces się zawiesi w oczekiwaniu na odpowiedź.
claude -p "Ile linii kodu ma src/main.py?" --output-format json
Claude Code ładuje konfigurację z czterech lokalizacji w kolejności rosnącego priorytetu:
| Poziom | Lokalizacja | Gitowany? | Kto zarządza | Priorytet |
|---|---|---|---|---|
| Enterprise | plik wdrażany przez MDM/GPO (ścieżka zależna od platformy) | NIE | Dział IT / admin | Najwyższy |
| Global | ~/.claude/settings.json |
NIE | Programista (maszyna) | 2 |
| Project | .claude/settings.json |
TAK | Cały zespół | 3 |
| Local | .claude/settings.local.json |
NIE (gitignore) | Programista (projekt) | Najniższy |
Ustawienia globalne stosują się do WSZYSTKICH projektów na tej maszynie. Dobre miejsce na uprawnienia które dajesz sobie bezwarunkowo (np. czytanie plików, podstawowe komendy git).
// ~/.claude/settings.json — ustawienia globalne maszyny
{
"permissions": {
"allow": [
"Read",
"Bash(git status)",
"Bash(git log *)",
"Bash(git diff *)",
"Bash(git branch *)"
],
"deny": [
"Bash(git push --force *)",
"Bash(git push -f *)",
"Bash(sudo *)"
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
To najważniejszy plik z perspektywy zespołu. Commitowany do repozytorium (czyli zapisany w historii projektu w git i widoczny dla wszystkich), stosuje się do każdego, kto pracuje z projektem. Definiuje zasady specyficzne dla danego projektu — jakie komendy są bezpieczne, a jakie nigdy nie powinny być uruchamiane automatycznie.
// .claude/settings.json — zasady projektowe (commituj do repo!)
{
"permissions": {
"allow": [
"Write",
"Edit",
"Bash(npm *)",
"Bash(npx *)",
"Bash(python -m pytest *)",
"Bash(python -m mypy *)",
"Bash(docker compose up *)",
"Bash(docker compose down)",
"Bash(make *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl * | bash)",
"Bash(wget * | sh)",
"Bash(pip install *)", // tylko przez requirements.txt
"Bash(npm install -g *)", // globalne instalacje zablokowane
"Bash(docker system prune *)"
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Lokalny plik jest niewidoczny dla współpracowników (gitignore). Służy do nadpisań specyficznych dla Twojej maszyny — np. dodatkowe uprawnienia debugowania, lokalne ścieżki, tymczasowe zmiany.
// .claude/settings.local.json — tylko moja maszyna, nie commituj!
{
"permissions": {
"allow": [
"Bash(pip install *)", // lokalnie pozwalam — mam własny venv
"Bash(psql *)", // dostęp do lokalnej bazy
"Bash(./scripts/seed-db.sh)"
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Wskazówka: dodaj .claude/settings.local.json do .gitignore raz na zawsze przez globalny gitignore: echo ".claude/settings.local.json" >> ~/.gitignore_global i git config --global core.excludesfile ~/.gitignore_global.
Bash uprawnienia używają wzorców glob — to prosty sposób dopasowywania tekstu, w którym gwiazdka * zastępuje „dowolny ciąg znaków". To ten sam mechanizm, którego używasz w terminalu pisząc np. ls *.txt, żeby wylistować wszystkie pliki z rozszerzeniem .txt. Tutaj wzorzec porównywany jest z całą komendą potraktowaną jak zwykły tekst. Daje to bardzo dużą precyzję — możesz pozwolić na git commit blokując jednocześnie git push.
| Wzorzec | Dopasowuje | Nie dopasowuje |
|---|---|---|
Bash(git *) |
git status, git log, git commit | npm, docker |
Bash(git commit *) |
git commit -m "msg" | git push, git reset |
Bash(npm test) |
npm test (dokładnie) | npm test -- --watch |
Bash(npm test *) |
npm test, npm test -- --watch | npm install |
Bash(rm *) |
rm plik.txt, rm -rf /! | — |
Pułapka: Bash(rm *) pozwala na rm -rf /. Wzorzec pasuje do całej komendy po rm, więc obejmuje też najbardziej destrukcyjne warianty. Zawsze sprawdź, czy nie dajesz zbyt szerokich uprawnień. Bezpieczniej zawęzić wzorzec — albo do konkretnego rozszerzenia: Bash(rm *.tmp) (tylko pliki .tmp w bieżącym katalogu), albo do konkretnej ścieżki: Bash(rm ./build/*) czy Bash(rm /tmp/cache/*) — wtedy usuwanie jest ograniczone do jednego katalogu i komenda nie sięgnie poza niego.
// Projekt Python (Django/FastAPI)
"allow": [
"Bash(python -m pytest *)",
"Bash(python manage.py *)",
"Bash(python manage.py migrate)",
"Bash(python manage.py makemigrations *)",
"Bash(python -m mypy *)",
"Bash(python -m black *)",
"Bash(python -m ruff *)"
]
// Projekt Node.js / TypeScript
"allow": [
"Bash(npm run *)",
"Bash(npx tsc *)",
"Bash(npx eslint *)",
"Bash(node *)",
"Bash(pnpm *)"
]
// Projekt infrastruktury (Terraform/Ansible)
"allow": [
"Bash(terraform fmt *)",
"Bash(terraform validate)",
"Bash(terraform plan *)"
],
"deny": [
"Bash(terraform apply *)", // ZAWSZE ręcznie!
"Bash(terraform destroy *)"
]
Czym w ogóle jest hook? Wyobraź sobie ochroniarza przy wejściu, który sprawdza każdego gościa, zanim wpuści go do środka — może przepuścić, zawrócić albo po prostu zanotować w zeszycie, kto i kiedy wchodził. Hook robi to samo, tylko wobec operacji Claude'a. Mówiąc technicznie: hook (dosłownie „zaczep", „hak") to Twój własny, krótki program — zwykły plik bash albo Python — który Claude Code uruchamia sam, automatycznie w ściśle określonym momencie. Najczęściej tuż przed tym, jak Claude zamierza użyć jakiegoś narzędzia (wykonać komendę w terminalu, zapisać plik), albo zaraz po tym. Nie musisz o niego prosić za każdym razem ani liczyć, że model „będzie pamiętał" — hook odpala się zawsze, tak samo, przy każdej takiej operacji.
Po co to komu? Listy allow i deny z wcześniejszych sekcji są sztywne: coś jest albo dozwolone, albo nie. Hook pozwala podjąć decyzję na bieżąco, według dowolnej reguły, którą sam napiszesz. Kilka konkretnych przykładów, do czego się przydaje:
prod", nawet jeśli lista allow/deny jej nie przewidziała.To dokładnie ta sama idea, co hooki w git (skrypt uruchamiany np. przed każdym commitem) albo „nasłuchiwacze zdarzeń" znane z aplikacji — kawałek Twojego kodu, który system sam wywołuje w odpowiednim momencie.
Zapamiętaj jedno pojęcie — „kod wyjścia" (ang. exit code). Każdy program po zakończeniu zwraca systemowi jedną liczbę. Reguła jest uniwersalna w całym świecie systemów uniksowych: 0 znaczy „zakończyłem się OK", a każda inna liczba (1, 2, ...) znaczy „coś poszło nie tak / błąd". Hook typu PreToolUse wykorzystuje to jako swoją decyzję: skrypt kończy się kodem 0 = operacja przechodzi; kończy się kodem różnym od zera = operacja zostaje zablokowana. W bash ustawiasz to poleceniem exit 0 lub exit 1, w Pythonie — sys.exit(0) / sys.exit(1).
| Hook | Kiedy | Kod wyjścia ma znaczenie? | Zastosowanie |
|---|---|---|---|
| PreToolUse | Przed wywołaniem narzędzia | TAK — niezerowy = blokada | Walidacja, audyt, warunkowe blokowanie |
| PostToolUse | Po zakończeniu narzędzia | NIE (informacyjny) | Sprawdzanie kodu (linting), testy, powiadomienia, logi |
| Notification | Gdy Claude ma powiadomienie | NIE | Integracja z systemami alertów |
| Stop | Gdy Claude kończy pracę | NIE | Sprzątanie po zadaniu, raporty końcowe |
// .claude/settings.json — konfiguracja hooks
{
"permissions": { /* ... */ },
"hooks": {
"PreToolUse": [
{
"matcher": "Bash", // "Bash", "Write", "Read", "*" (wszystkie)
"hooks": [
{
"type": "command",
"command": ".claude/hooks/check-bash.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/lint-after-write.sh"
}
]
}
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Struktura jest prosta: w sekcji hooks wskazujesz moment (PreToolUse — przed operacją, albo PostToolUse — po niej), a w nim listę reguł. Każda reguła ma matcher (dla którego narzędzia hook ma zadziałać — np. Bash, Write, Read lub * = wszystkie) oraz command (ścieżkę do skryptu, który zostanie uruchomiony).
Każdy hook dostaje na standardowym wejściu (stdin — strumień, którym program przyjmuje dane; w bashu czytasz go przez cat, w Pythonie przez sys.stdin) porcję danych w formacie JSON z pełnym kontekstem wywołania narzędzia. Możesz je odczytać i przetworzyć w bashu lub Pythonie:
# Przykład JSON który hook otrzymuje na stdin (Bash PreToolUse):
{
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf ./build",
"description": "Clean build directory"
},
"session_id": "abc-123",
"tool_use_id": "toolu_xyz"
}
Prosty hook który loguje każdą komendę bash do pliku — przydatny do śledzenia co Claude robił w projekcie:
#!/bin/bash
# .claude/hooks/audit-bash.sh
# Loguje każdą komendę bash wykonywaną przez Claude
AUDIT_FILE=".claude/audit.log"
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['tool_input']['command'])")
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] BASH: $COMMAND" >> "$AUDIT_FILE"
exit 0 # zawsze zezwól — tylko logujemy
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Co ten skrypt robi, linijka po linijce:
INPUT=$(cat) — wczytuje dane, które Claude Code podaje hookowi na wejście (to wspomniany wyżej JSON z opisem operacji).python3 — wyciąga z tego JSON-a samą treść komendy bash (pole tool_input.command).date — pobiera aktualną datę i godzinę, żeby wiedzieć, kiedy operacja się wydarzyła.echo ... >> "$AUDIT_FILE" — dopisuje jedną linię (data + komenda) na koniec pliku .claude/audit.log (>> oznacza „dopisz na końcu", nie „nadpisz").exit 0 — kończy się kodem wyjścia 0, czyli „przepuść". Ten hook niczego nie blokuje — tylko po cichu zapisuje, co się działo.Bardziej zaawansowany hook blokujący konkretne wzorce komend. Zwraca exit code 1 gdy komenda jest potencjalnie niebezpieczna:
#!/usr/bin/env python3
# .claude/hooks/check-dangerous.py
# Blokuje komendy potencjalnie destrukcyjne
import json
import sys
import re
# Wzorce które ZAWSZE wymagają ręcznego zatwierdzenia
DANGEROUS_PATTERNS = [
r"git\s+push\s+.*(--force|-f)",
r"git\s+reset\s+--hard",
r"git\s+clean\s+.*-[fd]",
r"rm\s+.*-[rf].*/",
r"DROP\s+(TABLE|DATABASE)",
r"(curl|wget).*\|\s*(bash|sh)",
]
try:
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
for pattern in DANGEROUS_PATTERNS:
if re.search(pattern, command, re.IGNORECASE):
print(f"ZABLOKOWANO: Komenda pasuje do wzorca '{pattern}'",
file=sys.stderr)
print("Wymagane ręczne zatwierdzenie dla tej operacji.",
file=sys.stderr)
sys.exit(1) # kod wyjścia 1 = Claude Code blokuje operację
except Exception as e:
print(f"Hook error: {e}", file=sys.stderr)
sys.exit(0) # kod wyjścia 0 = operacja dozwolona
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Jak to działa: lista DANGEROUS_PATTERNS zawiera wzorce (tzw. wyrażenia regularne — sposób opisywania „pasujących" fragmentów tekstu) dla komend, których nigdy nie chcemy puścić automatycznie: git push --force, git reset --hard, kasowanie plików przez rm, usuwanie tabel w bazie (DROP TABLE) czy pobieranie i uruchamianie skryptu prosto z internetu (curl ... | bash). Skrypt czyta komendę z wejścia i porównuje ją po kolei z każdym wzorcem:
sys.exit(1) (kod wyjścia różny od zera = blokada, Claude nie wykona operacji);sys.exit(0) na końcu (kod 0 = przepuść).Po każdym zapisie pliku Python uruchom automatycznie linter i testy jednostkowe:
#!/bin/bash
# .claude/hooks/lint-after-write.sh
# Uruchamia linter po każdym zapisie pliku
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import json,sys; print(json.load(sys.stdin)['tool_input'].get('path',''))")
# Tylko pliki Python
if [[ "$FILE_PATH" == *.py ]]; then
echo "Uruchamiam ruff na $FILE_PATH..."
python3 -m ruff check "$FILE_PATH" --fix 2>&1
if [[ "$FILE_PATH" == src/* ]]; then
echo "Uruchamiam testy powiązane..."
python3 -m pytest tests/ -x -q 2>&1 || echo "Testy: sprawdź błędy"
fi
fi
exit 0 # PostToolUse — kod wyjścia bez znaczenia
Jak to działa: ten hook jest typu PostToolUse, czyli uruchamia się po zapisaniu pliku. Wyciąga z danych wejściowych ścieżkę zapisanego pliku i — jeśli to plik Pythona (.py) — automatycznie uruchamia na nim ruff (narzędzie sprawdzające i poprawiające kod, tzw. linter), a dla plików z katalogu src/ dodatkowo odpala testy. Dzięki temu zaraz po każdej zmianie od razu wiadomo, czy kod nadal się „trzyma". W hooku PostToolUse kod wyjścia nie ma już znaczenia — operacja została już wykonana, więc taki hook służy do reakcji po fakcie, a nie do blokowania.
Wskazówka: to, co hook wypisze na standardowe wyjście (stdout), trafia prosto do Claude'a jako dodatkowy kontekst. Możesz więc zwracać z hooka dowolne informacje — wynik sprawdzenia kodu (linting to automatyczna analiza kodu pod kątem błędów i stylu), status testów, ostrzeżenia — a Claude je zobaczy i na ich podstawie skoryguje kolejne kroki.
Claude Code obsługuje serwery MCP (Model Context Protocol — standard, dzięki któremu Claude może korzystać z zewnętrznych narzędzi i źródeł danych, np. przeglądarki, bazy danych czy repozytorium plików). Każdy taki serwer działa jako osobny program i ma własne uprawnienia — możesz je kontrolować przez settings.json.
Spójrzmy na konkretny przykład. Poniższa konfiguracja robi dwie rzeczy naraz: najpierw podłącza dwa serwery MCP (sekcja mcpServers), a następnie — w sekcji permissions — decyduje, z których dokładnie ich narzędzi Claude może korzystać:
// Konfiguracja MCP servers w ~/.claude/settings.json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp"]
},
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/tmp"]
// ograniczamy dostęp tylko do /tmp!
}
},
"permissions": {
"allow": [
"mcp__playwright__browser_navigate",
"mcp__playwright__browser_take_screenshot"
],
"deny": [
"mcp__playwright__browser_evaluate" // blokuj eval JS w przeglądarce
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Co robi ta konfiguracja — sekcja po sekcji:
mcpServers — podłącza dwa serwery MCP: playwright (sterowanie przeglądarką — otwieranie stron, klikanie, robienie zrzutów) oraz filesystem (dostęp do plików), przy czym temu drugiemu z góry ograniczamy zasięg tylko do katalogu /tmp. Same serwery to gotowe paczki uruchamiane poleceniem npx — nie musisz nic pisać samodzielnie.permissions.allow — spośród wszystkich narzędzi, jakie te serwery udostępniają, pozwalamy Claude'owi tylko na dwa: otwieranie strony (browser_navigate) i robienie zrzutu ekranu (browser_take_screenshot).permissions.deny — i jawnie blokujemy jedno konkretne narzędzie: browser_evaluate, które pozwala wykonać dowolny kod JavaScript w przeglądarce (a to potencjalnie groźne).Zwróć uwagę na schemat nazw: każde narzędzie z serwera MCP ma postać mcp__nazwaserwera__nazwanarzędzia. Dzięki temu na listach allow/deny wskazujesz konkretne narzędzie, a nie cały serwer — możesz więc podłączyć serwer, ale udostępnić Claude'owi tylko jego bezpieczną część.
W środowiskach korporacyjnych administrator może definiować polityki które nie mogą być nadpisane przez indywidualnych użytkowników. Takie odgórnie narzucone ustawienia (ang. managed settings) mają absolutny priorytet nad wszystkim innym.
Wdraża się je przez firmowe systemy do centralnego zarządzania komputerami pracowników. Dwa najczęstsze skróty, które tu spotkasz, to MDM i GPO:
W obu przypadkach chodzi o to samo: plik z politykami trafia na komputer pracownika odgórnie, a użytkownik nie może go zmienić ani usunąć.
// Przykład polityki enterprise (wdrożonej przez IT przez MDM/GPO):
// Blokuje wysyłanie kodu do zewnętrznych usług AI i dostęp do sekretów
{
"permissions": {
"deny": [
"Bash(curl *openai.com*)",
"Bash(curl *anthropic.com*)",
"Bash(cat */.env*)",
"Bash(cat *secret*)",
"Bash(aws *)",
"Bash(gcloud *)"
]
}
}
Powyżej to zrzut ekranu — ten sam kod skopiujesz przyciskiem „Kopiuj".
Polityki enterprise wdraża się przez platformowy mechanizm zarządzania (MDM na macOS, GPO/Intune na Windows). Format JSON jest taki sam jak w zwykłym .claude/settings.json — administrator zamraża wybrane klucze, użytkownik nie może ich nadpisać.
Nie ma jednego „właściwego" zestawu uprawnień — dobiera się go do ryzyka danego środowiska. Prosta zasada: im mniej wrażliwych rzeczy Claude może tu zepsuć (sekrety, produkcyjne bazy, infrastruktura), tym luźniej możesz pozwolić mu działać; im wyższa stawka, tym ciaśniej. Poniżej trzy typowe punkty na tej skali.
Dlaczego akurat projekt open-source może mieć luźne uprawnienia? Bo jego kod i tak jest publiczny, w repozytorium nie trzyma się sekretów ani danych produkcyjnych, a Claude nie ma stąd dostępu do żadnej wrażliwej infrastruktury. Najgorsze, co realnie może się zdarzyć, to lokalny bałagan w plikach — a nie wyciek danych czy awaria produkcji. Dlatego można dać modelowi więcej swobody i rzadziej go pytać:
// .claude/settings.json dla projektu open-source
{
"permissions": {
"allow": [
"Read", "Write", "Edit",
"Bash(git *)",
"Bash(npm *)",
"Bash(python *)",
"Bash(make *)",
"Bash(cargo *)",
"Bash(go *)"
],
"deny": [
"Bash(git push --force *)",
"Bash(rm -rf /)",
"Bash(:(){ :|:& };:)" // tzw. fork bomb — komenda zawieszająca system
]
}
}
// .claude/settings.json dla projektu z dostępem do prod infra
{
"permissions": {
"allow": [
"Read",
"Bash(git status)",
"Bash(git log *)",
"Bash(git diff *)",
"Bash(python -m pytest *)",
"Bash(python -m mypy *)"
],
"deny": [
"Bash(git push *)", // push zawsze ręcznie
"Bash(git commit *)", // commit zawsze ręcznie
"Bash(kubectl *)", // k8s - nigdy automatycznie
"Bash(terraform apply *)",
"Bash(terraform destroy *)",
"Bash(aws *)",
"Bash(psql *prod*)", // prod DB off-limits
"Write" // zapis plików też wymaga OK
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{"type": "command", "command": ".claude/hooks/audit-all.sh"}
]
}
]
}
}
# GitHub Actions — Claude Code w CI
name: Claude Code Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Claude review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# --dangerously-skip-permissions BEZPIECZNE w izolowanym, jednorazowym runnerze
claude --dangerously-skip-permissions -p \
"Zrób code review diff'a w tym PR. Sprawdź typy, edge cases, bezpieczeństwo."
"Bash(git push --force *)" i "Bash(git push -f *)" w deny na poziomie globalnym.terraform apply, kubectl delete, aws s3 rm zawsze wymagają ręcznego zatwierdzenia.Uprawnienia, hooks, MCP, sub-agenci i praca w CI/CD — trzy dni ćwiczeń z trenerem. Prowadzi Łukasz Matuszewski. Kurs ma termin gwarantowany.
Szkolenie Claude Code — sprawdź terminy
Komentarze (0)
Brak komentarzy...