Normative sources that guide the design. Each requirement has a stable ID
(REQ-C-* crypto construction, REQ-E-* evidence quality, REQ-R-* regulatory
report content), a citation, and the module(s) it constrains.
docs/architecture.md traces design decisions back to these IDs.
Status legend: MUST (v1 non-negotiable), SHOULD (v1 unless costly), MAY (post-v1, interface reserved).
| ID | Requirement | Source | Modules |
|---|---|---|---|
| REQ-C-01 | MUST build per-segment Merkle trees with RFC 6962 §2.1 construction: leaf hash SHA-256(0x00‖entry), node hash SHA-256(0x01‖left‖right), left-balanced split at largest power of two < n. Domain separation prevents leaf/node second-preimage confusion and gives bit-compatibility with the tlog ecosystem (Go sumdb, sigsum, Rekor). |
RFC 6962 §2.1; RFC 9162 §2.1 (algorithms) | segment, verifier |
| REQ-C-02 | MUST support inclusion proofs and consistency proofs per RFC 9162 §2.1.3/§2.1.4 so the verifier can prove a record is in a sealed segment and that a grown log is an append-only extension. | RFC 9162 | segment, verifier |
| REQ-C-03 | MUST use SHA-256 (FIPS 180-4) for all hashing; MUST NOT use bare SHA-256(secret‖data) as a MAC (length extension) — HMAC where a MAC is needed. |
FIPS 180-4; NIST SP 800-57 §5.6 (128-bit strength acceptable beyond 2031) | all |
| REQ-C-04 | MUST hash the exact stored bytes of a record; MUST NOT parse and re-serialize before hashing or verifying. Rationale: canonicalization is fragile (property order, IEEE-754 re-serialization, escaping) — the pitfalls RFC 8785 (JCS) exists to patch are sidestepped by defining the stored byte string as the canonical form. | RFC 8785 (rationale) | envelope, spool, verifier |
| REQ-C-05 | MUST sign with Ed25519 per RFC 8032 (Go crypto/ed25519); deterministic nonces, canonical-encoding verification. Citable as NIST-approved since FIPS 186-5 (2023). |
RFC 8032; FIPS 186-5 | keys, segment, verifier |
| REQ-C-06 | MUST sign structured, domain-separated messages — never bare 32-byte hashes — to prevent cross-protocol signature reuse. Envelope format: C2SP signed note (key name, 4-byte key ID = truncated SHA-256, Ed25519 type byte 0x01). | C2SP signed-note | segment, verifier |
| REQ-C-07 | MUST emit chain-head attestations as C2SP tlog-checkpoints: line 1 origin (e.g. prooflog/<org>/<source_id>), line 2 tree size (ASCII decimal), line 3 base64 RFC 6962 root; wrapped in a signed note. The verifier MUST enforce the spec rule: never accept/co-sign a checkpoint inconsistent with a previously signed one (append-only commitment). |
C2SP tlog-checkpoint | agent, verifier |
| REQ-C-08 | MUST encrypt payloads with ChaCha20-Poly1305 (RFC 8439) via the age format (filippo.io/age, C2SP age spec): per-file single-use keys, X25519 recipient stanzas, STREAM chunking. XChaCha20-Poly1305 is rejected: the IRTF draft is dead, it is standardized nowhere (no RFC, no NIST, no HPKE codepoint). Bonus: sealed payloads decrypt with the standard age CLI using the org key. |
RFC 8439; C2SP age; draft-irtf-cfrg-xchacha (expired) | seal |
| REQ-C-09 | MUST bind ciphertext to its position: segment ID, source ID, and sequence range authenticated alongside the payload (via the signed segment header covering payload hashes; AAD if using raw AEAD). | RFC 8439 (AAD semantics) | segment, seal |
| REQ-C-10 | SHOULD keep the AEAD pluggable so a FIPS 140-3 deployment mode can substitute AES-256-GCM (per-segment keys already satisfy GCM's nonce constraints). | NIST SP 800-38D | seal |
| REQ-C-11 | MUST keep key types separate — Ed25519 signing key ≠ X25519 recipient key; one key, one purpose. X25519 all-zero shared-secret check per RFC 7748 §6.1 (Go crypto/ecdh does this). |
NIST SP 800-57 §5.1–5.2; RFC 7748 §6.1 | keys |
| REQ-C-12 | SHOULD document cryptoperiods: agent signing keys rotated on a 1–3 year schedule (or on compromise), old public keys retained indefinitely for verification of already-signed data; org X25519 recipient key rotation plan (re-wrap or multi-recipient stanzas). | NIST SP 800-57 Part 1 §5.3.6 | keys, docs |
| REQ-C-13 | MUST pin one exact RFC 3339 byte format for timestamps inside hashed bytes: UTC only, uppercase T/Z, fixed nanosecond precision (2006-01-02T15:04:05.000000000Z). RFC 3339 alone does not guarantee byte-uniqueness. |
RFC 3339 | envelope |
| REQ-C-14 | SHOULD use UUIDv7 (RFC 9562 §5.7) for segment IDs (time-ordered, index-friendly). Cite RFC 9562, not the obsoleted RFC 4122. | RFC 9562 | segment, store |
| REQ-C-15 | Implemented for RFC 3161 TSA (internal/anchor, prooflog verifier --tsa-url): the verifier anchors advancing checkpoint heads to an RFC 3161 TSA and stores the full DER TimeStampToken per receipt for offline verification (openssl ts -verify); the offline engine cross-checks each receipt's imprint and (origin,size,root) against accepted checkpoints (F-ANCHOR on mismatch). Full CMS signature-chain validation, ESSCertID/ESSCertIDv2 acceptance, and per-entry log origin/public key are reserved (Rekor shards rotate), as are Sigstore Rekor v2 hashedrekord entries. An EN 319 421-audited (eIDAS-qualified) TSA — operator-declared via --tsa-qualified — upgrades anchors to the Art. 41 legal presumption of accuracy and integrity; the presumption itself remains reserved pending a qualified provider. |
RFC 3161; RFC 5816; ETSI EN 319 421/422; eIDAS Art. 41–42; Rekor v2 | anchor |
| REQ-C-16 | MAY export signatures as DSSE/COSE at integration boundaries only; internally the signed-note format is canonical (no second envelope format, no CBOR surface). | RFC 9052 (assessed, rejected as core) | export (future) |
| ID | Requirement | Source | Modules |
|---|---|---|---|
| REQ-E-01 | Reports and evidence handling MUST target the five RFC 3227 criteria: admissible, authentic, complete, reliable, believable — "reliable" = nothing about collection/handling casts doubt on authenticity. The continuity report exists to demonstrate this. | RFC 3227 (BCP 55) | report, verifier |
| REQ-E-02 | Chain-of-custody documentation MUST be producible: where/when/by whom evidence was produced and collected, who had custody during which period, when/how each transfer occurred. Prooflog's mapping: agent identity + signatures (who/where), seq + timestamps (when), upload ACKs + verifier receipt log (transfers). | RFC 3227; ISO/IEC 27037 | report, store, verifier |
| REQ-E-03 | Dual-tier storage — record at system level AND infrastructure level so either surviving reveals tampering of the other. Prooflog's local spool + Store implements this stated NIST guidance; the report SHOULD cite it. | NIST SP 800-92 §5.1.2 | spool, store |
| REQ-E-04 | Log write access MUST be append-only; archived logs protected via message digests + encryption; log-shipping over secure transport only (TLS). Behavior on logging failure MUST be defined, not accidental. | NIST SP 800-92 §5.1.3 | spool, agent, api |
| REQ-E-05 | Integrity of transferred/archived logs MUST be verifiable by digest comparison (mechanized here as hash chain + Merkle roots). | NIST SP 800-92 §5.4; ISO/IEC 27037 (preservation) | verifier |
| REQ-E-06 | The logging status of every source MUST be monitored to ensure it is functioning (heartbeats operationalize SP 800-92 §5.5); clock synchronization to a common source MUST be checkable — agents SHOULD record time-source/sync-state metadata (NTP per RFC 5905; NTS RFC 8915 recommended) so reports can attest time-source trust (what ISO 27001 A.8.17 auditors probe). | NIST SP 800-92 §5.5; ISO 27001 A.8.17; RFC 5905; RFC 8915 | heartbeat, report |
| REQ-E-07 | Every record MUST carry: date/time, event type, subject identity (source + actor when known), and outcome — the FAU_GEN.1 minimum. | CC:2022 Part 2 FAU_GEN.1 | envelope |
| REQ-E-08 | Tamper protection posture = FAU_STG.2 "detect" option: prevent unauthorized deletion, detect unauthorized modification. State this mapping explicitly (tamper-evident, not tamper-proof). | CC:2022 FAU_STG.2 | docs, verifier |
| REQ-E-09 | Spool exhaustion MUST trigger a defined, configurable action (FAU_STG.4): block new events vs drop-oldest, with the choice itself recorded as an event (system.local_spool_pressure). |
CC:2022 FAU_STG.4/STG.5 | spool, agent |
| REQ-E-10 | The verification report MUST double as the SP 800-86 documentation artifact: every verification step listed, repeatable (offline re-verification command), copies-not-originals semantics. | NIST SP 800-86 | report |
| REQ-E-11 | Retention SHOULD support ≥12 months (SOC 2 Type II observation window) and per-framework configurable periods. | AICPA TSC CC7.2/CC7.3; ISO 27001 A.8.15 | store |
| REQ-E-12 | Prior art to cite: RFC 5848 (signed syslog) failed because in-band signature blocks break under relay truncation and UDP limits; ecosystem converged on transport security which protects in transit but not at rest — the at-rest/continuity gap is Prooflog's justification. Segment sealing lives above transport by design. | RFC 5848 (lessons) | docs |
| REQ-E-13 | Legal context: SEC 17a-4 (2022) recognizes an "audit-trail alternative" to WORM — complete time-stamped audit trail of modifications/deletions with actor identity. Prooflog's append-only + hash-chain model is architecturally this alternative; ISO 27043 "readiness processes" are the normative hook for continuous evidence logging. | SEC 17a-4 (17 CFR 240.17a-4); FINRA 4511; ISO/IEC 27043 | docs, report |
| REQ-E-14 | Every report MUST state its assurance tier (0 assessed · 1 captured/single-admin · 2 independently verified · 3 witnessed/qualified-anchored). A Tier 0 assessment over foreign, unsigned data MUST be visibly distinct from a captured/verified report and MUST NOT carry a verification certificate. Prevents an analytical assessment being mistaken for cryptographic proof (extends the FAU_STG.2 honesty posture of REQ-E-08). | ADR-0008; RFC 3227 (believable) | evidence, report, assess |
| REQ-E-15 | An assessment MUST be bound to exactly the input bytes it was computed from: a SHA-256 input digest (per source and whole-input, malformed lines included) is recorded so re-running over the same export reproduces it and a changed export changes it. Mirrors REQ-E-02 chain-of-custody for foreign-data inputs the tool did not capture. | ADR-0008; RFC 3227; ISO/IEC 27037 | assess, report |
| REQ-E-16 | Findings over foreign, unsigned data MUST be labelled indicative, never attested: they carry A-* ids (distinct from the verifier's probative F-*), and a Tier 0 document MUST NOT contain an F-* id. Size-capped reads MUST disclose truncation loudly (no silent caps). |
ADR-0008; RFC 3227 (reliable) | assess, report |
These define the report generator's data model: every field an authority expects becomes a typed report field — auto-populated from evidence where Prooflog can, exposed as a manual-input slot where it cannot — so a generated report is always structurally complete for its framework.
| ID | Requirement | Source | Modules |
|---|---|---|---|
| REQ-R-01 | MUST implement one common incident-evidence model covering the superset of all regimes: discovery timestamp (starts every regulatory clock) · attack/breach type & how carried out · affected assets/services/data with C-I-A impact · severity / initial assessment · indicators of compromise · measures taken + planned · root cause / threat type · cross-border & user impact · contact point. Per-framework reports are projections of this model. | Cross-regime synthesis (NCSC, FDPIC, NIS2, CRA, DORA, FINMA) | report |
| REQ-R-02 | MUST support the Swiss NCSC report pair — 24h from discovery (initial, may be incomplete) + complete report within 14 calendar days. Fields (ISA Art. 74e(2)): identity of organisation · type of cyberattack and how carried out · effects on availability, integrity, confidentiality and on functioning · measures taken · planned further steps · contact. Channel: NCSC Cyber Security Hub form (report.ncsc.admin.ch). Universities/higher-education are expressly covered entities (Art. 74b); reportable attack criteria per Art. 74d; sanctions up to CHF 100k since 1 Oct 2025. | ISA/LSI Arts. 74a–74h (in force 1 Apr 2025); Cybersecurity Ordinance (CSV) | report |
| REQ-R-03 | MUST support the FDPIC breach notification (LPD Art. 24, "as soon as possible", threshold: high risk) with OPDo Art. 15(1) fields: (a) nature of breach · (b) time and duration · (c) categories & approx. number of personal data · (d) categories & approx. number of data subjects · (e) consequences/risks · (f) measures taken or envisaged · (g) contact person. Staged completion allowed (15(2)). Documentation duty OPDo 15(5)–(6): ALL breaches documented (facts, effects, measures), retained ≥2 years — a built-in breach register satisfies this directly. Channel: databreach.edoeb.admin.ch. | LPD Art. 24; OPDo Art. 15 (in force 1 Sep 2023) | report, store |
| REQ-R-04 | MUST support the NIS2 Art. 23 cascade: 24h early warning (suspected malicious cause? cross-border impact?) → 72h notification (+ severity/impact assessment, IoCs where available) → final report ≤1 month (detailed description incl. severity/impact · threat type or root cause · applied and ongoing mitigation · cross-border impact). No EU-level template — national CSIRT forms vary; export as structured document. | NIS2 Art. 23(4), Directive 2022/2555 | report |
| REQ-R-05 | SHOULD align the event catalog with NIS2 IR 2024/2690 Annex 3.2 (binding on MSPs/MSSPs, cloud, DNS…): loggable categories include user create/modify/delete and permission changes · authentication events · privileged/admin activity · access to and changes of critical configuration and backup files · log start/stop events (3.2.3) · logs protected from modification (3.2.5) · synchronised time sources (3.2.6). Prooflog's agent start/stop + heartbeat + clock-drift events map 1:1 to 3.2.3/3.2.6. ENISA Technical Implementation Guidance (June 2025) lists "examples of evidence" per requirement — the reference for what report content supervisors accept. | IR (EU) 2024/2690 Annex 3.2; ENISA TIG v1.0 (2025) | envelope (catalog), heartbeat, report |
| REQ-R-06 | SHOULD support CRA Art. 14 (applies from 11 Sep 2026): actively-exploited-vulnerability path — 24h early warning (fact + Member States) → 72h (product info · general nature of exploit and vulnerability · corrective/mitigating measures taken and available to users) → final ≤14 days after corrective measure (description incl. severity/impact · malicious actor info where available · security-update details). Severe-incident path: 24h → 72h → 1 month, same shape as NIS2. Submission: CSIRT coordinator + ENISA Single Reporting Platform; user information in machine-readable format where feasible (Art. 14(8)). | CRA Reg. (EU) 2024/2847 Art. 14, 16 | report |
| REQ-R-07 | SHOULD support GDPR Art. 33: 72h to authority, minimum content per Art. 33(3): (a) nature incl. categories & approx. numbers of data subjects and records · (b) DPO/contact · (c) likely consequences · (d) measures taken/proposed. Art. 33(5) breach register duty (document all breaches: facts, effects, remedial action) — same register as REQ-R-03. | GDPR Arts. 33/34 | report, store |
| REQ-R-08 | MAY support DORA (financial entities): initial ≤4h from classification / ≤24h from awareness → intermediate ≤72h → final ≤1 month, per RTS 2025/301 templates. Art. 17(3): record ALL ICT incidents and significant cyber threats. RTS 2024/1774 Art. 12: documented logging procedures, defined retention, logs secured against tampering. | DORA Reg. (EU) 2022/2554; RTS 2025/301; RTS 2024/1774 Art. 12 | report |
| REQ-R-09 | MAY support FINMA reporting: 24h informal initial report from discovery (severe: strict 24h) → 72h structured notification via EHP platform (type of attack · critical functions & protection goals affected · measures taken · severity assessment + forecast) → root-cause/forensic report for medium+ attacks. | FINMASA Art. 29(2); FINMA Guidance 05/2020 & 03/2024; Circ. 2023/1 | report |
| REQ-R-10 | MUST make retention configurable per framework: OPDo 2y breach docs · SOC 2 12-month observation window · CRA technical documentation 10y [UNVERIFIED exact article] · DORA per risk assessment. Retention policy itself is evidence — changes to it are logged events. | OPDo 15(6); TSC; CRA Annex VII; RTS 2024/1774 | store |
| REQ-R-11 | SHOULD compute regulatory deadline clocks from evidence: an incident.detected / data.breach_confirmed event starts the applicable 4h/24h/72h/14d/1M countdowns, and generated reports show elapsed vs. remaining time per framework. Discovery time is itself tamper-evidenced — proving when the clock started is a Prooflog-unique claim. |
All regimes (clocks run from discovery/classification) | report, verifier |
Cross-reference: qualified timestamps on anchors (REQ-C-15) carry the eIDAS Art. 41(2) presumption of time accuracy and data integrity — the legal upgrade path for every artifact above.
| Standard | Reason |
|---|---|
| XChaCha20-Poly1305 | Dead IRTF draft, standardized nowhere; per-segment single-use keys remove the extended-nonce motivation (REQ-C-08). |
| RFC 8785 JCS canonicalization | Replaced by hash-the-stored-bytes (REQ-C-04); cited as rationale only. |
| COSE / JWS envelopes | No interop benefit in the tlog ecosystem; adds CBOR/base64url surface (REQ-C-16). |
| RFC 5848 signed syslog | Prior art studied for lessons, not adopted (REQ-E-12). |
| HPKE (RFC 9180) for key wrap | age X25519 stanzas chosen instead (REQ-C-08): same primitives, deployed tooling, org keys usable with the age CLI. HPKE remains the fallback citation if the wrap is ever reimplemented raw. |