25 Commits

Author SHA1 Message Date
johannes 1b8ac53dd8 docs(claude): slim CLAUDE.md to thin standard, defer architecture to the Guide
Keeps operating essentials (template gate, ports, build/deploy, env, What's New,\nrepo-specific quirks); moves architecture/endpoints/tables/topics to the HiveIQ\nGuide (guide.bcos.dev) which is kept in sync with code. Part of the guide-KB rollout.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:31:29 -04:00
johannes b21e029711 docs(claude): add hiveops-template usage pointer (copy canonical, header=text-only)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 18:09:39 -04:00
johannes b0121c9f44 refactor(aria): standardize API URL — VITE_API_URL=api.bcos.dev/aria
Single VITE_API_URL replaces apiUrl+authUrl. Gateway URL for auth calls
is derived at runtime via apiUrl.replace(/\/aria$/, '').

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 14:40:10 -04:00
johannes 2c957fb072 fix(aria): correct auth users/me endpoint path
Path was /api/auth/users/me but the auth controller is at /auth/api/users/me.
Caused a CORS-then-404 error on every page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 20:23:12 -04:00
johannes dd10b8754a feat(aria): replace countdown toggle with labeled auto-refresh switch
Replace cryptic SVG countdown circle with a clear labeled toggle switch
in ThreatEvents, DevicePosture, and PrecursorAlerts. State is persisted
to localStorage per-component (aria_threats_autoRefresh, aria_posture_autoRefresh,
aria_alerts_autoRefresh).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 10:03:16 -04:00
johannes 7e4b147db8 style: remove bar-filters-active blue highlight from filter sidebar toggle bar
CD - Develop / build-and-deploy (push) Failing after 14m20s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 21:38:04 -04:00
johannes f7e5158446 style: remove light blue background from active-filters chips row
CD - Develop / build-and-deploy (push) Failing after 13m1s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 21:34:18 -04:00
johannes 4dc3636f70 style: align all aria pages to canonical TemplatePage layout
CD - Develop / build-and-deploy (push) Failing after 11m51s
- page-right/content-frame/active-filters now match TemplatePage exactly
- active-filters gets the blue tinted background box (#f0f4ff, border #d0d9f0)
- content-frame uses padding+gap instead of margin-top
- page-right gets padding:0.65rem + gap:0.5rem
- ThreatEvents restructured with content-frame wrapper and toolbar-count
- IocManagement .count renamed to .toolbar-count

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 21:30:31 -04:00
johannes b151bf112c style: standardize ThreatEvents filter chip CSS to canonical template
CD - Develop / build-and-deploy (push) Failing after 10m44s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 21:16:37 -04:00
johannes 7ea07440dc fix(aria): collapse filter sidebar by default on all pages
CD - Develop / build-and-deploy (push) Failing after 11m0s
PrecursorAlerts and ThreatEvents were still starting expanded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 20:51:24 -04:00
johannes 1a47e2dea9 feat(aria): IOC reported_at, threat stats 24h window, filter sidebar, posture UX
CD - Develop / build-and-deploy (push) Failing after 11m51s
- Add reported_at field to threat_ioc (V7 migration) — tracks when the source
  originally published the IOC, distinct from addedAt (ingestion time); wired
  into OTX (created field), MalwareBazaar and ThreatFox (first_seen field),
  and the manual IOC creation endpoint
- Fix threat event stats to use a 24h time window for critical/high counts
  (countBySeverityAndDetectedAtAfter) instead of all-time totals
- Rebuild IOC Management with canonical filter sidebar: collapsible left sidebar
  with per-type toggle pills, active filter chips with individual removal
- DevicePosture: collapse institutions and filter sidebar by default

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 20:45:19 -04:00
johannes 87ad185711 feat(aria): group Device Posture table by institution with collapsible accordion
CD - Develop / build-and-deploy (push) Failing after 14m7s
All institutions expanded by default. Header row shows device count,
avg posture score, and a warning badge when any device scores below 80.
Fetches all records in one call (size=500) instead of paginating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 17:43:10 -04:00
johannes e288bcdfe9 fix(aria): IOC Feeds table — canonical column CSS matching DevicePosture
CD - Develop / build-and-deploy (push) Failing after 15m13s
2026-06-15 22:52:11 -04:00
johannes 75ff2b92fd chore(aria): add frontend CLAUDE.md with mandatory UI pattern rules
CD - Develop / build-and-deploy (push) Failing after 12m33s
2026-06-15 22:44:51 -04:00
johannes 571d88db4d fix(aria): IOC Feeds — restore app, fix API shapes, canonical UI
CD - Develop / build-and-deploy (push) Failing after 10m58s
Root cause: IocFeeds.svelte called feeds.find() on a Map (backend returned
Map<String,Object> not List) → reactive statement crash → entire Svelte tree
broken, all sidebar nav dead.

Backend:
- /feeds/status now returns List<Map> with feedName/configured/enabled/
  lastRunAt/lastRunStatus/lastIocsAdded/lastIocsUpdated fields
- /feeds/runs now returns full Page<IocFeedRun> (not stripped .getContent())
- IocFeedService.isConfigured(feedName) added for per-feed key check
- Feed order fixed to [OTX, MALWARE_BAZAAR, THREAT_FOX] (deterministic)

Frontend:
- loadFeeds: Array.isArray guard prevents crash if shape is ever wrong
- loadRuns: safe fallback for both Page and plain-array responses
- api.ts refreshFeed URL fixed: /feeds/refresh/{name} not /feeds/{name}/refresh
- IocFeedStatus type: added lastIocsUpdated
- IocFeeds.svelte: Refresh All moved from header to toolbar; all buttons
  use canonical btn/btn-primary/btn-secondary/btn-sm classes; pollInterval
  now calls pollStatus (status-only poll) not full refresh trigger

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 22:41:21 -04:00
johannes bdc2504635 feat(aria): Phase 5 — IOC feed refresh from OTX, MalwareBazaar, ThreatFox
CD - Develop / build-and-deploy (push) Failing after 52s
Adds automated daily IOC ingestion from three external threat feeds:
- AlienVault OTX: subscribed pulses + ATM-keyword searches (requires API key)
- MalwareBazaar (abuse.ch): ATM-tagged malware samples, no key required
- ThreatFox (abuse.ch): ATM malware family IOCs, no key required

Backend:
- IocFeedRun entity + V6 Flyway migration (ioc_feed_run table)
- OtxFeedClient / MalwareBazaarFeedClient / ThreatFoxFeedClient
- IocFeedService: upsert dedup + @Scheduled daily 03:00 refresh
- IocFeedController: GET /status, GET /runs, POST /refresh, POST /refresh/{feed}
- ThreatIoc.IocSource enum extended: OTX, MALWARE_BAZAAR, THREAT_FOX

Frontend:
- IocFeeds.svelte: feed status cards, run history table, manual refresh
- App.svelte: IOC Feeds nav item (📡), version string removed from sidebar
- api.ts: getFeedStatus, getFeedRuns, refreshAllFeeds, refreshFeed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:01:09 -04:00
johannes d102a4bf61 fix(posture): page size selector now applies correctly
CD - Develop / build-and-deploy (push) Failing after 10m31s
const → let and pageSizeChange handler was discarding e.detail.size.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:31:51 -04:00
johannes 43b56fb859 fix(frontend): remove version string from sidebar, bump to v1.0.0
CD - Develop / build-and-deploy (push) Failing after 12m52s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:03:14 -04:00
johannes 02d99c8ca2 fix(aria): replace severity pills with select dropdown in ThreatEvents filter sidebar
CD - Develop / build-and-deploy (push) Failing after 12m49s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 16:49:36 -04:00
johannes c78289bfef fix(aria): replace plain Refresh button with canonical circular auto-refresh control
CD - Develop / build-and-deploy (push) Failing after 13m3s
All three list pages (ThreatEvents, PrecursorAlerts, DevicePosture) now
use the template's btn-manual-refresh icon button + SVG countdown timer
in header-controls, matching the canonical TablePage.svelte pattern.
Plain text Refresh button removed from toolbar-right.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 16:39:21 -04:00
johannes 726ccb4ecf fix(aria): correct V3 column names and switch filters to select dropdowns
CD - Develop / build-and-deploy (push) Failing after 13m2s
V3 migration had wrong column names for threat_ioc (source, confidence)
and precursor_sequence_alert (auto_response_taken). Fixed column names
and added phases_detected TEXT[] conversion. PrecursorAlerts and
DevicePosture filter sidebar now uses <select> dropdowns per template
pattern (filter-sidebar structure kept; pill buttons removed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 16:29:22 -04:00
johannes d8fdec4da7 fix(aria): rewrite filter UI to follow canonical template pattern
CD - Develop / build-and-deploy (push) Failing after 13m51s
PrecursorAlerts and DevicePosture were using custom inline select
dropdowns for filtering. Both now use the canonical left filter sidebar
with collapsible status-pills, active filter chips, and content-frame
layout from hiveops-template/TablePage.svelte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 16:18:30 -04:00
johannes 68cee9bd90 feat(aria): Phase 3 — device security posture tracking
CD - Develop / build-and-deploy (push) Failing after 14m13s
Adds per-device security posture reports and compliance dashboard. Agents POST
posture data (disk encryption, audit policy, image hashes, OS version/EOL) to
POST /api/aria/posture/report (service-secret authenticated). DevicePostureService
upserts the record and calculates a 0–100 posture score using a penalty model:
disk encryption off −25, audit policy off −20, OS EOL −20, image hash drift −20,
whitelist off −10, stale check −5/day (capped at −15). REST API adds GET /posture
(filterable by EOL status and score band) and GET /posture/{deviceId}. Stats
endpoint gains lowPostureCount (<50) and eolDeviceCount. Dashboard reorganised
into Threat Activity and Compliance rows. Device Posture SPA view enables the
previously-disabled nav item with score bar, EOL badges, and full detail panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:38:11 -04:00
johannes aa9f8a10ef feat(aria): Phase 2 — precursor sequence detection engine
CD - Develop / build-and-deploy (push) Failing after 11m45s
Adds multi-phase attack sequence detection to ARIA. After each event is
ingested, SequenceDetectionService queries events within a 15-minute window
for the same device and fires a PrecursorSequenceAlert when jackpotting
(PHYSICAL_ACCESS + malware phase) or skimming (PHYSICAL_ACCESS + card reader
tamper/USB) patterns are detected. Confidence is scored 0–1 based on phases
and severity. Detected sequences are published to hiveops.aria.sequences Kafka
topic. Adds REST API (GET /sequences, GET /{id}/events, POST /{id}/resolve) and
enables the Precursor Alerts view in the SPA with filter sidebar, confidence
bar, and event detail slide panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:25:35 -04:00
johannes fe9a252dcd feat(aria): add Svelte SPA frontend and threat events API
CD - Develop / build-and-deploy (push) Failing after 54s
- frontend/: full aria.bcos.dev SPA (port 5187) with Dashboard, Threat Events,
  and IOC Management views; Phase 2-3 nav items disabled as placeholders
- ThreatEventController: GET /api/aria/events (paginated, severity/device filter)
  and GET /api/aria/stats (total/critical/high/activeIoc counts)
- Deployed to bcos.dev: hiveiq-aria-frontend container + aria.bcos.dev NPM proxy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 10:00:07 -04:00