Releases: jmrGrav/security-automation-go
Release list
v1.7.7 — Unified v2 shell + collapsible sidebar + fix Ask AI
What's new in v1.7.7
Unified v2 shell
All pages now share a single v2Page() wrapper — Dashboard (previously had its own "OPERATOR" branded shell) and Trusted Networks (previously used the old v1 ConsoleLayout templ) are now fully consistent with every other v2 page.
Collapsible sidebar
BetterStack-style collapse: 218px (icon + label) → 66px (icon only). Toggle button (‹/›) in the brand area, state persisted in localStorage. Smooth CSS transition on width.
SVG nav icons
All 9 sidebar nav items now use clean inline SVGs (dashboard grid, magnifying glass, activity wave, layers, ECG pulse, cloud, file, list, shield) replacing the colored 5px dots.
Design system tokens
Global CSS token classes defined in the shell: .v2-card, .v2-kpi, .v2-pill, .v2-banner, .v2-table, .v2-kv-row.
Fix ✦ Ask AI button
The ✦ trigger in Timeline row details now works: click handler added, CSRF token threaded into the page via a hidden element, inline result panel created on click below the row details.
Install
curl -LO https://github.com/jmrGrav/security-automation-go/releases/download/v1.7.7/security-automation-go_1.7.7_amd64.deb
sudo dpkg -i security-automation-go_1.7.7_amd64.deb
sudo systemctl restart cf-syncv1.7.6 — UI v2 polish + operator ergonomics
What's new in v1.7.6
UI v2 — Timeline
- Clickable histogram bars now filter events by time window (
?from=X&to=Y) - Contextual "why it matters" hints on row details (threat/borderline/trusted classification)
- ✦ AI explain trigger on timeline row details
v2FilterTimelineEventswith proper time-range support- Cleaner action list (removed stale v1
/forensiclink)
UI v2 — Investigate
- "Pivot to" card with quick links to Timeline, Cloudflare, Notes, and add-note-for-this-IP
- Back-navigation banner when arriving from timeline filter
UI v2 — Notes
- Type selector (IP address / ASN / Domain / Other) replacing hardcoded hidden input
- Note count pill in card header
- Improved empty state with actionable hint
- Ctrl+K shortcut hint below Save button
- "View all N notes" link when list is truncated
UI v2 — Freshness
data-tsattributes added across audit rows, dashboard live tail, providers posture meta, and Cloudflare sync badgefreshness.js— live relative-time updates for alldata-tselements (refreshes every 30s)
UI v2 — Navigation & Feedback
nav-progress.js— body.v2-loadingclass applies skeleton shimmer on.v2-cardduring page transitions- Palette —
g+c(Cloudflare),g+n(Notes),g+a(Audit) shortcuts; recent-IPs stored in localStorage - Operator live script — complete v2 route map;
j/k/Enterkeyboard navigation for<details>rows
Fixes
- Updated stale test assertions (removed
/forensicv1 link expectation, verifieddata-tspresence)
Closes #160 #161 #162 #163 #164 #165 #166 #167 #168 #169 #172 #173 #174 #175 #176 #178
v1.7.5 — UI v2 SOC Operator Console
UI v2 SOC Operator Console — complete
Full dark-shell operator console at /v2/ with sidebar workflow navigation (Observe / Investigate / Infrastructure / Operations), animated login loader, and working sign-out.
New v2 pages
/v2/timeline— Live Tail: 46-bar histogram, 200-row stream with colored borders, IP drill-down actions/v2/providers— Integrations: fused Providers + Cloudflare Diff + Trusted Networks, posture strip, advisory banner/v2/incident— Focus Incident: IP aggregation, ASN/Country (unavailable if not enriched), pivots to AbuseIPDB/VirusTotal/v2/notes— Operator Notes (v2 shell)/v2/audit— Audit Trail (v2 shell)
Fixes
- Sign-out now works:
POST /v2/logout(no CSRF required for logout) - Login loader uses
fetch()+ asset prefetch (~2s faster first load) - All AbuseIPDB/VirusTotal links use
rel="noopener noreferrer" - Dashboard live-tail now links to
/v2/timeline
Install
```bash
curl -LO https://github.com/jmrGrav/security-automation-go/releases/download/v1.7.5/security-automation-go_1.7.5_amd64.deb
curl -LO https://github.com/jmrGrav/security-automation-go/releases/download/v1.7.5/SHA256SUMS
sha256sum -c SHA256SUMS
sudo dpkg -i security-automation-go_1.7.5_amd64.deb
sudo systemctl restart cf-sync
```
Playwright smoke: 60 passed / 13 skipped / 0 failed
v1.7.4
[v1.7.4] — 2026-06-22
Summary
Two missions plus a hardening pass. Mission 1 closes the Cloudflare ban lifecycle loop: bans now expire and auto-deban, and auto-ban decisions require corroborating local evidence in addition to AbuseIPDB confidence — confidence=100 alone is never sufficient. Mission 2 introduces the Trusted Networks registry, a hub-and-spoke source of truth for allowlisted ASNs/CIDRs consumed by every ban/report decision point. Also includes local WAF/HTTP-error-burst evidence-only signals, four Codex-audit fixes (#64, #65, #66, #69), and HTTP-level test coverage for the first-run setup wizard (#67).
Added
- Cloudflare ban lifecycle —
internal/services/cfbanlifecycletracks ban expiry and runs a cleanup worker that lifts expired bans automatically. - Reputation-gated auto-ban/auto-deban — auto-ban requires AbuseIPDB confidence=100 and a corroborating local evidence signal (burst counter ≥ 1); confidence alone is rejected. Auto-deban runs on improved reputation. New
reputation_policyconfig block and a Cloudflare Ban Lifecycle UI page. - Trusted Networks registry —
internal/runtime/providerstatehub-and-spoke ASN/CIDR allowlist, single source of truth consumed by ban/report decisions, with an import/export UI. - Local WAF / HTTP-error intelligence —
internal/adapters/wafrefandinternal/adapters/nginxerrorsingest local WAF references and Nginx 4xx/5xx error bursts as evidence-only signals (shadow/enforce gated), surfaced in a new dashboard section. - Setup-wizard test coverage — HTTP-level tests drive the full first-run wizard (steps 1-9) through real session/CSRF-gated handlers, closing the coverage gaps reported in #67.
Fixes
-
#64/#65/#66/#69 — Codex audit findings — see PR #70 for the four individual fixes, including the
/timelinefull-history recomputation on every request (#69), now cached with a bounded TTL. -
/run/crowdsec-luapermission denied afterwww-datagroup grant (PR #74) —cf-syncexchanges files with the OpenResty/Lua CrowdSec bouncer via the sharedroot:www-data 0775directory/run/crowdsec-lua;postinstaddssecurity-automationto thewww-datagroup soopenrestyevent.LiveSourcecan renameevents.jsonl/waf_refs.jsonl. Linux processes keep the supplementary groups they had atexec()time, so acf-syncinstance already running when that group membership is granted or changed keeps failing withpermission denieduntil restarted. Added a packaging regression test (TestPostinst_CrowdsecLuaGroupGrant) and documented the restart/verification steps indocs/operations/RUNBOOK.md.
Operational note
- Upgrades may require a service restart for group membership to take effect. If an upgrade or manual
usermodchanges which groupssecurity-automationbelongs to (e.g. thewww-datagrant above), the already-runningcf-syncprocess does not pick up the change automatically — runsudo systemctl restart cf-syncafterward. Seedocs/operations/RUNBOOK.md, "/run/crowdsec-luapermissions — restart required after group changes".
v1.7.3 — Spamhaus Submit hotfix
Summary
Hotfix: Spamhaus Submit was never wired into the reporting pipeline — the spamhaus.Client interface existed but had no concrete implementation. This release adds SubmitClient (POST /portal/api/v1/submissions/add/ip, Bearer token) and wires it into reporting.Service independently of AbuseIPDB: own 24h per-IP dedup, fail-open on error, independent metrics. AbuseIPDB behaviour is unchanged.
Fixes
- FIX-SPAMHAUS-SUBMIT —
internal/security/enrichment/spamhaus.SubmitClientimplementsClient.Report()viaPOST https://submit.spamhaus.org/portal/api/v1/submissions/add/ipwith Bearer token auth. HTTP 401/403 → auth error, 429 → rate-limit, 5xx → retryable. All errors fail-open (logged WARN, do not affect AbuseIPDB result). - FIX-SPAMHAUS-DEDUP —
spamhausIPDeduptracks submitted IPs with a 24h TTL, independent from AbuseIPDB's dedup window. - FIX-SPAMHAUS-WIRE — startup wiring reads
spamhaus.api_keyfrom credential store and gates on provider-enabled state.
Metrics Added
spamhaus_submit_totalspamhaus_submit_failures_totalspamhaus_submit_dedup_total
Full changelog: see CHANGELOG.md
v1.7.2 — Operability sprint: auto-ban, enrichment, CF fields, nginx UI
Summary
Operability sprint. Fixes two root causes that had silenced AbuseIPDB reporting since June 13. Introduces live IP auto-banning via Cloudflare IP access rules, gated on local evidence corroboration and AbuseIPDB confidence=100. Adds AbuseIPDB enrichment in Forensic/Security Intelligence, CF named fields in Evidence Detail, and Nginx 4xx/5xx access log view.
Auto-ban (new)
- Confidence-100 rule: requires local evidence (≥1 event in last 15min) AND AbuseIPDB score=100
- Burst rule: >30 events in any 30s sub-window per IP
- Full safety gate: trust registry, quota guard, 24h dedup
- Enable live mode: set
auto_ban_enabled=truein SQLiteui_settingstable
Fixes
- FIX-ABUSEIPDB-SILENCE: LeaseGuard gated on strict-HA profile only
- FIX-CHECKPOINT: INSERT OR IGNORE for event checkpoint saves
- FIX-PROVIDER-DIAGNOSTIC: HTTP 401/403 → AUTH_FAILED, 429 → RATE_LIMITED
- FIX-CF-SUPPRESS: CF Custom Rule + Managed Rule blocks now scored correctly
Features
- FEAT-AUTOBAN: Live CF IP access rule enforcement with 22 unit tests
- FEAT-ABUSEIPDB-ENRICHMENT: AbuseIPDB /check in Forensic + Security Intelligence (Manual mode)
- FEAT-EVIDENCE-CF-FIELDS: ray_id, ruleset_id, rule_id, http_method, edge_response_status, country_name, asn_description
- FEAT-NGINX-ACCESS: /nginx-access page — Nginx 4xx/5xx log viewer
- FEAT-PIPELINE-HEALTH: Suppressed breakdown by reason
- FEAT-AI-EXPLAIN: AI Explain consumes AbuseIPDB enrichment + recent evidence records
Install
dpkg -i security-automation-go_1.7.2_amd64.deb
v1.7.1 — UI audit corrections
What's fixed
Timeline — broken evidence links on audit rows
Audit entries carried no real evidence record but generated clickable links pointing at random hex IDs, opening to "Evidence not found" live panels. Two-site fix: clear EvidenceID in the converter and pass the raw empty string to evidenceDetailLinkHTML so it renders "unavailable". WAF evidence rows (real EvidenceID) are unaffected.
Forensic page — enrichment not running in production
handleForensicPage and handleForensicLookup called s.enrichment directly, which is nil in production. Both handlers now use securityIntelligenceService(), the same factory used by the Security Intelligence page, which falls back to config-initialised service.
Table column widths — four data tables
Timeline, WAF Events, Pipeline Health, and Forensic Local Evidence all used table-layout: fixed with no column hints, giving equal width to every column and truncating source names. Added <colgroup> with explicit rem widths per table.
Dashboard counter — developer TODOs removed from disabled count
Replay, Recovery, and Shadow/cutover were listed as disabled: not wired, inflating DisabledCount from 1 (HA/fencing — real architectural boundary) to 4. The three entries are removed.
Install
curl -LO https://github.com/jmrGrav/security-automation-go/releases/download/v1.7.1/security-automation-go_1.7.1_amd64.deb
curl -LO https://github.com/jmrGrav/security-automation-go/releases/download/v1.7.1/SHA256SUMS
sha256sum -c SHA256SUMS
sudo dpkg -i security-automation-go_1.7.1_amd64.deb
sudo systemctl restart cf-syncv1.7.0
v1.7.0
Highlights
- Stable
cf-syncshutdown path and restart behavior. - Provider runtime toggles for non-AI providers with live health refresh.
- AI explain gateway auto-activation from persisted credential state.
- Live operator console polish: dashboard hub, live panels, AJAX refresh, and compact forensic views.
- Security Intelligence, Forensic, Evidence, Timeline, and Pipeline Health coherence fixes.
Release Blockers Resolved
- Dashboard hero contrast and hierarchy.
- Evidence / Timeline side panel fallback and recovery path.
- SQLite
interruptedsymptom from heavy last-event lookup. - AI explain disabled state when a valid provider exists in CredentialStore.
- Provider diagnostics and status contradictions.
Validation
go test ./...go test -race ./...go vet ./...go build ./...NO_RPM=1 make package- Live smoke:
59 passed, 2 skipped
v1.6.4
v1.6.4
Provider credential-store hotfix release.
Included changes
- fix providers non-AI CredentialStore read path
- Spamhaus/VirusTotal/AbuseIPDB UI configured state
- migration old uppercase credential keys vers dotted keys
- lazy quota client init from CredentialStore
- tests/smoke ajoutés
v1.6.3 — Operator protected IP guard, AI model defaults, CF sync clarity
v1.6.3 — Security hardening and observability
Fixes
-
Operator-protected IP guard —
global.protected_hostsYAML field andSECURITY_AUTOMATION_PROTECTED_HOSTSenv var. IPs listed are suppressed before any AbuseIPDB report or Cloudflare propagation via the existing trust registry chokepoint. Includes unit tests and regression guard. -
AI model safe defaults — When a provider is enabled but the model field is empty (e.g. after credential-store migration),
normalizeAIConfignow applies safe defaults:gpt-4.1-mini/claude-sonnet-4-6/gemini-1.5-pro. -
CF ban sync page clarity — Dry-run mode now shows a
DRY-RUNbadge with instructions to enable mutations. Missing decisions source shows config guidance. Mode badge (MUTATIONS ON/DRY-RUN) shown alongside sync status when cycles exist.
Smoke tests
- Replace Key form: CSRF token present, password field not pre-filled, POST without CSRF rejected with 403.
Deployment note
To activate the protected IP guard on the host, add to /etc/security-automation-go/security-automation.env:
SECURITY_AUTOMATION_PROTECTED_HOSTS=82.65.145.189
Then sudo dpkg -i security-automation-go_1.6.3_amd64.deb && sudo systemctl restart cf-sync.