# NIS2 technical gap checklist
# Checklist de brechas técnicas NIS2

Pikas Systems — 26 Aug 2026
Not legal advice. A map from Directive (EU) 2022/2555 Arts. 20, 21 and 23 to evidence
your platform can produce. Fill the last column: **have** / **gap** / **n/a**.
If the evidence is not in git, write the system of record instead.

Esto no es asesoramiento jurídico. Traduce los arts. 20, 21 y 23 de la
Directiva (UE) 2022/2555 a evidencia que tu plataforma puede producir.
Rellena la última columna: **sí** / **brecha** / **n/a**.
Si la evidencia no está en git, escribe el sistema de registro.

Sources / fuentes:
- Directive (EU) 2022/2555, Arts. 20–23 — https://eur-lex.europa.eu/eli/dir/2022/2555/oj
- Commission Implementing Regulation (EU) 2024/2690 (digital infrastructure / ICT
  service management — direct application, no Spanish law required)
  — https://eur-lex.europa.eu/eli/reg_impl/2024/2690/oj

How to use: for each row, a reviewer who does not own the system should be able
to open the path and see the proof in under five minutes. A policy with no
artifact is a gap.

---

## Article 21(2) — risk-management measures

| # | Measure (EN) | Medida (ES) | Evidence in the repo / Evidencia en el repo | Have? |
|---|---|---|---|---|
| 21(2)(a) | Policies on risk analysis and information system security | Políticas de análisis de riesgo y seguridad de los sistemas de información | `docs/security/risk-register.md` (owners, last review date, residual risk accepted by name). Policy-as-code under `policies/` if you enforce it. A PDF in a shared drive is not this row. | |
| 21(2)(b) | Incident handling | Gestión de incidentes | `docs/runbooks/incident.md` executed, not drafted. On-call routing in code (`observability/` or Terraform for PagerDuty/Opsgenie). Ticket template that captures: detection time, awareness time, customer impact, IoCs. | |
| 21(2)(c) | Business continuity, backup management, disaster recovery, crisis management | Continuidad, copias, recuperación ante desastres, gestión de crisis | Backup resources declared in Terraform/Pulumi. `docs/runbooks/restore.md`. Last restore job in CI or a dated log: what was restored, how long, who authorised it. A bucket that exists is not a restore. | |
| 21(2)(d) | Supply chain security, including direct suppliers and service providers | Seguridad de la cadena de suministro, incluidos proveedores directos | `docs/suppliers.md`: who can break production, contract owner, last review. SBOM published per release (`syft` / CycloneDX artifact next to the image). Signed artifacts and pinned digests in the deploy path. Vendor access via federated identity, not a shared user. | |
| 21(2)(e) | Security in acquisition, development and maintenance, including vulnerability handling and disclosure | Seguridad en adquisición, desarrollo y mantenimiento, incluido el tratamiento de vulnerabilidades | One path to production: reproducible build, promote-by-digest, policy on the plan. Vuln tickets with an SLA in the tracker, not a scanner dashboard nobody opens. Disclosure contact in `SECURITY.md`. | |
| 21(2)(f) | Policies and procedures to assess the effectiveness of the measures | Políticas y procedimientos para evaluar la eficacia de las medidas | Scheduled jobs: restore drill, failover drill, secret rotation proof, drift detection that opens a ticket. `docs/audits/` with date, finding, owner, due date. A pentest PDF with no ticket is theatre. | |
| 21(2)(g) | Basic cyber hygiene and cybersecurity training | Higiene básica y formación | Baseline as code (CIS-ish): disk encryption, automatic updates, no local admin by default. Training records: management (Art. 20(2)) and staff. If this lives in HR, write the system of record and the last completion rate. | |
| 21(2)(h) | Cryptography and, where appropriate, encryption | Criptografía y, cuando proceda, cifrado | TLS policy and cipher baseline in ingress/Terraform. Encryption at rest as a module default, not a per-resource flag. Key lifecycle: where keys live, who can use them, rotation date. No secrets in Terraform state or CI variables. | |
| 21(2)(i) | Human resources security, access control, asset management | Seguridad de los recursos humanos, control de acceso, gestión de activos | Joiner–mover–leaver in IdP groups as code. Inventory of human console users and access-key age (IAM query, not a spreadsheet). Asset list that matches the bill: accounts, clusters, registries, SaaS admins. | |
| 21(2)(j) | MFA or continuous authentication; secured voice, video and text; secured emergency communications | MFA o autenticación continua; comunicaciones de voz, vídeo y texto seguras; comunicaciones de emergencia | MFA enforced at the IdP for humans. No long-lived credentials in CI: OIDC per job, distinct plan/apply roles. Break-glass role: short session, two-person approval, audit trail. Emergency comms channel that is not the production Slack workspace you just lost. | |

## Article 23 — the notification clock

The clock in Art. 23(4) starts when you **become aware**. If a customer is the first
to know, you still have 24 hours from that moment — and you have already failed
the detection duty that makes the clock usable.

El reloj del art. 23(4) empieza cuando **tienes conocimiento**. Si el primer
aviso llega de un cliente, aún tienes 24 horas desde ese momento — y ya has
fallado el deber de detección que hace útil el reloj.

| # | Measure (EN) | Medida (ES) | Evidence in the repo / Evidencia en el repo | Have? |
|---|---|---|---|---|
| 23(4)(a) | Early warning within 24h of becoming aware | Alerta temprana en 24 h desde el conocimiento | Alert that pages a human on customer-visible impact, not on CPU. Runbook: who files, to which CSIRT (INCIBE-CERT / CCN-CERT), with what template. Time from detect → aware is measured. | |
| 23(4)(b) | Incident notification within 72h | Notificación del incidente en 72 h | Same template plus initial severity, impact, IoCs. Owner who can file without waiting for a board meeting. | |
| 23(4)(d) | Final report within one month of the 72h notification | Informe final en un mes desde la notificación de 72 h | Timeline reconstructed from logs you still have: first event, containment, root cause, measures still open. Retention long enough to do this. | |
| 23(1) | Notify recipients of services when the incident is likely to affect them | Notificar a los destinatarios del servicio cuando el incidente pueda afectarles | Customer-comms template and the list of who gets it. Not a tweet drafted during the incident. | |

## Article 20 — management responsibility

Personal for the management body. In practice: a report the platform produces
on a schedule, that a board member can read without a translator.

Personal para el órgano de dirección. En la práctica: un informe que la
plataforma produce con calendario, que un consejero puede leer sin traductor.

| # | Measure (EN) | Medida (ES) | Evidence in the repo / Evidencia en el repo | Have? |
|---|---|---|---|---|
| 20(1) | Management body approves the Art. 21 measures, oversees implementation, can be held liable | El órgano de dirección aprueba las medidas del art. 21, supervisa e incurre en responsabilidad | Named approver on the risk register. Recurring board pack (below) generated from the same sources as production, not from a slide rebuilt by hand. | |
| 20(2) | Management body follows cybersecurity training | El órgano de dirección recibe formación en ciberseguridad | Date of last session, attendance, material. Encouraged for staff on a regular basis. | |

### Board pack — what the report contains

Generate this from the platform. If a human has to copy-paste it, it will be late.

1. Open significant incidents: detect time, aware time, customer impact, status.
2. MTTD / MTTR for the last quarter, and whether the 24h early-warning path was rehearsed.
3. Vulnerabilities past SLA, by service, with owner.
4. Last backup restore: date, scope, duration, who authorised it.
5. Privileged access: human console users, access keys older than 90 days, MFA coverage.
6. Supply chain: unsigned artifacts still in the deploy path; suppliers without a named owner.
7. Training: management completion; % of staff overdue.
8. Residual risks the board is explicitly accepting this quarter (named, dated).

---

Send the filled last column to hola@pikas.systems with two lines about your stack.
Within 24h you get back what you already cover and what you do not.

Envía la última columna rellena a hola@pikas.systems con dos líneas sobre tu stack.
En 24 h te devolvemos qué tienes ya cubierto y qué no.
