Incident Response — VayuPress
Status: Authoritative
Last reviewed: 2026-06-13
Severity Levels
| Severity | Definition | Response time |
|---|---|---|
| P0 — Critical | Data exfiltration, RCE, complete service loss | Immediate (< 1 hour) |
| P1 — High | Auth bypass, privilege escalation, significant data corruption | < 4 hours |
| P2 — Medium | Denial of service, partial data unavailability, security regression | < 24 hours |
| P3 — Low | Information disclosure, non-critical degradation | < 72 hours |
Incident Detection Sources
- Structured logs —
level=errororlevel=warnentries withcomponent=sandbox,component=signing,component=federation - Metrics —
vp_plugin_crashes_total,vp_plugin_quarantined_total,vp_signing_failures_total - Health endpoint —
GET /healthzreturns503on critical subsystem failure - External report — via
SECURITY.mdresponsible disclosure process
Playbooks
PB-1: Plugin Quarantine Storm
Symptom: Multiple plugins quarantined within short window; vp_plugin_quarantined_total spike.
# 1. Identify quarantined plugins
journalctl -u vayupress --since "10 minutes ago" | grep quarantined
# 2. Check if binary hash changed (supply chain compromise?)
sha256sum /opt/vayupress/plugins/*.bin
# 3. If hash mismatch: take plugin offline immediately
systemctl stop vayupress
# Restore plugin from verified backup
cp /backup/plugins/known-good/<name>.bin /opt/vayupress/plugins/
systemctl start vayupress
# 4. If runtime crash: collect coredump and plugin logs
coredumpctl dump > /tmp/plugin-coredump.$(date +%s)
PB-2: Article Signature Verification Failure
Symptom: signing: verify failed in logs; vp_signing_failures_total > 0.
# 1. Identify affected article IDs
journalctl -u vayupress | grep "signing: verify" | grep -o "id=[^ ]*"
# 2. Quarantine affected articles (mark as unverified in DB)
sqlite3 /data/vayupress.db \
"UPDATE articles SET verified=0 WHERE id IN (...)"
# 3. Determine cause: key rotation vs tamper
# Compare stored public key with current signing key public component
vayupress keydump --key /etc/vayupress/signing.key
# 4. If tamper: preserve evidence, restore from archive
vayupress archive restore --id <article-id> --target /tmp/restore/
# 5. Re-sign from restored canonical source
vayupress resign --article-id <id> --key /etc/vayupress/signing.key
PB-3: WAL Corruption
Symptom: SQLITE_CORRUPT errors; integrity_check fails on startup.
See full runbook: docs/operations/wal-corruption-recovery.md.
PB-4: Federation Inbox Flood
Symptom: Queue depth > 10,000; inbox goroutines saturated; memory pressure.
# 1. Identify flooding actor
journalctl -u vayupress | grep "inbox" | awk '{print $NF}' | sort | uniq -c | sort -rn | head
# 2. Block actor at Nginx level immediately
echo "deny <actor-ip>;" >> /etc/nginx/conf.d/blocked.conf
nginx -s reload
# 3. Drain queue safely
vayupress queue drain --actor <actor-id> --reason "flood-block"
# 4. Add to permanent blocklist
sqlite3 /data/vayupress.db \
"INSERT INTO federation_blocks(actor_id, reason, blocked_at) VALUES('<actor>', 'flood', datetime('now'))"
PB-5: Seccomp Violation (Unexpected Syscall)
Symptom: Plugin process receives EPERM on a syscall that should succeed; plugin behaviour degraded.
# 1. Enable strace on plugin process (dev/staging only)
strace -p <plugin-pid> -e trace=all 2>&1 | head -100
# 2. Identify blocked syscall number from audit log
ausearch -m SECCOMP --start recent
# 3. If legitimate: update allowedSyscalls in confinement_linux.go
# 4. If illegitimate: plugin is attempting restricted operations — investigate plugin source
Post-Incident Requirements
For P0 and P1 incidents:
- Timeline document within 24 hours of resolution.
- Root cause analysis within 72 hours.
- ADR update if architectural change is required.
- CHANGELOG entry in next release.
- CVE request if externally exploitable.
Responsible Disclosure
Security vulnerabilities: see SECURITY.md at repository root.
Embargo period: 90 days from reporter notification before public disclosure.