Przejdź do głównej zawartości

Operacje bezpieczeństwa z AI

Snyk właśnie oznaczył 14 „krytycznych” CVE w drzewie zależności. Jedenaście dotyczy pakietów wyłącznie deweloperskich, które nigdy nie trafiają na produkcję, dwa są nieosiągalne z jakiejkolwiek ścieżki kodu, którą faktycznie wywołujesz, a ten jeden, który ma znaczenie, leży pogrzebany na samym dole raportu. Twój release jest zablokowany, bo znów segregujesz wszystko ręcznie. Obietnica „bezpieczeństwa z AI” rzadko oznacza nowy skaner — to asystent, który czyta wynik skanera tak, jak zrobiłby to starszy inżynier: oddziela realne, możliwe do wykorzystania podatności od szumu i zamienia te prawdziwe w zrecenzowane pull requesty, zamiast w 200-liniowy zrzut JSON, którego nikt nie otwiera.

Ten przewodnik buduje taką pętlę z narzędzi, które istnieją już dziś — Semgrep, npm audit, detect-secrets, Trivy i serwer GitHub MCP — sterowanych z Cursora, Claude Code lub Codex.

  • Prompt do segregacji, który zamienia surowy zrzut z semgrep --config=auto w uszeregowane wyniki „możliwe do wykorzystania vs fałszywy alarm” wraz z minimalnymi poprawkami
  • Prompt do CVE w zależnościach, który czyta npm audit --json i mówi, które CVE są naprawdę osiągalne w Twoim kodzie
  • Prompt do rotacji sekretów na wypadek, gdy detect-secrets znajdzie żywe poświadczenie w historii
  • Mechanikę poszczególnych narzędzi do uruchamiania tej pętli w Cursorze (tryb agenta + MCP), Claude Code (bezgłowy -p w CI + hooki) i Codex (automatyzacja w chmurze + GitHub)
  • Zadanie CI, które uruchamia krok skan-i-segregacja na każdym PR i kończy się błędem przy naprawdę nowych wynikach o wysokiej istotności

Błąd, który popełnia większość zespołów, to podłączenie AI tak, by zastąpiło skaner. Skaner (Semgrep, CodeQL, Trivy) jest deterministyczny, szybki i audytowalny — zostaw go. Zadaniem AI jest ta kosztowna część, którą obecnie wykonuje człowiek: czytanie wyników, eliminowanie fałszywych alarmów i proponowanie najmniejszej poprawnej poprawki. Pętla ma trzy kroki.

  1. Uruchom deterministyczne skanery i przechwyć wynik czytelny dla maszyny. To są prawdziwe komendy, nie prompty — wklej je do terminala:

    Okno terminala
    # Analiza statyczna (reguły z rejestru)
    semgrep --config=auto --json --output semgrep.json .
    # CVE w zależnościach
    npm audit --json > audit.json
    # Sekrety w drzewie roboczym + historii
    detect-secrets scan --all-files > secrets.json
    # Obraz kontenera (jeśli go dostarczasz)
    trivy image --format json --output trivy.json myapp:latest

    semgrep instalujesz przez pip install semgrep lub brew install semgrep; detect-secrets przez pip install detect-secrets; trivy przez brew install trivy lub jego skrypt instalacyjny. Żadne z nich nie są pakietami npm — nie rób npm install.

  2. Przekaż wynik do AI w celu segregacji. Tu leży właściwa wartość. Skaner mówi „potencjalne wstrzyknięcie SQL w db.ts:42”; asystent mówi, czy db.ts:42 jest osiągalne z niezaufanego wejścia, czy też jest zapytaniem parametryzowanym, które reguła błędnie oznaczyła. Użyj promptu do segregacji poniżej.

  3. Zamień prawdziwe wyniki w zrecenzowany PR — nigdy w automatycznie scalany. Pozwól AI naszkicować poprawkę i treść PR, ale zatwierdza ją człowiek (lub wymagana bramka CI). Automatyczne stosowanie poprawek AI w pliku wrażliwym na bezpieczeństwo to przepis na wprowadzenie regresji z zielonym ptaszkiem.

Mechanika kroków 2 i 3 różni się między narzędziami. Komendy skanerów z kroku 1 są wszędzie identyczne.

Otwórz repozytorium w Cursorze, uruchom skanery, by semgrep.json / audit.json znalazły się w przestrzeni roboczej, a następnie przejdź do trybu agenta (Cmd/Ctrl+I). Tryb agenta potrafi czytać pliki JSON bezpośrednio i edytować oznaczone pliki źródłowe w miejscu, pokazując każdą zmianę jako punkt kontrolny, który akceptujesz albo odrzucasz.

Dodaj serwer GitHub MCP, by agent mógł otworzyć PR z naprawą bez wychodzenia z edytora. W ustawieniach MCP Cursora (lub w .cursor/mcp.json) zarejestruj oficjalny zdalny serwer:

{
"mcpServers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer ${GITHUB_PAT}" }
}
}
}

Teraz agent czyta semgrep.json, poprawia dwa prawdziwe wyniki i wywołuje narzędzie create_pull_request z GitHub MCP — wszystko z jednego promptu.

To są przepisy. Zakładają, że masz już przechwycony JSON ze skanerów, tak jak opisano powyżej.

Dwie opcje rozszerzalności zmieniają ten przepływ pracy i nie są wymienne.

  • Serwer GitHub MCP (github/github-mcp-server, zdalnie pod https://api.githubcopilot.com/mcp/) to trwałe połączenie: pozwala agentowi przeszukiwać kod w całej organizacji, czytać alerty Dependabota / skanowania sekretów i otwierać PR z naprawą. Sięgaj po niego, gdy agent musi wielokrotnie działać na GitHubie. Nie istnieje warstwa ułatwiająca w stylu @anthropic/* ani jednostringowe new MCPClient('github') — MCP to connect(transport), a potem callTool({ name, arguments }). Jeśli skryptujesz bezpośrednio na SDK, pakiet to @modelcontextprotocol/sdk, a klient mieszka pod @modelcontextprotocol/sdk/client/index.js.
  • Umiejętność Semgrep (semgrep/skills, instalowana przez npx skills add semgrep/skills) to lżejsza opcja: uczy agenta, jak pisać własne reguły Semgrep dla Twojego kodu i uruchamiać skany, bez stawiania serwera. Sięgaj po umiejętność, gdy zadaniem jest „napisz i uruchom reguły”; sięgaj po serwer MCP, gdy zadaniem jest „operuj na GitHubie”.

Jeśli dostarczasz na Kubernetes, AI może naszkicować Twoją politykę dopuszczania — ale musi naszkicować tę aktualną. PodSecurityPolicy (policy/v1beta1) zostało usunięte w Kubernetes 1.25 i nie istnieje na żadnym wspieranym klastrze. Wspieranym następcą jest Pod Security Admission poprzez etykiety przestrzeni nazw, w parze z NetworkPolicy do izolacji ruchu.

# przestrzeń nazw z egzekwowanymi Pod Security Standards (zastępuje PodSecurityPolicy)
apiVersion: v1
kind: Namespace
metadata:
name: payments
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/warn: restricted
---
# domyślne odrzucanie ruchu wyjściowego/wejściowego, potem zezwól tylko na to, co potrzebne
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payments-isolation
namespace: payments
spec:
podSelector:
matchLabels:
app: payments-api
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels: { app: api-gateway }
ports:
- { protocol: TCP, port: 8443 }
egress:
- to:
- podSelector:
matchLabels: { app: postgres }
ports:
- { protocol: TCP, port: 5432 }

Uruchamiaj deterministyczne skanery na każdym PR, a potem segregację AI jako krok doradczy. Twarda bramka pozostaje deterministyczna — pipeline kończy się błędem przy naprawdę nowych wynikach o wysokiej istotności z Semgrep/Trivy, a nie na podstawie opinii AI. Zwróć uwagę na actions/checkout@v5 (Node 24; runnery v3 są wycofane z końcem czerwca 2026).

.github/workflows/security-scan.yml
name: Security Scan
on:
pull_request:
schedule:
- cron: '0 */6 * * *'
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Semgrep (hard gate on new high-severity)
uses: semgrep/semgrep-action@v1
with:
config: auto
- name: Dependency audit
run: npm audit --audit-level=high
- name: Secret scan
run: |
pipx install detect-secrets
detect-secrets scan --all-files | tee secrets.json
# Doradczo: podsumowanie segregacji AI wpisane do PR, nie blokada
- name: AI triage (advisory)
if: github.event_name == 'pull_request'
run: |
semgrep --config=auto --json --output semgrep.json . || true
claude -p "Summarize semgrep.json: rank exploitable findings, list \
likely false positives, suggest the smallest fix for each real one." \
--allowedTools "Read,Grep" --output-format json > triage.json
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}