Compliance and Evidence – Proving Rather Than Declaring¶
Machine translation of the French original.
A dashboard that displays "compliant" in green answers a question that no one asks. An auditor would ask something else: "How do you know that it was true at that date, and that the evidence hasn't been tampered with since?"
This page describes how the park responds to this question: a catalog of controls, probes that measure, a status that cannot be manually verified, and a record that cannot be rewritten without being noticed.
The technical terms refer to the glossary.
What "compliant" can mean here¶
Two frameworks serve as a benchmark, and neither applies strictly:
- NIS2 requires entities that are essential and important to the Union. A private park is not one of them. The directive serves as a measurement framework: its ten minimum measures (Article 21 §2) and its notification mechanism (Article 23) provide a good inventory of what a serious defense should cover.
- SOC 2 is a report prepared by an accredited auditor, over a period. No tool is "SOC 2 certified", and a product that claims to be so confuses the report with the audit file. However, a tool can produce the evidence file that the auditor would request.
That's what the park does: a catalog of controls, measured evidence, a status derived from the evidence, and an export – and the uncovered criteria, displayed as such rather than hidden.
flowchart LR
classDef src fill:#3f3f46,stroke:#3f3f46,color:#fff
classDef proof fill:#1e40af,stroke:#1e40af,color:#fff
classDef out fill:#0f766e,stroke:#0f766e,color:#fff
cat["Catalogue de contrôles<br/>versionné dans git"]:::src
son["Sondes<br/>pass · fail · indeterminate"]:::src
att["Attestations humaines<br/>session authentifiée · expiration"]:::src
tri["Gestes de triage<br/>avant → après · auteur"]:::src
run["Lanceur<br/>toutes les six heures"]:::proof
reg["Registre chaîné<br/>ajout seul · SHA-256"]:::proof
anc["Ancre quotidienne<br/>git, deux dépôts distants"]:::proof
der["Statut DÉRIVÉ<br/>recalculé à chaque lecture"]:::out
tab["Tableau de conformité"]:::out
exp["Dossier d'audit"]:::out
cat --> run
son --> run --> reg
att --> reg
tri --> reg
reg --> anc
reg --> der --> tab
der --> exp
1. The Common Controls Catalog¶
A control is a security measure that can be proven to work. The catalog contains around thirty of them. Each one includes:
- a goal, in one sentence;
- the NIS2 articles and SOC 2 criteria it addresses – a single control serves both frameworks (common controls);
- its evidence sources: one or more probes, an attestation, or both.
The catalog is a versioned file in Git. Each version also registers itself: we not only know what was proven at a given date, but also what we required at that date.
How does the catalog cover the ten measures of Article 21 §2:
| NIS2, Art. 21 §2 | What the catalog requires | SOC 2 | Evidence |
|---|---|---|---|
| a) Risk analysis | Written risk analysis and blind spots, annual review | CC3 | Attestation |
| b) Incident management | SIEM and alerting, runtime detection, network IDS, file system monitoring, threat intelligence, automated response, incident investigation | CC7 | Probes |
| c) Continuity, backups, crisis management | Immutable backups, proven recovery, offline master key | A1, CC9 | Probes + Attestation |
| d) Supply chain | Version quarantine, SBOM, review of critical vendors | CC8, CC9 | Probes + Attestation |
| e) Development and maintenance security, vulnerabilities | Continuous scanning, remediation of identified vulnerabilities, change traceability, patches, perimeter blocking | CC6, CC7, CC8 | Probes |
| f) Effectiveness evaluation | Integrity of evidence log, quarterly review of controls | CC4 | Probe + Attestation |
| g) Cybersecurity and training | Patches, CIS hardening, operator competency | CC1, CC5 | Probes + Attestation |
| h) Cryptography | Valid certificates, master key | CC6 | Probes |
| i) Access control, asset management | Inventory and persistence, SBOM, absence of clear secrets on hosts | CC6, C1 | Probes |
| j) Multi-factor authentication, secure communications | MFA on privileged accounts, out-of-band crisis channel | CC6, CC2 | Probe + Attestation |
This is supplemented by Article 20 (Responsibility and oversight: an annual attestation) and Article 23 (Notification: the incident log).
2. The Probes¶
A probe is a script that measures a fact and delivers a verdict. Its contract is short, and each clause has a reason:
| Clause | Reason |
|---|---|
| A single JSON line as output: identifier, verdict, observed fact, detail, measurement date | A single trigger, a unique format, no interpretation |
Verdict among pass, fail, indeterminate |
Three states, because there are three situations |
Unreachable target → indeterminate, never pass |
The absence of a response is not a measurement |
Output as success as soon as a verdict is delivered, even fail |
A failed check is not a faulty probe |
| Less than one minute | A slow probe is a probe that eventually gets disabled |
| No secrets in the output | The detail goes into a log that others read |
| Header: what it proves, what it does not prove, the command that caused it to fail | A probe that has never turned red measures nothing |
{"probe": "<identifiant>", "status": "pass",
"observed": "<le fait mesuré, en une phrase>",
"detail": {"...": "..."}, "measured_at": "<date ISO 8601>"}
The last clause is the most important. Before being accepted, each probe undergoes its reverse verification: we deliberately create the situation that it must detect, and we watch it turn red. A probe that cannot fail is not proof, it's just decoration.
What probes measure, for example: actually served certificates and their expiration dates; SIEM agents connected; a disposable container that triggers detection at runtime; the canary rule for file systems; a refused deletion on the backup target; the age of the last restore exercise; the presence of dozens of versions in each repository; the second factor of privileged accounts; the integrity of the registry against its anchors.
A probe proves what it measures, and nothing more
The incident log probe verifies that the deadlines for reported incidents are being met. An empty log indicates that this is not the case. It does not prove that no incidents have occurred, nor that a real incident has been reported – and this is written in its header, where the next reader will find it.
The probes rotate every six hours. A probe present on disk but not attached to any control will appear on the table as an orphaned proof: it measures something that no one has requested, or a control has lost its proof.
3. The Derived Status¶
The status of a control is not captured. It is calculated, at each reading, from the evidence:
| Status | Condition |
|---|---|
| Active | All its probes are pass, and they are fresh (36 hours by default), and all its attestations are valid |
| Failed | At least one probe is fail |
| Unverified | Everything else: a silent probe, expired probe, indeterminate probe, a missing or expired attestation |
The third line is the key difference. The absence of measurement is not a measurement: a control whose probe has failed does not remain green due to inertia; it goes to "unverified".
Why never capture a status: a captured status is a declaration. It was true on the day it was written, and it remains in the interface long after the reality has changed. A derived status cannot remain inaccurate longer than the freshness of its evidence.
4. The Chain Log and its Anchor¶
All evidence – each probe verdict, each attestation, each version of the catalog – enters a chain log, adding only.
flowchart LR
classDef e fill:#1e40af,stroke:#1e40af,color:#fff
classDef a fill:#0f766e,stroke:#0f766e,color:#fff
e1["Entrée n<br/>contenu + empreinte de n-1"]:::e
e2["Entrée n+1<br/>contenu + empreinte de n"]:::e
e3["Entrée n+2 — tête<br/>contenu + empreinte de n+1"]:::e
anc["Ancre du jour<br/>numéro + empreinte de tête<br/>versionnée dans git"]:::a
e1 --> e2 --> e3
e3 -.->|"chaque soir"| anc
- Each entry contains the SHA-256 hash of the previous one. Modifying, deleting, or inserting an entry in the middle breaks the chain at the exact entry: the verification tells you where.
- There is also a case where the chain alone doesn't see it: truncation. Deleting the last entries leaves a perfectly valid chain, simply shorter.
- This is why the anchor is important: every evening, the number and hash of the head of the log are versioned in Git and pushed to two remote repositories. A truncated log no longer finds its anchors. A probe confronts the log with the published anchors.
An intended consequence
Restoring the log from a backup returns it to a previous state: its recent entries are gone, and the verification against the anchors fails. This is exactly what happens – the log has indeed lost evidence. This failure is recorded; it never "corrects" itself by purging the anchors, which would be equivalent to erasing the trace of the loss.
5. Two logs, and who signs them¶
The log contains two types of entries:
- the evidence, described above;
- human actions: each decision to triage, each remediation action, recorded with its state before and after, in the same transaction as the action itself – an action without a trace cannot have occurred.
The author of an action is read from the channel – the authenticated session provided by the identity provider – and never from the body of the request. A log where the author declares themselves proves nothing: anyone with access could write any name.
6. The attestations¶
Some things cannot be measured: that a risk analysis has been reviewed, that the operator has been trained, that critical suppliers have been reviewed, that the off-site crisis channel has been tested. These are all based on a declaration: a human statement dated.
Three safeguards ensure that this is more than just a checkbox:
- it is only accepted after an authenticated session;
- it expires – annually or quarterly depending on the control;
- it is entered into the register as any other piece of evidence, so it cannot be altered.
7. Auditing – The Process¶
An auditor, or the operator, will repeat these steps:
- Recalculate the chain in the register, then compare it to the anchors taken in git – not those that the server announces: the purpose of an anchor is to be outside the reach of the machine it monitors.
- Export the audit file – including the catalogue, status, evidence, incidents, and method – into a single file.
- Manually run a probe without writing to the register, and compare its verdict to the last one recorded.
- Choose a control at random and ask for its reverse verification – what command caused it to fail, and what did it reveal?
8. Adding a Control or Probe¶
- Write the probe according to the contract, including the header.
- Make it fail intentionally, and note the command that caused it to fail.
- Declare it in a catalogue control – the probe's identifier is the name of the file.
- Run it without declaring it, then wait for the next launch. A probe that has not been declared will appear as orphaned: it is clear that it has been forgotten.
To Read Next¶
- Detection – the process of re-reading the data from the probes.
- Continuity – immutability and the ability to restore.
- Response – the incident log.
- Glossary.
Dernière vérification de cette page : 2026-09-11