Automatyzacja zgodności regulacyjnej
ENAutomatyzacja zgodności regulacyjnej wykorzystuje agenta kodującego do mapowania kontroli SOC 2, HIPAA i RODO (GDPR) na kod, pisania bramek CI, które je egzekwują, oraz generowania skryptów zbierających dowody audytowe. Dowody wytwarzają deterministyczne narzędzia, a podpisuje je wskazany właściciel kontroli; agent pisze kolektory i szkice, ale nigdy nie wytwarza samych dowodów.
W poniedziałek przychodzi lista żądań od audytora: ustawienia ochrony gałęzi za cały okres obserwacji, dowód, że każda zmiana w src/auth/ przeszła code review, lista zależności produkcyjnych z licencjami i opis przepływu danych osobowych objętych RODO. Rok temu zajęło to dwóm inżynierom dwa tygodnie zrzutów ekranu i arkuszy. Ta strona jest dla programisty albo tech leada, który odpowiada za tę listę i chce, żeby następny audyt był ponownym uruchomieniem skryptów, a nie gaszeniem pożaru.
Co dają zautomatyzowane dowody zgodności
Dział zatytułowany „Co dają zautomatyzowane dowody zgodności”- Prompt mapujący kontrolę, który zwraca tabelę luk z cytatami
plik:linia, oraz krótki skrypt odrzucający każdy cytat, który nie istnieje. - Bramkę polityki licencji i bramkę sekretów, które blokują merge (albo własny commit agenta) i przy każdym uruchomieniu zostawiają datowany artefakt.
- Kolektor zarządzania zmianą dla SOC 2 CC8.1, który czyta zatwierdzenia z GitHuba, a nie z
git log. - Szkic rejestru przepływu danych RODO i kontrolę pokrycia żądań DSAR zbudowane na żywym schemacie bazy.
- Zaplanowane zadanie, które co tydzień regeneruje dowody, oraz regułę podpisu określającą, kto za nie odpowiada.
Jeśli dopiero decydujesz, jakie dane w ogóle mogą trafić do agenta, zacznij od strony prywatność danych i polityki firmowe dla agentów kodujących. Jeśli pracujesz w finansach, ochronie zdrowia albo sektorze publicznym, przeczytaj o inżynierii agentowej w branżach regulowanych, gdzie omówiony jest podział obowiązków. Ta strona zakłada, że obie sprawy są już rozstrzygnięte.
Kto co robi w compliance-as-code?
Dział zatytułowany „Kto co robi w compliance-as-code?”Compliance-as-code zamienia każdą kontrolę w sprawdzenie uruchamiane przy każdej zmianie, więc dowody gromadzą się przy okazji dostarczania kodu. Agent szybko robi to, co jest żmudne do napisania, a błędy w tym łatwo przeoczyć. Właśnie dlatego nie może mieć ostatniego słowa.
| Warstwa | Zadanie agenta | Co to uruchamia | Jaki dowód zostaje |
|---|---|---|---|
| Mapowanie kontroli | Szkic tabeli luk z cytatami | Ty, raz na kwartał dla każdej kontroli | Tabela luk (JSON) i log sprawdzenia cytatów |
| Hook agenta | Napisanie konfiguracji hooka | Claude Code, gdy agent uruchamia git commit | Komunikat o blokadzie od skanera (tylko lokalnie) |
| Pre-commit | Napisanie .pre-commit-config.yaml | git commit każdego programisty | Żaden (tylko lokalnie), więc nigdy nie polegaj na nim samym |
| Bramka CI | Napisanie workflow i skryptów pomocniczych | GitHub Actions przy każdym pull requeście | Log zadania i artefakt z każdego uruchomienia |
| Kolektor dowodów | Napisanie skryptu | Zaplanowane zadanie, deterministycznie | Datowany JSON z API systemu źródłowego |
| Narracja | Szkic tekstu i diagramów na podstawie JSON | Ty recenzujesz, właściciel kontroli podpisuje | Podpisany dokument cytujący JSON |
Czytaj tabelę od góry do dołu jako kolejność budowania. Narracja bez kolektorów pod spodem to opowieść, a nie dowód.
Zmapuj jedną kontrolę na kod z cytatami plik:linia
Dział zatytułowany „Zmapuj jedną kontrolę na kod z cytatami plik:linia”Zacznij od jednej kontroli, nie od całego frameworka. SOC 2 CC6.1 (dostęp logiczny) to dobry pierwszy wybór, bo większość dowodów już leży w repozytorium: middleware uwierzytelniania, sprawdzenia autoryzacji, polityki IAM w Terraformie i obsługa sekretów.
Zapisz ten prompt jako .compliance/prompts/cc6.1.md.
Cała wartość tkwi w regule „Met tylko z cytatem”. Prompt o zgodność to miejsce, w którym model najchętniej zwraca schludną odpowiedź „wszystko spełnione”. Wymóg cytatów zamienia taką odpowiedź w coś, co może sprawdzić skrypt.
Uruchom go w trybie headless (nieinteraktywnie) i tylko do odczytu. --allowedTools jedynie automatycznie zatwierdza wymienione narzędzia, ale nie usuwa pozostałych. --tools usuwa z sesji wszystkie inne wbudowane narzędzia, więc nie zostaje żadne, które mogłoby pytać o zgodę. --strict-mcp-config nie wpuszcza do sesji skonfigurowanych serwerów MCP. --json-schema razem z --output-format json sprawdza odpowiedź względem schematu z karty Codex (zapisz go jako .compliance/gap.schema.json) i zwraca ją w polu structured_output (wszystko sprawdzone w Claude Code 2.1.283).
mkdir -p evidenceclaude -p "$(cat .compliance/prompts/cc6.1.md)" \ --tools "Read,Grep,Glob" --allowedTools "Read,Grep,Glob" \ --strict-mcp-config \ --output-format json --json-schema "$(cat .compliance/gap.schema.json)" \ | jq -e '.structured_output' > evidence/cc6.1-gap.json # exits 1 if no validated objectcodex exec przyjmuje JSON Schema i zapisuje ostatnią wiadomość do pliku. Profil uprawnień :read-only (beta) chroni drzewo robocze przed zmianami. Zapisz poniższy schemat jako .compliance/gap.schema.json. Schemat nie wymaga co najmniej jednego cytatu w wierszu „Met”, bo to zależy od status; pilnuje tego skrypt cytatów.
mkdir -p evidencecodex exec -c default_permissions=":read-only" \ --output-schema .compliance/gap.schema.json \ -o evidence/cc6.1-gap.json "$(cat .compliance/prompts/cc6.1.md)"{ "type": "object", "additionalProperties": false, "required": ["control", "requirements"], "properties": { "control": { "type": "string" }, "requirements": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["requirement", "status", "evidence", "remediation"], "properties": { "requirement": { "type": "string" }, "status": { "type": "string", "enum": ["Met", "Partial", "Gap"] }, "evidence": { "type": "array", "items": { "type": "string" } }, "remediation": { "type": "string" } } } } }}Otwórz repozytorium, przełącz agenta w Plan Mode, żeby czytał bez edytowania, i wklej prompt. Odpowiedź JSON zapisz samodzielnie do evidence/cc6.1-gap.json. Sprawdzenie cytatów poniżej działa tak samo na wyniku z Cursora.
Teraz sprawdź każdy cytat mechanicznie, zamiast czytać tabelę. Zapisz to jako scripts/compliance/check-citations.sh i uruchamiaj z katalogu głównego repozytorium. Skrypt wymaga basha, bo czyta z podstawienia procesu; potok jq … | while ustawiałby broken w podpowłoce i zawsze kończył się kodem 0.
#!/usr/bin/env bash# scripts/compliance/check-citations.sh <file.json> [jq filter]# Exits 1 on any citation that is not an existing file plus one line number.filter="${2:-.requirements[] | select(.status==\"Met\") | .evidence[]}"jq empty "$1" || exit 1# The loop only sees citations that exist, so reject a "Met" row with none first.if [ -z "$2" ]; then jq -e 'all(.requirements[]; .status != "Met" or (.evidence | length > 0))' "$1" >/dev/null \ || { echo 'MET WITHOUT CITATION'; exit 1; }fibroken=0while IFS=: read -r file line; do case "$line" in ''|*[!0-9]*) echo "BROKEN CITATION (no single line number): $file:$line"; broken=1; continue ;; esac if [ ! -f "$file" ] || [ "$line" -lt 1 ] || [ "$line" -gt "$(awk 'END{print NR}' "$file")" ]; then echo "BROKEN CITATION: $file:$line"; broken=1 fidone < <(jq -r "$filter" "$1")exit "$broken"Zanim mu zaufasz, dopisz do kopii JSON-a jeden fałszywy cytat (src/nope.ts:1) i potwierdź, że skrypt wypisuje BROKEN CITATION i kończy się kodem 1. Cytat bez pojedynczego numeru linii, na przykład file.ts albo file.ts:42-50, również nie przechodzi, podobnie jak wiersz „Met” z pustą tablicą evidence (MET WITHOUT CITATION). Liczbę linii podaje awk, a nie wc -l, bo wc -l liczy znaki nowej linii i odrzuciłby cytat ostatniej linii pliku, który nie kończy się znakiem nowej linii.
Jeden błędny cytat oznacza, że cała tabela jest niewiarygodna: wyrzuć ją i uruchom ponownie, nie poprawiaj pojedynczego wiersza. Gdy wszystkie cytaty się zgadzają, otwórz trzy losowe wiersze „Met” i sprawdź, czy wskazana linia rzeczywiście realizuje wymaganie. Twoim przeglądem jest ta próbka, a nie lektura całości.
Podłącz bramki, które zostawiają dowód przy każdym uruchomieniu
Dział zatytułowany „Podłącz bramki, które zostawiają dowód przy każdym uruchomieniu”Bramka jest lepszym dowodem niż raport, bo działa przy każdej zmianie przez cały okres obserwacji. Najszybciej zwracają się dwie: licencje zależności i sekrety. Skanowanie sekretów gitleaks, Semgrep i Trivy opisuje szczegółowo strona o automatyzacji operacji bezpieczeństwa; ta sekcja dodaje bramkę licencji i sprawia, że obie zostawiają artefakty, z których audytor może pobrać próbkę.
Wynik powinien wyglądać tak. Porównaj go z promptem, zamiast mu ufać:
name: license-policyon: pull_request:permissions: contents: readjobs: licenses: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-node@v7 with: node-version: 22 - run: npm ci --ignore-scripts - name: Write the license report (always) run: > npx --yes license-checker-rseidelsohn@5 --production --excludePrivatePackages --json --out license-report.json - name: Enforce the allowlist (the gate) run: > npx --yes license-checker-rseidelsohn@5 --production --excludePrivatePackages --onlyAllow "MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD" - if: always() uses: actions/upload-artifact@v7 with: name: license-report path: license-report.json retention-days: 90Używaj listy dozwolonych licencji (--onlyAllow), a nie listy zakazanych (--failOn). Lista zakazanych z GPL-3.0 przepuści GPL-3.0-only, GPL-3.0-or-later i każdy ciąg licencji wpisany ręcznie przez opiekuna pakietu. Lista dozwolonych odrzuca wszystko nieznane, a to bezpieczny kierunek: decyzję podejmuje wtedy człowiek i zapisuje wyjątek.
Raport i bramka to osobne kroki, bo --onlyAllow kończy działanie przy pierwszej niedozwolonej licencji, więc jeden połączony krok może w ogóle nie zapisać license-report.json, a audytor pobiera próbki właśnie z nieudanych uruchomień. Ustaw bramkę jako wymaganą w ochronie gałęzi, a zanim zaczniesz na niej polegać, udowodnij, że działa: otwórz testowy pull request dodający jeden pakiet spoza listy i potwierdź, że sprawdzenie zmienia się na czerwone.
Nie pozwól agentowi zacommitować naruszenia
Dział zatytułowany „Nie pozwól agentowi zacommitować naruszenia”CI łapie naruszenie po wypchnięciu. Hook łapie je, zanim w ogóle powstanie. Warstwy różnią się między narzędziami, więc skonfiguruj tę, której używa twój zespół, a wspólną konfigurację pre-commit utrzymuj dla wszystkich.
Hook PreToolUse z warunkiem if uruchamia się tylko wtedy, gdy agent próbuje wykonać git commit. Dodaj go do .claude/settings.json:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "if": "Bash(git commit *)", "command": "gitleaks git --staged --redact --exit-code 2" } ] } ] }}--exit-code 2 jest tu kluczowe. Claude Code blokuje wywołanie narzędzia tylko przy kodzie wyjścia 2. gitleaks po znalezieniu wycieku domyślnie kończy się kodem 1, który Claude Code traktuje jako błąd nieblokujący, więc commit by przeszedł.
Najpierw zainstaluj gitleaks na każdej maszynie: brakujący plik wykonywalny kończy się kodem 127, który niczego nie blokuje. Hook skanuje to, co jest w poczekalni (staged) przed uruchomieniem polecenia, więc git add -A && git commit w jednym wywołaniu go omija; dlatego kontrolą pozostaje bramka CI.
Wzorzec pasuje tylko do zapisu, który wymienia, więc git -C . commit przez niego przejdzie, a dokumentacja hooków nazywa filtr if rozwiązaniem typu best-effort; traktuj ten hook jako wczesne ostrzeżenie. Kontrolą pozostaje wymagana bramka CI.
Użyj wspólnego frameworka pre-commit (następny blok): uruchamia się przy każdym git commit, także przy tych, które Codex robi w swoim sandboksie, i nie wymaga konfiguracji dla każdego narzędzia osobno. Codex ma też własne hooki, ale wymagają one utrwalonego zaufania na każdej maszynie, więc to konfiguracja pre-commit jest przenośną warstwą, na której warto się ustandaryzować.
Użyj wspólnego frameworka pre-commit (następny blok). Cursor ma własne hooki (JSON przez stdio), ale konfiguracja pre-commit łapie commity z agenta, z terminala i z panelu Source Control, więc to na niej warto się ustandaryzować.
Wspólną warstwą dla każdego autora zmian, człowieka czy agenta, jest .pre-commit-config.yaml:
repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.30.1 hooks: - id: gitleaksW każdym klonie uruchom raz pre-commit install. Hooki pre-commit trzeba włączyć w każdym klonie, a każdy może je pominąć przez --no-verify. Zmniejszają szum w CI, ale nie są kontrolą. Kontrolą jest bramka CI i tylko jej uruchomienia możesz pokazać audytorowi.
Zbieraj ścieżkę audytową zarządzania zmianą z GitHuba, a nie z git log
Dział zatytułowany „Zbieraj ścieżkę audytową zarządzania zmianą z GitHuba, a nie z git log”SOC 2 CC8.1 pyta, czy zmiany były autoryzowane, zrecenzowane i przetestowane. git log na to nie odpowie: nie zapisuje, kto zatwierdził pull request, czy recenzja została unieważniona (dismissed) ani czy wymagane sprawdzenia przeszły. Te dane są w GitHubie. Daj agentowi dostęp tylko do odczytu przez serwer GitHub MCP, korzystając z endpointu /readonly, dzięki czemu żadne narzędzie zapisujące nie jest nawet oferowane.
claude mcp add --transport http github-ro https://api.githubcopilot.com/mcp/readonly \ -H "Authorization: Bearer $GITHUB_PAT"codex mcp add github-ro --url https://api.githubcopilot.com/mcp/readonly \ --bearer-token-env-var GITHUB_PATDodaj do .cursor/mcp.json serwer z adresem https://api.githubcopilot.com/mcp/readonly i tokenem przesyłanym w nagłówku Authorization: Bearer. Dokładny JSON znajdziesz na stronie o GitHub MCP.
Powłoka rozwija $GITHUB_PAT, zanim Claude Code go zobaczy, więc token trafia jawnym tekstem do konfiguracji MCP Claude Code. Użyj tokena krótkotrwałego albo umieść serwer w .mcp.json z "Authorization": "Bearer ${GITHUB_PAT}", które Claude Code rozwija ze zmiennych środowiskowych przy starcie; dokładny JSON jest na stronie o GitHub MCP. W obu przypadkach użyj tokena fine-grained ograniczonego do audytowanych repozytoriów, z uprawnieniami tylko do odczytu. Po podłączeniu serwera ten sam prompt działa we wszystkich trzech narzędziach.
Raport to szkic dla człowieka. Dowodem, który zachowuje audytor, są surowe dane, a te powinny pochodzić ze skryptu, który uruchomisz ponownie rano w dniu audytu, a nie z transkryptu czatu. Poproś agenta, żeby napisał ten skrypt raz:
Zrecenzuj kolektor jak każdy skrypt istotny dla bezpieczeństwa: sprawdź, czy każda ścieżka gh api istnieje, czy nic nie loguje tokena i czy warunek wyjścia odpowiada twojej polityce. Potem uruchom go raz i porównaj JSON ze stroną ochrony gałęzi w interfejsie GitHuba. Odczyt ochrony gałęzi wymaga tokena z uprawnieniem administration read do repozytorium i to najczęstsza przyczyna pierwszego niepowodzenia.
Przygotuj rejestr przepływu danych RODO i pokrycie DSAR z żywego schematu
Dział zatytułowany „Przygotuj rejestr przepływu danych RODO i pokrycie DSAR z żywego schematu”Art. 30 RODO wymaga rejestru czynności przetwarzania, a art. 15 i 17 dają osobom, których dane dotyczą, prawo dostępu do danych i ich usunięcia. Jedno i drugie psuje się po cichu, gdy pojawia się nowa tabela albo nowe SDK zewnętrznego dostawcy. Agent prześledzi pola z danymi osobowymi w kodzie szybciej niż ty grepem, pod warunkiem że czyta prawdziwy schemat i oznacza to, czego nie potrafi prześledzić.
Podłącz serwer MCP bazy danych z rolą bazodanową tylko do odczytu (opcje opisuje strona o serwerach MCP dla baz danych). Nie używaj zarchiwizowanego pakietu referencyjnego @modelcontextprotocol/server-postgres: jego wpis w npm jest oznaczony jako deprecated (sprawdzone 2026-09-26).
W przypadku HIPAA uruchom ten sam prompt dla chronionych informacji zdrowotnych (PHI) zamiast danych osobowych i dodaj do każdego przepływu jedno pytanie: czy dostęp jest logowany z użytkownikiem i czasem? To wiąże każdy przepływ z zabezpieczeniami kontroli audytu (audit controls) i kontroli dostępu (access control) z 45 CFR 164.312.
Znacznik NEEDS REVIEW to zawór bezpieczeństwa: wskazuje dokładnie to, co inspektor ochrony danych musi domknąć ręcznie. Następnie zamień tę samą analizę w stałe sprawdzenie, bo handler DSAR, który pomija jeden magazyn danych, nie realizuje żądania dostępu i nie zgłasza przy tym żadnego błędu:
Uruchamiaj go według harmonogramu i zapisuj odpowiedź jako evidence/dsar.json. Pierwsze polecenie oznacza zadanie jako nieudane, gdy którakolwiek wartość export lub erasure wynosi null albo gdy tablica jest pusta, bo all na pustym zbiorze zwraca prawdę; drugie przekazuje skryptowi cytatów filtr dopasowany do kształtu DSAR, bo domyślny czyta .requirements[] i nie znalazłby niczego do sprawdzenia:
jq -e 'length > 0 and all(.[]; .export != null and .erasure != null)' evidence/dsar.jsonscripts/compliance/check-citations.sh evidence/dsar.json \ '.[] | .export, .erasure | select(. != null)'Ścieżka usuwania jest destrukcyjna, więc trafia do kodu wyłącznie przez zrecenzowany pull request z testami na bazie z danymi testowymi, nigdy prosto z sesji agenta.
Zaplanuj cykliczne zbieranie dowodów
Dział zatytułowany „Zaplanuj cykliczne zbieranie dowodów”Ciągłe dowody oznaczają, że kolektory działają według kalendarza, a nie w tygodniu przed audytem. Zaplanowany workflow uruchamia się z gałęzi domyślnej, więc wykonuje tylko zrecenzowany kod. Ręczne uruchomienie przez workflow_dispatch już nie: każdy z prawem zapisu może je wywołać z dowolnej gałęzi i dostałoby ono oba sekrety. Warunek if na poziomie zadania ogranicza także ręczne uruchomienia do gałęzi domyślnej; zastąp main nazwą swojej. Ręczne uruchomienie czyta jednak plik workflow z gałęzi, z której je wywołano, więc ta gałąź może ten if usunąć, a gałąź, która doda wyzwalacz push, też dostanie sekrety repozytorium. Twardą gwarancję daje dopiero umieszczenie obu sekretów w środowisku (environment), którego gałęzie wdrożeń są ograniczone do domyślnej, i dodanie do zadania environment: z jego nazwą. Krok agenta zostaw tylko do odczytu i pozwól, żeby dowód wytwarzał deterministyczny kolektor, który agent jedynie streszcza.
CLI agenta jest przypięte do konkretnej wersji (2.1.283, kanał latest 26.09.2026), więc każde cotygodniowe uruchomienie korzysta z tego samego, zrecenzowanego pliku binarnego; podbijaj ją w pull requeście, jak każdą inną zależność.
name: weekly-compliance-evidenceon: schedule: - cron: '17 6 * * 1' workflow_dispatch:permissions: contents: readjobs: evidence: if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - name: Collect raw evidence (deterministic) env: GH_TOKEN: ${{ secrets.EVIDENCE_READ_TOKEN }} run: node scripts/compliance/evidence-collect.mjs - name: Draft the weekly summary (read-only agent) if: always() env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | npx --yes @anthropic-ai/claude-code@2.1.283 -p \ "Read evidence/change-management-*.json. Summarize CC8.1 exceptions: PRs without approval, disabled protections, failed required checks. Cite the PR number for every exception. Do not restate anything that is not in the JSON." \ --tools "Read,Glob" --allowedTools "Read,Glob" --strict-mcp-config \ > evidence/cc8.1-summary.md - if: always() uses: actions/upload-artifact@v7 with: name: compliance-evidence path: evidence/ retention-days: 90Kroki streszczenia i wysyłki artefaktu mają if: always(), bo kolektor kończy się kodem 1, gdy znajdzie wyjątek. Bez tego warunku nieudany kolektor pomija oba kroki, więc uruchomienia, które rejestrują wyjątek, a to właśnie je audytor bierze do próbki, nie zostawiłyby żadnego artefaktu.
Zastąp krok streszczenia akcją Codex dla GitHuba, trzymaj prompt w repozytorium i uruchamiaj go z profilem uprawnień :read-only:
- name: Draft the weekly summary (read-only agent) if: always() uses: openai/codex-action@v1 with: openai-api-key: ${{ secrets.OPENAI_API_KEY }} permission-profile: ":read-only" prompt-file: .compliance/prompts/cc8.1-summary.md output-file: evidence/cc8.1-summary.mdZapisz prompt streszczenia z karty Claude Code jako .compliance/prompts/cc8.1-summary.md. Zachowaj warunek if na poziomie zadania oraz if: always() przy tym kroku i przy wysyłce artefaktu, z tych samych powodów co w karcie Claude Code.
Akcja domyślnie odbiera uprawnienia sudo (safety-strategy: drop-sudo), więc każdy krok wymagający roota umieść przed nią. Na wielokrotnie używanym runnerze self-hosted zrób z niej ostatni krok zadania, a artefakt wyślij w kolejnym zadaniu, bo zmiana sudo przetrwa koniec zadania.
Utwórz zaplanowaną automatyzację (Automation w Cursorze), która uruchamia Cloud Agenta z promptem streszczenia i otwiera pull request dodający streszczenie w evidence/. Deterministyczny kolektor zostaw w GitHub Actions: Cloud Agent pisze tekst, a zapisem jest uruchomienie w Actions.
Artefakty Actions wygasają zgodnie z ustawieniem retencji, które zwykle jest krótsze niż okres obserwacji. Kopiuj folder evidence/ z każdego uruchomienia do magazynu, do którego audytor ma dostęp, a którego nikt nie może nadpisać, na przykład do bucketu z object lock. Telemetrię agentów przechowuj przez ten sam okres: strona o obserwowalności agentów opisuje logi audytowe tego, co robił sam agent.
Skąd wiesz, że dowody są poprawne, bez czytania całości?
Dział zatytułowany „Skąd wiesz, że dowody są poprawne, bez czytania całości?”Pipeline weryfikujesz raz, a wynik sprawdzasz próbkowaniem. Każde sprawdzenie poniżej łapie konkretny błąd i żadne nie wymaga czytania całego raportu.
| Sprawdzenie | Co łapie | Kiedy |
|---|---|---|
jq empty na każdym wyniku JSON | Tekst albo ucięcie wokół danych | Przy każdym uruchomieniu |
| Skrypt sprawdzający cytaty | Wymyślone pliki i numery linii | Przy każdym uruchomieniu |
| Trzy losowe wiersze „Met” otwarte ręcznie | Prawdziwy plik, zła treść | Co kwartał, dla każdej kontroli |
Podrzucone naruszenie (zła licencja, fałszywy klucz, fałszywy cytat, wiersz „Met” z pustym evidence; każde musi dać kod 1) | Bramka, która nigdy nie zadziała | Po każdej zmianie bramki |
| Diff z JSON z poprzedniego kwartału | Cichy spadek pokrycia | Co kwartał |
| Wynik kolektora porównany z interfejsem GitHuba | Zły endpoint API albo uprawnienia | Raz, potem po zmianach |
| Podpis właściciela kontroli pod narracją | Brak osoby odpowiedzialnej za twierdzenie | Przy każdym audycie |
Reguła podpisu nie jest opcjonalna. Za każdą kontrolę odpowiada wskazany z imienia i nazwiska właściciel: agent pisze szkic, właściciel podpisuje. Dokładnie tę granicę postawi też twój audytor.
Kiedy automatyzacja zgodności zawodzi
Dział zatytułowany „Kiedy automatyzacja zgodności zawodzi”Agent oznacza kontrolę jako „Met” bez prawdziwego dowodu. Objaw: sprawdzenie cytatów wypisuje BROKEN CITATION albo MET WITHOUT CITATION. Wyjście: wyrzuć całą tabelę, zaostrz prompt („jeśli nie możesz zacytować linii, status to Partial”) i uruchom ponownie. Tabeli z jednym wymyślonym cytatem nie da się ufać wiersz po wierszu.
Hook nigdy nie blokuje. Objaw: agent commituje dodany testowy klucz i nic się nie dzieje. Przyczyna: skaner kończy się kodem 1, a Claude Code blokuje tylko przy kodzie 2. Wyjście: dodaj --exit-code 2 i powtórz test z podrzuconym kluczem.
Bramka licencji przepuszcza pakiet copyleft. Przyczyna: lista zakazanych, na której brakuje dokładnego wariantu SPDX, albo pakiet z ręcznie wpisanym ciągiem licencji. Wyjście: przejdź na --onlyAllow, zapisuj każdy wyjątek w repozytorium z nazwiskiem recenzenta i przeglądaj listę wyjątków co kwartał.
Kolektor zgłasza brak ochrony gałęzi. Przyczyna: token nie ma uprawnienia administration read; API odpowiada wtedy 404, co naiwny skrypt odczytuje jako „brak ochrony”. Wyjście: popraw zakres tokena, uruchom ponownie i porównaj z interfejsem, zanim uwierzysz w jakikolwiek wynik „brak”.
Ścieżka audytowa ma dziury. Przyczyna: ktoś z uprawnieniami administratora wypchnął zmiany prosto na main albo obszedł ochronę. Wyjście: włącz „Do not allow bypassing the above settings” (albo odpowiednik w rulesetach), a lukę opisz w raporcie zamiast ją ukrywać. Audytorzy znacznie lepiej traktują ujawniony i wyjaśniony wyjątek niż taki, który sami odkryją.
Wygenerowany dokument ujawnia prawdziwy sekret albo dane osobowe. Przyczyna: agent zacytował wartości wierszy albo konfigurację. Wyjście: każdy prompt na tej stronie prosi o nazwy, a nie wartości; trzymaj się tej zasady, skanuj evidence/ gitleaksem przed wysłaniem i rotuj wszystko, co wyciekło.
Tekst polityki i automatyzacja się rozjeżdżają. Objaw: polityka mówi, że poświadczenia są rotowane co 90 dni, a zadanie rotacji działa co 180. Wyjście: niech kolektor porównuje skonfigurowany harmonogram z polityką na piśmie i kończy się błędem przy niezgodności, zamiast powtarzać treść polityki.
Przepisy zmieniają się pod regułami. Wyjście: nadaj każdej regule identyfikator kontroli i datę przeglądu w nagłówku, a w kalendarzu właściciela kontroli umieść kwartalne zadanie przeglądu reguł względem aktualnego tekstu. O unijnych regulacjach, które obejmują już zespoły tworzące oprogramowanie, przeczytasz na stronie o CRA, NIS2 i DORA-EU.