NIS2 & SecNumCloud Compliance¶
Document type: Compliance evidence
Applicable regulations: NIS2 Directive (EU) 2022/2555 · ANSSI SecNumCloud
Repod version: 1.x
Date: 2026-05-12
NIS2 Overview¶
The NIS2 Directive (Network and Information Security, version 2) entered into force across EU member states on 18 October 2024. Article 21 requires "essential" and "important" entities to implement technical and organisational measures proportionate to the risk, covering at minimum:
- Risk analysis and information system security policies
- Incident handling
- Business continuity
- Supply chain security ← directly addressed by Repod
- Security in network and information systems acquisition
- Policies on cryptography
- Access control
- Vulnerability management
Repod addresses the supply chain security and vulnerability management requirements that apply to organisations distributing or consuming Debian packages internally.
Article 21 Compliance Matrix¶
Supply chain security¶
| Requirement | Status | How Repod addresses it |
|---|---|---|
| Verify integrity of software before deployment | ✅ | SHA-256 provenance check against upstream Packages.gz index on every upload |
| Scan for known vulnerabilities before deployment | ✅ | Grype CVE scan (NVD, GitHub Advisory, CISA KEV databases) on every upload |
| Block or review packages with critical vulnerabilities | ✅ (Enterprise) | Configurable CVE policy: block (quarantine) or review (CISO queue) per severity |
| Maintain a software inventory | ✅ (Enterprise) | SBOM in CycloneDX 1.5 and SPDX 2.3 per package and per repository |
| Trace who introduced which software component | ✅ | Immutable audit trail: every upload logged with user, role, timestamp, source IP |
| GPG signing of distributed packages | ✅ | Integrated GPG signing; clients verify signatures via apt |
| Antivirus scanning of software artifacts | ✅ | ClamAV scan with daily signature updates on every upload |
Access control¶
| Requirement | Status | How Repod addresses it |
|---|---|---|
| Role-based access control | ✅ | 5 roles: reader, uploader, maintainer, auditor, admin |
| Least privilege principle | ✅ | CI/CD systems get uploader only; CISO gets auditor; no over-provisioning |
| Separation of duties (CVE approval) | ✅ | Only admin can approve CVE-flagged packages; uploader cannot |
| Multi-factor authentication | ❌ | MFA not implemented in v1 — mitigate with LDAP + your IdP's MFA |
| Enterprise directory integration | ✅ | LDAP / Active Directory with group-to-role mapping |
| API token management | ✅ | Short-lived tokens with role scoping; revocable immediately |
| Account disabling | ✅ | is_active flag checked on every request; disabling blocks existing sessions |
Logging and monitoring¶
| Requirement | Status | How Repod addresses it |
|---|---|---|
| Log all privileged actions | ✅ | Event types including all user management, config changes, CVE decisions, AV updates, sync operations |
| Log authentication events (success + failure) | ✅ | LOGIN with result SUCCESS / FAILURE and source IP |
| Tamper-evident logs | ✅ | Append-only JSONL files; no API to modify or delete log entries |
| Configurable retention | ✅ | retention_days setting; default 90 days |
| SIEM-compatible export | ✅ | JSONL format; GET /artifacts/audit/logs API endpoint |
Cryptography¶
| Requirement | Status | How Repod addresses it |
|---|---|---|
| Encrypted credentials at rest | ✅ | Passwords hashed with bcrypt (passlib); never stored in plaintext |
| Encrypted tokens | ✅ | Reset tokens and API tokens stored as SHA-256 hashes only |
| Signed repository | ✅ | GPG-signed Release files; clients verify with apt |
| Encrypted communications | Delegated | TLS terminated at reverse proxy (see Reverse Proxy guide) |
Vulnerability management¶
| Requirement | Status | How Repod addresses it |
|---|---|---|
| Identify vulnerabilities in deployed software | ✅ | Grype scans every incoming package; results stored per-package |
| Prioritise remediation | ✅ | EPSS probability score + CISA KEV flag per CVE for risk-based prioritisation |
| SLA for vulnerability decisions | ✅ | Configurable SLA per severity (default: Critical=0d, High=30d, Medium=90d) |
| Document vulnerability decisions | ✅ | Mandatory justification text on approve/reject; permanently logged |
ANSSI SecNumCloud Mapping¶
| SecNumCloud requirement | Status | Evidence |
|---|---|---|
| Software inventory (SBOM) | ✅ | CycloneDX 1.5 · SPDX 2.3 per package; export API available |
| Audit trail | ✅ | Append-only JSONL; 19 event types; configurable retention |
| Access control | ✅ | RBAC 5 roles; LDAP integration; API tokens |
| Environment separation | ✅ | Docker containers with isolated networks; no Docker socket in production |
| Encryption in transit | Delegated | Reverse proxy (Nginx / Traefik / Caddy) handles TLS |
| Encryption at rest | ❌ | Volume /repos not encrypted by default — implement at OS/infrastructure level (dm-crypt, LUKS, encrypted EBS) |
| Key management | Partial | GPG integrated; JWT secret validated at startup; HSM not supported |
| Vulnerability management | ✅ | Grype + CISO review queue + EPSS + CISA KEV |
Evidence Package for Auditors¶
The following artefacts can be collected and attached to an audit dossier:
1 — Software Bill of Materials¶
# Full repository SBOM (CycloneDX)
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/sbom/export?format=cyclonedx&distribution=jammy" \
-o sbom-jammy-$(date +%Y%m%d).cdx.json
# Full repository SBOM (SPDX)
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/sbom/export?format=spdx&distribution=jammy" \
-o sbom-jammy-$(date +%Y%m%d).spdx.json
2 — Audit log export¶
# Export audit logs for a date range
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/artifacts/audit/logs" \
-o audit-$(date +%Y%m%d).jsonl
3 — Vulnerability posture report¶
# All CVEs across all packages
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/security/vulnerabilities" \
-o cve-posture-$(date +%Y%m%d).json
# Packages awaiting CISO review
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/security/review-queue" \
-o pending-review-$(date +%Y%m%d).json
4 — Security report (comprehensive audit evidence)¶
# Full security report: CVE totals, all decisions, pending review, policy in effect
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/security/report" \
-o security-report-$(date +%Y%m%d).json
5 — Configuration snapshot¶
# Settings (secrets masked automatically — Enterprise only)
curl -s -H "Authorization: Bearer $TOKEN" \
"http://REPO_HOST:8000/settings/" \
-o settings-$(date +%Y%m%d).json
6 — Downloadable NIS2 PDF report¶
GET /compliance/nis2-report.pdf renders the same posture and
decisions-history data as items 3 and 4 above into a single, standalone
PDF — combining CVE exposure posture, SLA compliance, and recent security
decisions — meant to be handed directly to an auditor, management, or a
compliance officer without further assembly. It can be scoped to a period
(security-decisions history only) and/or a subset of machines (tags and/or
explicit client IDs, unioned). See Generate a NIS2 compliance
report for the full parameter reference and
worked examples.
curl -s "http://REPO_HOST:8000/api/v1/compliance/nis2-report.pdf" \
-H "Authorization: Bearer $TOKEN" \
-o nis2-report-$(date +%Y%m%d).pdf
CVE posture is a live snapshot; only the decisions history is period-filtered
period_start/period_end filter only the security-decisions
history section of the report. The CVE exposure/SLA posture figures are
always computed at generation time — there is no time-series store for
this data, so a report generated today with a January period shows
today's posture alongside January's decisions, never a reconstruction of
what the posture looked like in January. The report itself states this
explicitly. Some sections requiring regulatory judgment the application
cannot derive on its own (organisational measures, incident-response
procedures, supplier risk assessments) render as an explicit
[À VALIDER: …] placeholder — a labeled gap for your compliance/GRC
team to complete before the PDF is used as a finished audit artifact,
not a section to send to an external auditor as-is.
Limitations and Residual Risks¶
The following limitations are known and should be documented in your risk treatment plan:
| Limitation | Residual risk | Recommended mitigation |
|---|---|---|
| TOTP MFA available but opt-in by default | Low — mandatory-MFA policy with a grace period can be enabled for admin accounts | Enable the mandatory admin MFA policy; enforce MFA at IdP level for LDAP/OIDC-federated accounts |
Volume /repos not encrypted by default |
Medium (if physical access to storage is a threat) | Use LUKS, dm-crypt, or encrypted cloud volumes |
| TLS terminated at reverse proxy | Low — internal traffic is within the same host/network | Use mutual TLS for internal services if threat model requires it |
| Single-node by default (multi-replica HA available) | Low — active/passive HA is available for deployments that require it | Deploy with the HA overlay + external HA PostgreSQL for availability-critical environments |
unsafe-inline in CSP |
Low — internal UI, no user-generated content in scripts | Planned remediation with nonce-based CSP |
Responsible Disclosure¶
To report a security vulnerability in Repod:
- Email: security@[your-organisation]
- PGP: [your PGP key fingerprint]
- Response SLA: acknowledgement within 72 hours, fix within 30 days for Critical/High
Do not report vulnerabilities through public issue trackers.
Generated for Repod v1.x — 2026-05-12
For the full security dossier including RBAC matrix and infrastructure hardening details, see Security dossier (CISO).