
Hari 49: AI Remediation Node — LLM Auto-Summarize Scanner Findings ke Slack
Scanner findings (Semgrep, Checkov, Trivy) otomatis di-summarize oleh LLM gratis (OpenCode Zen deepseek-v4-flash-free) dan diposting ke Slack. 3 format scanner dinormalisasi ke unified schema. Cloudflare WAF block urllib fixed.
Day 48 routing Falco CRITICAL alerts ke Slack. Hari ini — LLM baca scanner finding, generate ringkasan bahaya + contoh kode perbaikan, kirim ke Slack #security-alerts. Full automation.
Arsitektur
Scanner finding JSON → POST /webhook/sast-alert
→ normalize_finding(raw, scanner)
→ IF severity in (CRITICAL, HIGH, MEDIUM):
→ call_llm() via OpenCode Zen (deepseek-v4-flash-free, $0.00)
→ post_to_slack_remediation()
→ ELSE: log only
Unified Finding Format
Setiap scanner punya JSON schema beda. Normalize ke unified format:
def normalize_finding(raw, scanner):
if scanner == "semgrep":
return {
"id": raw["check_id"],
"title": raw["check_id"].split(".")[-1],
"severity": raw["extra"]["severity"],
"file": f"{raw['path']}:{raw['start']['line']}",
"description": raw["extra"]["message"],
"references": raw["extra"]["metadata"]["references"],
}
elif scanner == "checkov":
return {
"id": raw["check_id"],
"title": raw["check_name"],
"severity": raw.get("severity") or "MEDIUM",
"file": raw["file_path"],
"description": f"Check {raw['check_id']} failed on {raw['resource']}",
"references": [raw["guideline"]] if raw.get("guideline") else [],
}
elif scanner == "trivy":
return {
"id": raw["VulnerabilityID"],
"title": raw.get("Title") or f"{raw['PkgName']} vulnerability",
"severity": raw["Severity"],
"file": raw["PkgName"],
"description": raw["Description"],
"references": raw.get("References", []),
}
LLM Prompt (Bahasa Indonesia)
Berikut temuan keamanan dari scanner:
Judul: [title]
Severity: [severity]
File: [file]
Deskripsi: [description]
Referensi: [references]
Berikan:
1. Ringkasan bahaya (max 2 kalimat)
2. Contoh kode perbaikan (jika ada, singkat)
OpenCode Zen — FREE Model
| Model | Cost | Privacy | Quality |
|---|---|---|---|
| deepseek-v4-flash-free | $0.00 | Zero-retention | Best reasoning |
| big-pickle | $0.00 | Data dipakai training | Stealth |
| ling-3.0-flash-free | $0.00 | Zero-retention | Fast |
| nemotron-3-ultra-free | $0.00 | Data di-log NVIDIA | NVIDIA |
Pilih deepseek-v4-flash-free — free, reasoning bagus, no privacy concerns.
Test Results — 3 Scanners
| Test | Scanner | Severity | Route | LLM Response | Slack? |
|---|---|---|---|---|---|
| 1 | Semgrep | WARNING | Log only | — | — |
| 2 | Checkov | MEDIUM | LLM + Slack | 496 chars | ✅ HTTP 200 |
| 3 | Trivy | CRITICAL | LLM + Slack | 636 chars | ✅ HTTP 200 |
Priority routing: CRITICAL/HIGH/MEDIUM → LLM + Slack. WARNING/NOTICE/LOW → log only (save LLM cost).
Slack Message Format
🤖 *AI Remediation: Ensure no security groups allow ingress from 0.0.0.0:0 to port 80*
*Scanner:* checkov | *Severity:* MEDIUM | *File:* terraform/main.tf
*AI Analysis:*
[LLM-generated ringkasan bahaya + contoh kode perbaikan]
Cloudflare WAF vs Python urllib
Problem: urllib.request default User-Agent Python-urllib/3.x → Cloudflare block (HTTP 403, error code 1010)
Fix: Tambah custom User-Agent header:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENCODE_ZEN_API_KEY}",
"User-Agent": "SecureBank-WebhookReceiver/1.0", # ← fix
}
Pelajaran Hari Ini
Scanner format normalization. Semgrep, Checkov, Trivy — semua beda JSON schema. Unified format simplifies downstream processing. Satu normalize_finding() function, 3 branches.
OpenCode Zen free models. 7 model gratis, deepseek-v4-flash-free paling bagus. OpenAI-compatible API — tinggal ganti base URL + model name. $0.00 cost.
Cloudflare blocks default urllib User-Agent. Selalu tambah custom User-Agent di urllib requests ke public APIs. Python-urllib/3.x = bot signature = blocked.
Priority routing saves cost. WARNING/NOTICE/LOW skip LLM call entirely. Hanya CRITICAL/HIGH/MEDIUM yang kena LLM. Hemat token, hemat waktu.
Repo
Semua code dan dokumentasi ada di: https://github.com/stayrelevantid/chalange-devsecops
Kesimpulan
Day 49 complete. AI remediation node — scanner findings auto-summarized via LLM (deepseek-v4-flash-free, $0.00) and posted to Slack. 3 scanner formats normalized (Semgrep, Checkov, Trivy). Priority routing: CRITICAL/HIGH/MEDIUM → LLM+Slack, others → log. Cloudflare WAF fix applied. Besok Day 50 — CSPM (Prowler/ScoutSuite).
Diskusi & Komentar
Artikel Terkait
Hari 20: Terraform + Checkov, 15 Celah IaC Ketahuan
Bikin infrastructure as code pakai Terraform, lalu scan dengan Checkov. Hasilnya 15 celah keamanan ketahuan — S3 tanpa enkripsi, security group terbuka ke dunia.
Hari 22: Pipeline IaC, Dua Scanner Barengan Gagal
Bikin workflow GitHub Actions khusus infrastructure security. Checkov dan Trivy IaC scan Terraform barengan. Hasilnya pipeline MERAH — security gate bekerja!
Hari 22 Bonus: Perbaikan Pipeline Gitleaks yang Merah Diam-diam
Pipeline Gitleaks merah sejak Day 14 karena flag --no-gitignore tidak pernah ada. Gitleaks detect scan git history, bukan working directory. Fix: hapus flag.