feat: add NIS2 landing page, roadmap page, and compliance section
CI / TypeScript — type-check (push) Successful in 8s
CI / Publish — build & push image (push) Successful in 7s
CI / Deploy — pull & restart on host (push) Successful in 2s

- New /nis2 page: full Art. 21 mapping with covered/partial/roadmap/n-a
  tags, evidence-by-trigger breakdown, and roadmap callout
- New /roadmap page: planned and under-consideration items, NIS2-tagged
  items highlighted with monospace badge
- Home: new NIS2 section between screenshots and plugin block — Art. 21
  mapping list + MockCompliance UI + link to /nis2
- Features: new "Compliance & Audit (NIS2)" section
- Nav: Roadmap link added; NIS2 in Docs dropdown
- Footer: Roadmap and NIS2 links added
- docs/PRODUCT.md: NIS2 evidence foundation as value proposition #9
- docs/PAGES.md: /nis2, /roadmap, and NIS2 home section documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-28 11:35:37 +02:00
co-authored by Claude Sonnet 4.6
parent 0f6ec6241f
commit f194c379e4
9 changed files with 638 additions and 1 deletions
+143
View File
@@ -0,0 +1,143 @@
type Item = {
title: string
detail: string
nis2?: boolean
}
type Group = {
label: string
items: Item[]
}
const GROUPS: Group[] = [
{
label: 'Planned',
items: [
{
title: 'CVE tracking per device',
detail:
'Cross-reference installed packages and OS versions against NVD / OSV. Surfaces "this device has 3 unpatched CVEs (CVSS ≥ 7)" without leaving netOrk.',
nis2: true,
},
{
title: 'Configuration backup & versioning',
detail:
'Git-backed config snapshots on every poll. Detect unauthorized changes between snapshots and provide rollback targets.',
nis2: true,
},
{
title: 'Compliance dashboard',
detail:
'Per-site Art. 21 checklist: asset coverage, patch status, security agent deployment, config drift, syslog forwarding, audit activity — aggregated into a single view.',
nis2: true,
},
{
title: 'Audit log export',
detail:
'PDF and CSV export of the audit log, filtered by date range, device, user, or action type. For NIS2 audit submissions and internal reviews.',
nis2: true,
},
{
title: 'Webhook engine',
detail:
'Outbound HTTP webhooks for events: device discovered, config change detected, job failed, alert threshold exceeded. HMAC-SHA256 payload signing. Integrates with n8n, Slack, PagerDuty.',
},
{
title: 'Live job log streaming',
detail:
'WebSocket endpoint for real-time Celery task output in the UI. Currently streamed via SSE for fix-flows; full job log streaming for all long-running operations.',
},
{
title: 'NetBox sync — manual trigger & status view',
detail:
'POST /api/v1/netbox/sync endpoint with progress feedback and a sync history view in the UI. Currently sync runs automatically; the manual trigger and status are missing.',
},
],
},
{
label: 'Under consideration',
items: [
{
title: 'Incident workflow',
detail:
'Structured incident record tied to devices and security events. Fristen-Tracker for NIS2 Art. 23 reporting windows (24 h early warning, 72 h full notification). Webhook to external ticketing systems.',
nis2: true,
},
{
title: 'EOL tracking for firmware and OS',
detail:
'Flag devices running end-of-life software via the endoflife.date API. Covers OPNsense, OpenWRT, Debian, Ubuntu, and more — matched to the OS versions netOrk already polls.',
nis2: true,
},
{
title: 'MFA (TOTP) for netOrk login',
detail:
'Time-based one-time passwords as a second factor for netOrk user accounts. Directly covers NIS2 Art. 21 (2i) MFA requirement for administrative access.',
nis2: true,
},
{
title: 'mDNS scanner',
detail:
'Discover media devices (Apple TV, Chromecast, Sonos) via mDNS/Bonjour without needing a NAPALM driver. Inventory visibility and firewall segmentation suggestions.',
},
{
title: 'Prometheus metrics + Grafana dashboards',
detail:
'Expose per-device SNMP health metrics as a Prometheus scrape endpoint. Pre-built Grafana dashboard for interface counters, CPU, memory, and poll lag.',
},
{
title: 'Kubernetes Helm chart',
detail:
'Helm chart for production-grade deployments: horizontal scaling for the API and worker pods, Secrets via Vault Agent Injector, Ingress with TLS termination.',
},
],
},
]
function Nis2Badge() {
return (
<span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-mono font-semibold bg-sky-500/10 text-sky-400 border border-sky-500/20">
NIS2
</span>
)
}
export default function Roadmap() {
return (
<div className="py-16 md:py-24">
<div className="max-w-4xl mx-auto px-6">
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-bold text-slate-100 mb-4">Roadmap</h1>
<p className="text-base text-slate-400 leading-relaxed max-w-xl">
What's being built and what's being evaluated. Items tagged{' '}
<Nis2Badge /> directly address NIS2 Art. 21 technical baseline requirements.
</p>
</div>
<div className="space-y-14">
{GROUPS.map((group) => (
<div key={group.label}>
<h2 className="text-xl font-semibold text-slate-200 mb-6 pb-2 border-b border-slate-800">
{group.label}
</h2>
<div className="space-y-6">
{group.items.map((item) => (
<div key={item.title} className="flex gap-4">
<div className="mt-1 shrink-0 h-1.5 w-1.5 rounded-full bg-sky-500 mt-2" />
<div>
<div className="flex items-center gap-2 mb-1">
<span className="text-sm font-medium text-slate-200">{item.title}</span>
{item.nis2 && <Nis2Badge />}
</div>
<p className="text-sm text-slate-500 leading-relaxed">{item.detail}</p>
</div>
</div>
))}
</div>
</div>
))}
</div>
</div>
</div>
)
}