Pular para o conteúdo
Infraestrutura & Tecnologia

Claude Code como controle de segurança no workflow DevOps

Runbook DevOps para Security Reviews automatizados com Claude Code: instalação, Custom Commands, Audit Scripts e integração CI.

Mansoor Ahmed
Mansoor Ahmed
Head of Engineering 16 min de leitura

Stacks de aplicações self-hosted modernos são compostos por muitos componentes: Supabase Platform, camada de aplicação Next.js, Edge Functions, Background Jobs e APIs externas. Com cada componente, aumenta a probabilidade de erros de configuração, vazamento de secrets, políticas ausentes e endpoints desprotegidos.

Scanners de segurança tradicionais verificam regras estáticas. Eles encontram service_role em um arquivo .env, mas não reconhecem que uma nova Server Action está sem o mesmo check de ownership presente em todas as outras Server Actions. Eles reportam portas abertas, mas não reconhecem que uma alteração de firewall na semana passada, junto com um novo container, abriu um caminho de acesso não intencional.

O Claude Code preenche essa lacuna como camada de análise contextual sobre todo o stack.

O Claude Code não substitui verificações determinísticas. Ele as complementa ao interpretar os resultados, reconhecer correlações e priorizar recomendações.

Este runbook descreve como o Claude Code é concretamente instalado, configurado e integrado no workflow DevOps.

Resumo - Artigo 5 de 6 da série DevOps Runbook

  • Claude Code apenas no servidor de auditoria
  • Modelo de três camadas
  • Custom Commands definem o escopo da revisão
  • Modo headless restrito a Read/Grep/Glob
  • Auditoria cron semanal mais revisões de PR

Sumário da série

Este guia faz parte da nossa série de runbooks DevOps para stacks de aplicações self-hosted.

  1. Supabase Self-Hosting Runbook
  2. Next.js sobre Supabase com segurança
  3. Supabase Edge Functions com segurança
  4. Trigger.dev Background Jobs com segurança
  5. Claude Code como controle de segurança no workflow DevOps - este artigo
  6. Security Baseline para todo o stack

Os primeiros quatro artigos descrevem os componentes individuais. Este artigo descreve a camada de controle de segurança sobre eles.

Visão geral da arquitetura

O Claude Code trabalha não no servidor de produção, mas no servidor de auditoria (veja Artigo 1). Ele tem acesso Read-Only aos dados que analisa.

Servidor de produção (supabase-prod)
   |
   +-- Supabase Stack
   +-- Next.js App
   +-- Edge Functions
   +-- Trigger.dev
   |
   +---- SSH (read-only) ----> Servidor de auditoria (audit-runner)
                                   |
                                   +-- Verificações determinísticas
                                   |   +-- Port Scans (nmap)
                                   |   +-- Firewall Diff (iptables-save)
                                   |   +-- Versões de containers (docker images)
                                   |   +-- Status RLS (psql)
                                   |   +-- npm audit
                                   |   +-- Verificações de código baseadas em grep
                                   |
                                   +-- Claude Code (headless)
                                   |   +-- Analisa resultados das verificações
                                   |   +-- Lê Git Diffs
                                   |   +-- Verifica configs contra runbooks
                                   |   +-- Cria relatório priorizado
                                   |
                                   +-- Relatório -> Equipe DevOps (humano decide)

O Claude Code não executa alterações no sistema de produção. Nenhum deployment, nenhuma rotação de secrets, nenhuma parada de containers.

Comparação das três camadas

PropriedadeVerificações determinísticasRegras de runbooksAnálise Claude
EntradaComandos do sistema (nmap, grep)Arquivos MarkdownOutput das camadas 1+2
SaídaFatos (aberto/fechado, presente/ausente)Estado desejado (DEVE)Relatório priorizado
FrequênciaDiária (cron)Estática (atualização com mudanças)Semanal + em PR
Falsos positivosNenhum (objetivo)Nenhum (regras definidas)Possíveis (interpretação)
Detecção de driftPadrões conhecidosNenhum (referência)Padrões desconhecidos

Princípio fundamental: três níveis de verificação de segurança

Nível 1: Verificações determinísticas (Scripts)
   -> Resultados objetivos e repetíveis
   -> Exemplo: "Porta 5432 está acessível externamente" = Fato

Nível 2: Regras de runbook (arquivos Markdown)
   -> Estado desejado definido do stack
   -> Exemplo: "PostgreSQL deve escutar apenas em 10.0.1.10"

Nível 3: Análise contextual do Claude Code (headless)
   -> Interpreta resultados, reconhece correlações
   -> Exemplo: "Porta 5432 está aberta E o novo container
     tem uma conexão direta com o DB. Isso é um problema."

Os níveis se constroem um sobre o outro. O Claude recebe os resultados do Nível 1 e as regras do Nível 2 como input e cria a partir disso seu review contextual.

Parte A - Configurar o Claude Code

A1 - Instalação e configuração no servidor de auditoria

Implementação

O Claude Code é instalado no servidor de auditoria, não no servidor de produção.

# Auf dem audit-runner Server

# Node.js installieren (falls nicht vorhanden)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
apt-get install -y nodejs

# Claude Code installieren
npm install -g @anthropic-ai/claude-code

# API Key konfigurieren
# Eigener API Key mit Budget-Limit für CI/CD
export ANTHROPIC_API_KEY="sk-ant-..."

# In .bashrc oder .env für den audit-user persistieren
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> /home/audit/.bashrc

Testar o Headless Mode:

# Einfacher Test: funktioniert Claude Code non-interaktiv?
echo "Hello" | claude -p "Antworte mit OK wenn du das lesen kannst" \
  --output-format text

# Erwartung: "OK" oder ähnliche Bestätigung

Condição verificável

# Claude Code installiert?
claude --version
# Erwartung: Versionsnummer

# API Key gesetzt?
test -n "$ANTHROPIC_API_KEY" && echo "OK" || echo "FEHLT"

# Headless Mode funktioniert?
claude -p "Sage nur: OK" --output-format text --max-turns 1 2>/dev/null
# Erwartung: "OK"

Cenário de falha

Quando o Claude Code roda no servidor de produção e tem acesso ao Bash, um prompt defeituoso poderia teoricamente executar comandos no sistema de produção. No servidor de auditoria, o Claude Code tem acesso apenas aos relatórios e cópias de configuração coletadas lá, não ao sistema em produção.

A2 - Configurar Custom Security Review Command

Implementação

O Claude Code suporta Custom Commands via arquivos Markdown em .claude/commands/. Esses Commands definem o contexto e as regras de verificação para o Security Review.

# Im Infrastruktur-Repository
mkdir -p .claude/commands
# .claude/commands/security-review.md

Du bist Security Reviewer für einen self-hosted Stack bestehend aus:
- Supabase (PostgreSQL, PostgREST, GoTrue, Kong, Edge Functions)
- Next.js (App-Schicht, Server Actions, Route Handler)
- Trigger.dev v3 (Background Jobs, self-hosted)
- Tudo em infraestrutura própria (ex. Locaweb, Magalu Cloud)

Du erhältst den Output der deterministischen Security Checks und die
aktuellen Konfigurationsdateien.

Prüfe folgendes:

## Infrastruktur (Artikel 1)
- Sind unerwartete Ports von aussen erreichbar?
- Hat sich die Firewall gegenüber der Baseline geändert?
- Sind Container-Versionen gepinnt und aktuell?
- Ist das TLS-Zertifikat noch mindestens 14 Tage gültig?
- Liegt das letzte Backup weniger als 26 Stunden zurück?

## Next.js (Artikel 2)
- Taucht service_role in NEXT_PUBLIC Variablen oder im Client-Bundle auf?
- Haben alle Server Actions einen getUser() Auth Check?
- Haben alle Route Handler einen getUser() Auth Check?
- Existiert middleware.ts mit getUser() (nicht getSession())?
- Sind Security Headers in next.config.js gesetzt?

## Edge Functions (Artikel 3)
- Haben alle Webhook-Functions eine Signaturprüfung?
- Gibt es Functions mit Business-Logik statt Integrations-Logik?
- Ist CORS korrekt konfiguriert (kein Wildcard in Produktion)?
- Gibt es hardcoded Secrets im Function-Code?

## Trigger.dev (Artikel 4)
- Haben alle Tasks maxDuration und concurrencyLimit?
- Haben Tasks mit externen API-Calls Idempotency Keys?
- Nutzen Tasks nur die DB-Felder die sie brauchen (kein SELECT *)?
- Gibt es console.log statt dem Trigger.dev logger?

## Stackübergreifend
- Gibt es Architektur-Drift? (Business-Logik in Edge Functions,
  Langläufer in Server Actions, etc.)
- Sind die Änderungen der letzten Woche konsistent mit der
  bestehenden Architektur?
- Gibt es neue Tabellen ohne RLS?
- Gibt es Muster die auf systematische Probleme hindeuten?

Erstelle einen priorisierten Bericht:
- KRITISCH: sofort handeln (Daten-Leak möglich, Port offen, Secret exponiert)
- WARNUNG: diese Woche lösen (fehlende Checks, Drift, veraltete Packages)
- INFO: bei Gelegenheit verbessern (Code-Qualität, fehlende Tests)

Für jedes Finding: Was ist das Problem, warum ist es ein Risiko,
was ist die konkrete Lösung.

Condição verificável

# Custom Command existiert?
test -f .claude/commands/security-review.md && echo "OK" || echo "FEHLT"

# Command wird von Claude Code erkannt?
claude -p "/security-review" --max-turns 1 2>/dev/null | head -5
# Erwartung: Claude beginnt mit der Analyse

A3 - CLAUDE.md como contexto do projeto

Implementação

O Claude Code lê automaticamente o arquivo CLAUDE.md no diretório do projeto. Esse arquivo fornece ao Claude o contexto permanente sobre o seu stack.

# CLAUDE.md (im Root des Infrastruktur-Repos)

## Stack-Überblick
Self-hosted Supabase + Next.js + Edge Functions + Trigger.dev v3
em infraestrutura própria (ex. Locaweb, Magalu Cloud).

## Server
- supabase-prod: 10.0.1.10 (Supabase, Next.js, Edge Functions)
- audit-runner: 10.0.1.11 (Security Checks, Claude Code, Monitoring)
- trigger-server: separater Docker-Stack für Trigger.dev v3

## Sicherheitsregeln
- service_role Key darf NUR in: lib/supabase/admin.ts und trigger/lib/supabase.ts
- NEXT_PUBLIC_* darf NUR enthalten: SUPABASE_URL und SUPABASE_ANON_KEY
- Alle public-Tabellen müssen RLS aktiviert haben
- Alle Server Actions und Route Handler müssen getUser() aufrufen
- Alle Webhook Edge Functions müssen Signaturen prüfen
- Alle Trigger.dev Tasks müssen maxDuration und concurrencyLimit haben
- PostgreSQL nur auf 10.0.1.10:5432 (internes Interface)
- Supabase Studio nicht von aussen erreichbar
- Trigger.dev Dashboard nicht von aussen erreichbar

## Deployment
- Infrastruktur wird nur über Git deployed (kein manuelles SSH-Editing)
- Edge Functions werden als Dateien in volumes/functions/ abgelegt
- Trigger.dev Tasks werden über npx trigger.dev deploy --self-hosted deployed

## Verzeichnisstruktur
- app/ = Next.js App (Server Actions, Route Handler, Pages)
- lib/supabase/ = Supabase Client Konfiguration
- middleware.ts = Auth Middleware
- volumes/functions/ = Supabase Edge Functions
- trigger/tasks/ = Trigger.dev Tasks
- infra/ = docker-compose, nginx/caddy, Firewall Configs
- scripts/ = Audit Scripts, Backup, Restore
- runbooks/ = Sicherheits-Runbooks

Quem combina a abordagem CLAUDE.md com as regras de segurança do Artigo 2 obtém uma base de contexto completa para reviews automatizados.

Parte B - O workflow de auditoria completo

Aqui se junta o que os Artigos 1 a 4 prepararam. Cada artigo tem seus próprios scripts de verificação. O Artigo 5 os reúne e passa o output ao Claude Code.

B1 - O script de auditoria completo

Implementação

Este script coleta todos os resultados das verificações determinísticas e os passa ao Claude Code no Headless Mode.

#!/bin/bash
# scripts/full-security-audit.sh
# Läuft auf dem audit-runner Server

set -euo pipefail

PROD_HOST="10.0.1.10"
REPORT_DIR="/opt/audit/reports"
DATE=$(date +%Y-%m-%d)
REPORT_FILE="${REPORT_DIR}/audit-input-${DATE}.md"

mkdir -p "$REPORT_DIR"

echo "=== Gesamt-Security-Audit ${DATE} ===" | tee "$REPORT_FILE"

# -------------------------------------------
# EBENE 1: Deterministische Checks
# -------------------------------------------

echo -e "\n# Deterministische Check-Ergebnisse\n" >> "$REPORT_FILE"

# --- Infrastruktur (Artikel 1) ---
echo "## Infrastruktur" >> "$REPORT_FILE"

echo "### Offene Ports (extern)" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
nmap -p 22,80,443,3000,3040,5432,5433,8000,9000 app.example.com \
  --open -oG - 2>/dev/null >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### Firewall Diff gegen Baseline" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "iptables-save" | \
  diff /opt/baselines/firewall-baseline.txt - >> "$REPORT_FILE" 2>&1 || true
echo '```' >> "$REPORT_FILE"

echo "### Container Status" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "docker compose ps --format 'table {{.Name}}\t{{.Status}}\t{{.Image}}'" \
  >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

echo "### TLS Zertifikat" >> "$REPORT_FILE"
CERT_EXPIRY=$(echo | openssl s_client -connect app.example.com:443 2>/dev/null | \
  openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
CERT_EPOCH=$(date -d "$CERT_EXPIRY" +%s 2>/dev/null || echo 0)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (CERT_EPOCH - NOW_EPOCH) / 86400 ))
echo "Ablauf: ${CERT_EXPIRY} (${DAYS_LEFT} Tage)" >> "$REPORT_FILE"

echo "### Backup Status" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "ls -lh /opt/backups/*.gpg 2>/dev/null | tail -3" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### RLS Status" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "docker compose exec -T postgres psql -U postgres -c \
  \"SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;\"" \
  >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

echo "### Disk Usage" >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "df -h / | tail -1" >> "$REPORT_FILE"

# --- Next.js (Artikel 2) ---
echo -e "\n## Next.js App-Schicht" >> "$REPORT_FILE"

echo "### service_role im Client Code" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && grep -rn 'SERVICE_ROLE\|service_role' app/ \
  --include='*.ts' --include='*.tsx' | grep -v 'lib/supabase/admin.ts' | grep -v node_modules" \
  >> "$REPORT_FILE" 2>&1 || echo "Keine Treffer" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### NEXT_PUBLIC mit Secrets" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && grep 'NEXT_PUBLIC_' .env* 2>/dev/null | \
  grep -iE 'service_role|secret|private|database'" \
  >> "$REPORT_FILE" 2>&1 || echo "Keine Treffer" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### Server Actions ohne Auth" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && for file in \$(grep -rl \"'use server'\" app/ --include='*.ts'); do
  if ! grep -q 'getUser' \"\$file\"; then
    echo \"WARNUNG: \$file\"
  fi
done" >> "$REPORT_FILE" 2>&1 || echo "Keine Treffer" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### Route Handler ohne Auth" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && for file in \$(find app/api -name 'route.ts' 2>/dev/null); do
  if ! grep -q 'getUser' \"\$file\"; then
    echo \"WARNUNG: \$file\"
  fi
done" >> "$REPORT_FILE" 2>&1 || echo "Keine Treffer" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

echo "### npm audit" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && npm audit --audit-level=high 2>&1 | tail -20" \
  >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

# --- Edge Functions (Artikel 3) ---
echo -e "\n## Edge Functions" >> "$REPORT_FILE"

echo "### Webhook Functions ohne Signaturprüfung" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "for dir in /opt/supabase/volumes/functions/*-webhook/; do
  [ -d \"\$dir\" ] || continue
  name=\$(basename \"\$dir\")
  if ! grep -qE 'signature|verify|hmac|crypto' \"\$dir/index.ts\" 2>/dev/null; then
    echo \"KRITISCH: \$name hat keine Signaturprüfung\"
  else
    echo \"OK: \$name\"
  fi
done" >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

echo "### Hardcoded Secrets in Functions" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "grep -rn 'sk_live\|sk_test\|whsec_\|Bearer ey' \
  /opt/supabase/volumes/functions/ --include='*.ts' 2>/dev/null" \
  >> "$REPORT_FILE" 2>&1 || echo "Keine Treffer" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"

# --- Trigger.dev (Artikel 4) ---
echo -e "\n## Trigger.dev Tasks" >> "$REPORT_FILE"

echo "### Tasks ohne maxDuration" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && for file in trigger/tasks/*.ts; do
  name=\$(basename \"\$file\" .ts)
  if ! grep -q 'maxDuration' \"\$file\" 2>/dev/null; then
    echo \"WARNUNG: \$name\"
  fi
done" >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

echo "### Tasks ohne Concurrency Limit" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && for file in trigger/tasks/*.ts; do
  name=\$(basename \"\$file\" .ts)
  if ! grep -qE 'concurrencyLimit|queue:' \"\$file\" 2>/dev/null; then
    echo \"WARNUNG: \$name\"
  fi
done" >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

# --- Git Änderungen ---
echo -e "\n## Code-Änderungen (letzte 7 Tage)" >> "$REPORT_FILE"
echo '```' >> "$REPORT_FILE"
ssh deploy@${PROD_HOST} "cd /opt/app && git log --oneline --since='7 days ago'" \
  >> "$REPORT_FILE" 2>&1
ssh deploy@${PROD_HOST} "cd /opt/app && git diff HEAD~10 --stat 2>/dev/null" \
  >> "$REPORT_FILE" 2>&1
echo '```' >> "$REPORT_FILE"

# -------------------------------------------
# EBENE 2: Runbook-Regeln (als Kontext)
# -------------------------------------------

echo -e "\n# Aktive Runbook-Regeln\n" >> "$REPORT_FILE"
cat runbooks/security-baseline.md >> "$REPORT_FILE" 2>/dev/null || \
  echo "security-baseline.md nicht gefunden" >> "$REPORT_FILE"

# -------------------------------------------
# EBENE 3: Claude Code Analyse
# -------------------------------------------

echo ""
echo "=== Deterministische Checks abgeschlossen ==="
echo "=== Starte Claude Code Analyse ==="
echo ""

# Claude Code im Headless Mode aufrufen
# --allowedTools einschränken: nur Lesen, kein Bash, kein Schreiben
CLAUDE_OUTPUT=$(cat "$REPORT_FILE" | claude -p \
  "Du erhältst den vollständigen Security-Audit-Report unseres self-hosted Stacks.
Analysiere ihn gemäss den Regeln in .claude/commands/security-review.md.
Erstelle einen priorisierten Bericht mit KRITISCH / WARNUNG / INFO.
Für jedes Finding: Problem, Risiko, konkrete Lösung." \
  --allowedTools "Read,Grep,Glob" \
  --append-system-prompt "Du bist ein Senior Security Engineer. Antworte auf Deutsch. Sei konkret und priorisiere strikt." \
  --output-format text \
  --max-turns 5 \
  2>/dev/null)

# Report speichern
CLAUDE_REPORT="${REPORT_DIR}/claude-review-${DATE}.md"
echo "$CLAUDE_OUTPUT" > "$CLAUDE_REPORT"

echo ""
echo "=== Claude Code Review abgeschlossen ==="
echo "Report: $CLAUDE_REPORT"

# Bei kritischen Findings: Alert
if echo "$CLAUDE_OUTPUT" | grep -qi "KRITISCH"; then
  echo "$CLAUDE_OUTPUT" | mail -s "KRITISCH: Security Review ${DATE}" ops@example.com
  echo "Alert gesendet an ops@example.com"
fi

Condição verificável

# Script ausführbar?
test -x scripts/full-security-audit.sh && echo "OK" || echo "NICHT AUSFÜHRBAR"

# Letzter Audit-Report vorhanden?
ls -la /opt/audit/reports/claude-review-$(date +%Y-%m-%d).md 2>/dev/null
# Erwartung: Datei von heute

# Report enthält die erwarteten Sektionen?
grep -c "KRITISCH\|WARNUNG\|INFO" /opt/audit/reports/claude-review-$(date +%Y-%m-%d).md
# Erwartung: mindestens 1

B2 - Quando a auditoria é executada

Três pontos de disparo

1. Cron semanal (domingo 6:00h)
   -> Auditoria completa sobre todo o stack
   -> Resultado: relatório priorizado para a semana

2. Em Pull Requests (CI/CD)
   -> Apenas os arquivos alterados
   -> Resultado: comentário de review no PR

3. Ad-hoc (manual)
   -> Após incidentes, deployments maiores, alterações de infraestrutura
   -> Resultado: análise imediata

Cron semanal:

# crontab auf dem audit-runner
0 6 * * 0 /opt/audit/scripts/full-security-audit.sh >> /var/log/security-audit.log 2>&1

PR Review (pipe do Git Diff para o Claude):

#!/bin/bash
# scripts/pr-security-review.sh
# Wird vom CI bei jedem PR aufgerufen

DIFF=$(git diff origin/main...HEAD)

if [ -z "$DIFF" ]; then
  echo "Kein Diff, kein Review nötig"
  exit 0
fi

echo "$DIFF" | claude -p \
  "Review diesen Git Diff auf Sicherheitsprobleme.
Prüfe insbesondere:
- service_role Nutzung in Client-Code
- Server Actions ohne Auth Check
- Edge Functions ohne Signaturprüfung
- Trigger.dev Tasks ohne maxDuration
- Hardcoded Secrets
- Neue API Endpoints ohne Rate Limiting

Antworte NUR wenn du ein konkretes Problem findest.
Wenn alles in Ordnung ist, sage: Keine Sicherheitsprobleme gefunden." \
  --allowedTools "Read,Grep,Glob" \
  --output-format text \
  --max-turns 3

Review ad-hoc:

# Manuell nach einem Incident
cd /opt/infra-repo
claude -p "Prüfe den aktuellen Zustand des Repositories auf Sicherheitsprobleme. \
Fokus auf die letzten 5 Commits." \
  --allowedTools "Read,Grep,Glob,Bash(git log*),Bash(git diff*)" \
  --max-turns 10

Condição verificável

# Cron Job aktiv?
crontab -l | grep "full-security-audit"
# Erwartung: Eintrag vorhanden

# Letzter Audit weniger als 8 Tage her?
LAST_REPORT=$(ls -t /opt/audit/reports/claude-review-*.md 2>/dev/null | head -1)
if [ -n "$LAST_REPORT" ]; then
  AGE=$(( ($(date +%s) - $(stat -c %Y "$LAST_REPORT")) / 86400 ))
  echo "Letzter Report: $AGE Tage alt"
  [ "$AGE" -gt 8 ] && echo "WARNUNG: Audit überfällig"
fi

Parte C - O que o Claude pode e o que não pode

C1 - Onde o Claude Code é especialmente forte

O Claude reconhece correlações que verificações determinísticas não conseguem identificar:

Reconhecer drift de arquitetura: As verificações determinísticas encontram que uma nova Edge Function existe. O Claude reconhece que essa Function contém lógica de negócio que pertence ao Next.js, porque ela processa input de usuários e transforma dados em vez de receber um evento externo.

Padrões que ultrapassam limites de arquivos: Um grep encontra que getUser() está ausente em uma Server Action. O Claude reconhece que essa Action é a única de 15 Actions sem o check, e que ela foi adicionada na semana passada em um commit que também alterou três outros arquivos, todos corretos. Isso indica um descuido, não um problema sistemático.

Priorização: As verificações determinísticas produzem uma lista plana de 30 findings. O Claude os agrupa: “Os 5 findings de service_role estão todos na biblioteca Admin e são corretos. Os 2 checks de auth ausentes nos Route Handlers são o risco real, porque afetam endpoints de API públicos.”

Contexto de configuração: Um Port Scan mostra que a porta 8000 está aberta. O Claude sabe pelo contexto do stack (CLAUDE.md) que a porta 8000 é a porta interna do Kong, e verifica se ela deveria escutar apenas em localhost.

C2 - O que o Claude Code não pode e não deve fazer

O Claude não pode escanear ativamente. Ele não pode realizar scans de rede, verificar processos em execução ou testar portas externamente. Isso é feito pelas ferramentas determinísticas (nmap, ss, docker ps). O Claude analisa o output delas.

O Claude não deve escrever em produção. A restrição --allowedTools no Headless Mode garante que o Claude só pode ler:

# RICHTIG: Nur Lese-Tools erlaubt
claude -p "..." --allowedTools "Read,Grep,Glob"

# FALSCH: Bash erlaubt = Claude kann beliebige Befehle ausführen
claude -p "..." --allowedTools "Read,Grep,Glob,Bash"

Quando o Bash é necessário (por exemplo, para git log), permitir apenas comandos específicos:

--allowedTools "Read,Grep,Glob,Bash(git log*),Bash(git diff*)"

O Claude não é determinístico. O mesmo input pode gerar relatórios levemente diferentes. Por isso, o Claude não substitui verificações determinísticas. Ele interpreta os resultados delas.

Estatística: De acordo com o relatório OWASP de 2024, mais de 34% das violações de segurança resultam de erros de configuração, não de vulnerabilidades no código - exatamente o tipo de problema que a análise contextual é projetada para detectar.

O Claude não conhece dados em tempo real. Ele trabalha com os snapshots que lhe são passados no momento da auditoria. Entre a auditoria e a leitura do review, o estado pode ter mudado.

C3 - Regras de segurança para o Claude Code no CI

# Auf dem Audit-Server: Claude Code Konfiguration

# 1. Eigener API Key mit Budget-Limit
#    Separater Key, nicht der Entwickler-Key
#    Budget: max. 50 USD/Monat für CI Reviews

# 2. --allowedTools immer einschränken
#    Niemals unbeschränkten Bash-Zugriff in automatisierten Scripts

# 3. --max-turns begrenzen
#    Verhindert Endlosschleifen bei verwirrenden Inputs
#    Empfehlung: 3-5 für PR Reviews, 5-10 für Full Audits

# 4. Output immer in Datei speichern
#    Nicht nur auf stdout, damit der Report nachvollziehbar bleibt

# 5. Claude Code hat keinen SSH-Zugriff auf Produktion
#    Die deterministischen Scripts sammeln die Daten
#    Claude bekommt nur den Text-Output zur Analyse

Checklist de deployment

Instalação
  [ ] Claude Code instalado no audit-runner
  [ ] API Key configurada (Key CI separada com limite de orçamento)
  [ ] Headless Mode funciona (teste com claude -p)

Configuração
  [ ] .claude/commands/security-review.md criado
  [ ] CLAUDE.md presente no repositório de infraestrutura
  [ ] --allowedTools restrito a Read,Grep,Glob
  [ ] --max-turns limitado a 5-10

Automação
  [ ] Script de auditoria completo presente e executável
  [ ] Cron Job semanal ativo
  [ ] Script de PR Review integrado ao CI
  [ ] Alerta para findings críticos configurado

Segurança
  [ ] Claude Code roda APENAS no audit-runner
  [ ] Claude Code NÃO tem acesso SSH à produção
  [ ] Sem acesso irrestrito ao Bash em --allowedTools
  [ ] Relatórios são armazenados e arquivados
  [ ] Limite de orçamento definido na API Key

Conclusão

O Claude Code não é um scanner de segurança automático e não substitui verificações determinísticas. Ele é um analista contextual que interpreta os resultados de scanners e verificações via grep, reconhece correlações e prioriza recomendações.

O workflow é sempre o mesmo: ferramentas determinísticas coletam fatos, o Claude Code os interpreta, um humano decide. Isso funciona porque cada camada faz o que faz de melhor. Scripts são confiáveis com padrões conhecidos. O Claude reconhece padrões desconhecidos. Humanos tomam decisões.

A combinação dos scripts de verificação dos Artigos 1-4, do Custom Security Review Command e do cron de auditoria semanal resulta em um controle de segurança que detecta tanto riscos conhecidos quanto inesperados.

Quem segue esses princípios junto com uma arquitetura Cert-Ready-by-Design constrói segurança verificável em vez de auditorias posteriores.

Checklists de auditoria da série

Prompts preparados para o Claude Code. Cada checklist verifica automaticamente os pontos de segurança do respectivo runbook e reporta APROVADO, AVISO ou CRÍTICO.

Sumário da série

  1. Supabase Self-Hosting Runbook
  2. Next.js sobre Supabase com segurança
  3. Supabase Edge Functions com segurança
  4. Trigger.dev Background Jobs com segurança
  5. Claude Code como controle de segurança no workflow DevOps - este artigo
  6. Security Baseline para todo o stack

O próximo e último artigo descreve a Security Baseline para o stack completo, que reúne todas as regras dos Artigos 1-5 em um único arquivo verificável.

Bert Gogolin

Bert Gogolin

Diretor Executivo, Gosign

AI Governance Briefing

IA empresarial, regulamentação e infraestrutura - uma vez por mês, diretamente de mim.

Sem spam. Cancelável a qualquer momento. Política de privacidade

Claude Code Security DevOps CI/CD Automation
Compartilhar este artigo

Perguntas frequentes

O Claude Code substitui scanners de segurança determinísticos?

Não. O Claude Code complementa verificações determinísticas ao interpretar seus resultados, reconhecer correlações e priorizar recomendações. Scripts encontram padrões conhecidos de forma confiável, o Claude reconhece padrões desconhecidos e drift de arquitetura.

O Claude Code pode rodar no servidor de produção?

Não. O Claude Code roda exclusivamente no servidor de auditoria com acesso Read-Only. Os scripts determinísticos coletam dados do servidor de produção, o Claude analisa apenas o output em texto.

Por que o Claude Code não deve ter acesso Bash em CI?

Com acesso Bash irrestrito, o Claude Code poderia teoricamente executar comandos arbitrários no servidor, mesmo que o prompt solicite apenas uma análise. Restringir a Read, Grep e Glob garante que o Claude possa apenas ler e analisar, mas não fazer alterações no sistema.