secubox-deb/docs/superpowers/plans
CyberMind bb3c56c2cd
Some checks are pending
License Headers / check (push) Waiting to run
feat(#817): Device Guardian consolidation — merge 5 device modules into secubox-nac (Project A) (#818)
* docs(device-guardian): Project A consolidation design — merge 5 device modules into nac (ref #817)

* docs(device-guardian): Project A implementation plan — 9 tasks (ref #817)

* feat(nac): SQLite device store + idempotent legacy migration (ref #817)

Add packages/secubox-nac/api/store.py — pure-stdlib sqlite3 module with
canon_mac(), DeviceStore (WAL, best-value upsert, list/get/count,
history), and migrate_legacy() for idempotent, per-source best-effort
import of mac-guard/device-intel/iot-guard legacy shapes. Reserved
Project-B columns (plane/provenance/geo_cc/geo_asn) created but unused.

Task 1 of the Device Guardian consolidation plan (docs/superpowers/plans/
2026-07-05-device-guardian-consolidation.md).

* fix(nac): store — preserve first_seen, skip corrupt legacy sources, no stray db, SPDX (ref #817)

* feat(nac): unified dnsmasq+ISC+ARP discovery merge (ref #817)

* fix(nac): discovery — latest ISC lease wins the IP on renewal (ref #817)

The merge loop only updated ip/source on a strict rank increase
(incoming_rank > existing_rank), so equal-rank sightings for the same
MAC never touched ip/source. Since dnsmasq -> isc -> arp is processed
in non-increasing rank order, multiple ISC dhcpd.leases blocks for one
MAC (a fresh block per renewal) are equal-rank ties, and the first
(oldest) block's ip was frozen instead of the latest one winning, as
the original secubox-device-intel._get_dhcp_leases did.

Change the condition to incoming_rank >= existing_rank so the latest
same-or-higher-rank sighting updates source, and overwrites ip when
the incoming ip is non-empty. Hostname rule and the lower-rank branch
are unchanged, so a later ARP sighting still cannot clobber a
higher-rank ip/hostname/source.

Add test_isc_latest_lease_wins: two ISC lease blocks for one MAC with
ip/hostname renewal, asserting the latest block wins. Confirmed this
test fails against the pre-fix >-only logic.

* feat(nac): absorbed enrichers — OUI vendor + device-type/risk + OpenWrt fingerprint (ref #817)

* fix(nac): enrich — is_router strictly vendor-based; cover classify/oui edge cases (ref #817)

* feat(nac): background collector + double-cache; handlers def, no inline scan (ref #817)

Task 4 of the Device Guardian consolidation: a Collector background
loop now owns all discover -> enrich -> upsert work (replacing
_monitor_clients), publishing an in-memory snapshot(). The status,
clients, and client/{mac} handlers become plain def reading the SQLite
store / collector cache instead of calling _discover_clients() inline
on every request -- the #808 aggregator SPOF.

* fix(nac): finish #808 — def-convert alerts/list_quarantine/summary; first_seen + recent_events (ref #817)

alerts/list_quarantine were still `async def` calling blocking
_discover_clients() inline on the shared aggregator loop; summary
awaited alerts on top of that (double loop-block). Converted all three
to plain `def` reading the SQLite store/collector snapshot instead,
completing the #808 SPOF fix started for status/clients/client.

Also: collector.cycle_once() now stamps first_seen on newly discovered
devices (store.upsert keeps the earliest via COALESCE), and get_client's
recent_events merges the SQLite device_history (client_joined) with the
JSON event log so a device's join event shows up again.

* feat(nac): allow/deny actions + def-convert action handlers (finish #808) (ref #817)

Task 5: fold mac-guard's allow/deny into nac's zones/nft. New
POST /allow/{mac} and /deny/{mac} set allow_state in the SQLite store
and mirror it into nft's existing inet secubox_nac blocked/lan_allowed
sets via _nft_add_element/_nft_delete_element (mac-guard's separate
inet secubox_mac_guard table stays retired; its element migration is
Task 9).

Carried from Task 4 review: zones, add_to_zone, remove_from_zone,
approve_client, ban_client, update_client, quarantine_client and
unquarantine were still async def wrapping blocking subprocess/nft
calls on the shared aggregator loop (#808). Converted to plain def so
FastAPI threadpools them off the loop; add_to_zone/ban_client's webhook
notify now fires via a new _fire_webhook_sync helper
(asyncio.run_coroutine_threadsafe against the loop captured at
startup) since a plain def can no longer await _notify_webhooks
directly.

Tests: tests/test_actions.py mocks nft via monkeypatched
_nft_add_element/_nft_delete_element/_nft_list_set (+ subprocess.run,
since ban_client/unban_client build raw nft argv) into an in-memory
set-membership dict; covers deny/allow/allow-then-deny, zones,
add_to_zone+approve_client, and ban_client+unban_client.

* feat(nac): absorbed endpoints — vendors/scan/probe/mdns/groups/export (ref #817)

* fix(nac): /scan enriches + validates subnet; /probe IP + CSV injection guards (ref #817)

* feat(nac): retire mac-guard/device-intel/iot-guard via 308 redirects; auth-gate network-anomaly (ref #817)

secubox-mac-guard, secubox-device-intel and secubox-iot-guard are
superseded by secubox-nac's consolidated Device Guardian. Their
api/main.py are reduced to thin shims: every route 308-redirects to
its secubox-nac equivalent (/devices->/clients, /device/{mac}->
/client/{mac}, /whitelist|/allow->/allow, /blacklist|/deny->/deny,
/scan, /vendors, /groups, /export/* pass through unchanged, and a
catch-all forwards anything else), with an X-SecuBox-Deprecated
header. /health stays a plain 200 so liveness probes never 308-loop.
Package removal is a separate, gated follow-up.

secubox-network-anomaly stays (separate traffic-anomaly engine) but
its /status endpoint was unauthenticated while every sibling route
already required a JWT; it now matches.

* feat(nac): webui — vendor/type/risk columns, groups view, export; drop retired webuis (ref #817)

- clients.js: render enriched /clients fields — oui_vendor, device_type,
  risk_level (color-coded badge)/risk_score, and OpenWrt/SecuBox/Router
  fingerprint badges. All values are attacker-influenceable (DHCP
  hostname/vendor) and are rendered exclusively via E()/textContent,
  never innerHTML. Null/missing device_type/vendor/risk render as
  "unknown"/"—", never "null". Adds an Export CSV button (direct link to
  GET /export/csv — auth via the existing SSO session cookie, same as
  every other same-origin nav link in this app; no new auth scheme).
- groups.js (new): list/create/delete device groups and assign a device
  to a group, hitting GET/POST/DELETE /groups* — mirrors zones.js's
  structure and auth (sbxFetch).
- nav.js: register the new "Groupes" tab alongside Zones.
- Remove packages/secubox-{mac-guard,device-intel,iot-guard}/www — their
  functionality is now consolidated into nac; secubox-network-anomaly/www
  is untouched (stays standalone per plan).

Note for Task 9: device-intel/iot-guard's debian/rules unconditionally
`cp -r www/<name>/.` — now broken since www/ is gone; mac-guard's rule is
already guarded (`[ -d www ] && ... || true`). Needs a debian/rules fix
when Task 9 retires/redirects these packages.

* chore(nac): packaging — ieee-data dep, nft migration, retirement redirects, changelog 3.0.0; fix retired debian/rules www (ref #817)

* fix(nac): whole-branch — lazy init for in-aggregator mount, collector off-loop, sqlite lock, batched zone lookup, sentinel-preserve (ref #817)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(nac): risk_score split — known router low, unknown router high (rogue-AP signal) (ref #817)

Split the router risk axis out of the generic device-type/open-ports
scoring: a router/gateway already known (allow-listed or already in the
store) is trusted infrastructure -> low risk; a newly-seen/unknown
router is a rogue-AP signal -> high risk, regardless of open ports.
Removes the old flat -10 "trusted router" discount. Non-router devices
keep the existing scoring unchanged.

risk_score() gains an is_known=False parameter (backward compatible).
collector.cycle_once() and main.scan() now compute is_known from the
prior store row (existing row or allow_state == "allow") before
upserting, reusing the row they already fetch for is_new/enrichment.

* feat(nac): mesh-sync (p2p peers as devices) + fingerprinted-router classification for rogue-AP risk (ref #817)

Part A: absorb iot-guard's missed "mesh-sync" capability. GET /mesh/peers
and POST /mesh/sync now live in nac, reading live P2P peers over
/run/secubox/p2p.sock (HTTP-over-UDS GET /peers, fail-safe -> [] on any
error/timeout/absent socket) and upserting one sb:-prefixed synthetic
device per peer (iot-guard's exact md5-hash MAC scheme), device_type
"mesh_node", source "mesh". iot-guard's retired redirect-shim catch-all
already forwards /mesh/* here, so no shim change needed.

Part B: classify_device_type's "router" keyword list is much narrower
than ROUTER_VENDORS (misses tp-link/asus/linksys/d-link/gl.inet/xiaomi/
huawei), so a router-vendor MAC with a generic hostname fingerprinted
is_router=True still classified as device_type="unknown" and skipped
risk scoring entirely (the omit-unknown guard) -- the known-router-vs-
rogue-AP HIGH signal never fired for the most common vendor case. Both
enrichment call sites (Collector.cycle_once and /scan) now reclassify
device_type="unknown"+is_router to "router" before scoring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(nac): postinst ensures secubox_nac table + zone sets (incl lxc_zone)

Nothing shipped created nac's inet secubox_nac table or its zone sets — they
were assumed to pre-exist (they don't: the live board had no such table), so
operator 'move to zone' failed for every zone and the mac-guard element
migration silently no-op'd. postinst now creates the table + all ZONES sets
(lan_allowed, lxc_zone, iot_zone, guest_zone, quarantine_zone) + blocked,
idempotently and best-effort, before the migration. Makes operator moves to
the LXC Containers zone work on a fresh install. nft commands validated on
gk2 (create/idempotent re-add/add-element/list), no live drift left.

Co-Authored-By: Gerald KERMA <devel@cybermind.fr>

---------

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 09:58:01 +02:00
..
2026-04-21-eye-remote-v2-implementation.md
2026-04-23-eye-remote-bootstrap.md
2026-04-24-eye-remote-touchscreen-controller.md
2026-04-26-eye-remote-swiss-army.md
2026-05-02-haproxy-webui-crud.md
2026-05-03-mitmproxy-waf-migration.md
2026-05-05-openwrt-to-debian-migration.md
2026-05-10-meta-script-generator.md
2026-05-11-secubox-apt-clone.md
2026-05-12-apt-public-repo-staging.md
2026-05-12-gitea-repair.md
2026-05-12-license-headers.md
2026-05-12-metablog-gitea-ingest.md
2026-05-12-metablog-site-schema.md
2026-05-12-metablog-version-dashboard.md
2026-05-12-multi-agent-worktree-workflow.md
2026-05-12-opad-doctrine-documents.md
2026-05-12-ssl-health-banner.md
2026-05-12-streamlit-gitea-version-pinning.md
2026-05-12-visitor-origin-feed.md
2026-05-12-webui-obfuscation.md
2026-05-13-eye-square-phase1-common-extraction.md
2026-05-13-eye-square-phase2-variant-build.md
2026-05-13-eye-square-phase3-python-kiosk.md
2026-05-13-metablog-deploy-webhook.md
2026-05-13-secubox-users-auth.md
2026-05-14-converged-dashboard.md
2026-05-15-mail-phase1-lxc-consolidation.md
2026-05-15-mail-phase2-rspamd.md
2026-05-16-cookie-audit-pipeline.md
2026-05-16-eye-remote-multi-gadget-dhcp.md
2026-05-18-dropletctl.md
2026-05-20-grafana-yacy-rustdesk-lxc-modules.md
2026-05-22-sentinelle-gsm-v0.3-observation-pipeline.md
2026-05-22-sentinelle-gsm-v0.3.1-l3-scoring-baseline.md
2026-05-22-sentinelle-gsm-webui-local-alerts.md
2026-05-22-streamlit-idle-timeout.md
2026-05-26-build-scripts-refactor.md
2026-05-26-secubox-modules-consolidation.md
2026-05-27-secubox-consolidation-audit.md
2026-06-17-anti-track-v2-core.md
2026-06-17-anti-track-v2-plan2a-learning.md
2026-06-17-anti-track-v2-plan2b-dns.md
2026-06-17-anti-track-v2-plan2b-ip-drop.md
2026-06-17-anti-track-v2-plan2c-bypass-seed.md
2026-06-17-anti-track-v2-plan2d-social-top5.md
2026-06-17-banner-stream-inject-csp-r3-fix.md
2026-06-17-social-ip-literal-fix.md docs: #642 social IP-literal fix design + plan (ref #642) 2026-06-17 16:58:28 +02:00
2026-06-17-toolbox-clients-reset-all-and-emojis.md docs: #clients reset-all + emojis implementation plan (ref #634, #635) 2026-06-17 16:01:03 +02:00
2026-06-18-ad-intelligence.md docs: implementation plan for Ad Intelligence (#656) 2026-06-18 13:06:26 +02:00
2026-06-18-hub-dashboard-latency.md docs: spec + plan for hub dashboard latency fix (ref #644) 2026-06-18 08:45:31 +02:00
2026-06-18-mitm-engine-migration.md feat(#662 Phase 1): MITM-engine migration analysis + phased plan + compiled/tested Go forging-MITM PoC 2026-06-18 17:07:48 +02:00
2026-06-18-toolbox-selective-sni-splice.md docs: implementation plan for toolbox selective SNI-splice (#649) 2026-06-18 11:09:02 +02:00
2026-06-26-cookies-crosssite-trackers.md docs(cookies): implementation plan — cross-site tracker detection (ref #749) 2026-06-26 18:04:01 +02:00
2026-06-26-waf-go-sbxwaf.md docs(plan): WAF→Go sbxwaf implementation plan, 10 phases TDD (ref #744) 2026-06-26 12:04:25 +02:00
2026-06-27-ads-aggregate-mitm-stats.md docs(toolbox): implementation plan — #ads aggregate MITM stats (ref #755) 2026-06-27 08:54:57 +02:00
2026-06-27-nft-based-network-stats.md docs(netstats): implementation plan — 11 TDD tasks (ref #758) 2026-06-27 10:54:47 +02:00
2026-06-27-sw-neuter-targeted-autolearn.md docs(toolbox-ng): implementation plan — targeted SW-neuter (ref #753) 2026-06-27 08:19:59 +02:00
2026-06-27-sw-revalidation-nudge.md docs(sbxmitm): plan — SW revalidation nudge (ref #757) 2026-06-27 09:40:32 +02:00
2026-06-29-gondwana-phase1-mesh-substrate.md docs(gondwana): fix P1 plan version bump 1.7.2->1.7.6 (1.7.5 already shipped) 2026-06-29 10:38:39 +02:00
2026-06-30-annuaire-service-offers-subscriptions.md feat(annuaire): service model (ServiceOffer/Subscription, ApprovalMode, ops) + design plan 2026-06-30 08:07:10 +02:00
2026-06-30-gondwana-p2p-clone-distribute-emancipate.md feat(annuaire): directory primitives — NodeRecord + ConfigBlob models (ref #768) 2026-06-30 09:22:37 +02:00
2026-06-30-p2p-annuaire-service-registry.md docs(p2p): implementation plan — Service Registry as live annuaire catalog view (M1) 2026-06-30 12:19:27 +02:00
2026-07-01-macro-subsystem-tor-exit.md docs(macro): M2 implementation plan — macro subsystem + tor-exit (3 packages) 2026-07-01 07:15:35 +02:00
2026-07-02-p2p-dht-federation-masterlink.md secubox-p2p: Kademlia DHT + federation health-checks + hierarchical master-link (#774) (#775) 2026-07-03 06:59:35 +02:00
2026-07-03-rapport-kbin-media-types.md Rapport kbin fidèle (PDF donut-grids + media types) + WebUI DPI + incident hardening (#787) 2026-07-03 12:27:28 +02:00
2026-07-03-secubox-proxypac.md feat(proxypac): WPAD/PAC auto-config routing to active mesh services (Closes #784) (#788) 2026-07-03 11:57:26 +02:00
2026-07-04-media-buffer-phase1.md feat: SecuBox Media Buffer Phase 1 — dashcam capture + replay + metatag lifecycle (#814) 2026-07-04 18:15:58 +02:00
2026-07-04-media-buffer-phase2-hls.md feat: SecuBox Media Buffer Phase 1 — dashcam capture + replay + metatag lifecycle (#814) 2026-07-04 18:15:58 +02:00
2026-07-04-mesh-federate-exclusion-lists.md docs(plan): mesh-federate toolbox exclusion lists — 5-task TDD plan (#806) 2026-07-04 17:06:45 +02:00
2026-07-04-pdf-character-sheet.md PDF report: rich character sheet + route parity + real Quêtes (#794) 2026-07-04 06:31:30 +02:00
2026-07-04-peertube-webui-admin-ops.md PeerTube WebUI: admin reset-password + version check/upgrade (#800) 2026-07-04 10:12:08 +02:00
2026-07-04-vhost-exposure-switch.md docs(plan): per-vhost exposure switch 8-task TDD plan (ref #793) 2026-07-04 06:29:54 +02:00
2026-07-05-device-guardian-consolidation.md feat(#817): Device Guardian consolidation — merge 5 device modules into secubox-nac (Project A) (#818) 2026-07-13 09:58:01 +02:00
2026-07-06-frigate-foundation.md feat(frigate): Frigate NVR Foundation — podman-in-LXC on amd64 + /api/v1/frigate shim (#821) (#822) 2026-07-06 11:53:20 +02:00
2026-07-06-sbxmitm-sentinel.md feat(sentinel): sbxmitm Sentinel — inline+async exploit/malware/spyware detection engine (#823) (#824) 2026-07-06 15:53:21 +02:00
2026-07-06-sentinel-activation-toolbox-surfaces.md feat(toolbox): activate Sentinel + surface compromise detections (WebUI tab · kbin report · PDF) — ref #823 (#825) 2026-07-06 17:39:42 +02:00
2026-07-07-sentinel-c2-autolearn.md feat(sentinel): C2/botnet auto-learning — high-precision, report-only (Closes #826) (#827) 2026-07-07 07:46:19 +02:00
2026-07-08-nextcloud-dashboard-real-manageable.md docs: plan addendum — real /storage via nextcloudctl (fold b715 #429) (ref #429) 2026-07-08 07:22:10 +02:00
2026-07-09-openclaw-lxc-scanner.md docs(openclaw): tighten target regex in plan (reject leading-dash flag-injection) 2026-07-09 05:55:37 +02:00
2026-07-09-tor-enhancement-phase1.md docs(tor-plan): Task 7 webui must warn about IPv6 leak on routed VPN clients (Task 3 limitation) 2026-07-09 08:44:01 +02:00
2026-07-11-metablogizer-publisher-wizard.md docs: implementation plan for MetaBlogizer Publisher Wizard (11 tasks, TDD) 2026-07-11 12:44:58 +02:00
2026-07-12-metalogue-osint-lxc.md docs: track metalogue OSINT suite (#845) — wiki + WIP + HISTORY + TODO 2026-07-13 05:44:28 +02:00