You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Batch 10 closure: two C-min Core touches (2 Severe findings closed)
attestation_chain_validated marker (§10.12 + §10.77):
- Add closed-enum marker to §10.12 additional_verifications table
- §10.77 verifier-side attestation validation discipline
- Behind feature detection: institution declares discipline in CC8.1 + verifier invoked with --attestation-trust-root; otherwise ffiec.chain.attestation is treated as opaque institution-side evidence
- Old verifier invocations (no trust-root) walk chains identically to v1.0a/v1.0b behavior
sign_payload_version pre-dispatch floor check (§7):
- New pre-flight discipline: institution's CC8.1 names sign_payload_version floor via one of four declaration sources (file / registry / seal field / inline CLI)
- §7 step 11 floor comparison runs once per seal before reconstruction dispatch (no per-event cost)
- Below-floor seals rejected with normative reason string + exit code 1
- Feature detection: when no floor declared, dispatch proceeds per existing form-table (back-compat with old chains and old invocations)
Code-impact:
- Spec only (§7 step 11 + §10.12 enumeration + §10.77)
- C-min Core touches: two deterministic, table-driven, behind feature detection
- Old verifier binaries continue to dispatch as before; new behavior is opt-in via CC8.1 declaration
- Herald.Core hot-path discipline preserved
- Citation verifier: clean (0 broken section refs)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/review-2026-05-11/remediation-plan.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -88,14 +88,14 @@ Closes the highest-leverage JCS canonicalisation Severe findings. SDK-side; Core
88
88
| 9.11 | §10.69 estate / fiduciary procedure subsection (documentary evidence accepted for successor key-fragment delivery) | S + OVL | no |**done**|
89
89
| 9.12 | §10.69 mid-dispute succession composition (clock continues; executor's verifier resolves both halves; cohort coverage attestation binds both) | S + HC | yes |**done**|
90
90
91
-
### Batch 10 — Two C-min Core touches (2 Severe, smallest possible Core change)
91
+
### Batch 10 — Two C-min Core touches (2 Severe, smallest possible Core change) — **DONE**
92
92
93
93
Both touches are deterministic, table-driven, no hot-path allocation. Behind feature detection.
94
94
95
95
| # | Item | Tags | F/A | Status |
96
96
|---:|---|---|---|---|
97
-
| 10.1 |`additional_verifications: ['attestation_chain_validated']` closed-enum marker for Security #4 (Adversary F chain-tail attestation). Add to §10.12 enumeration table. Core's verifier emits the marker when TPM-quote / Nitro attestation validates. | S + C-min + VEC | yes |open|
98
-
| 10.2 |`sign_payload_version` pre-dispatch floor check in §7. Verifier reads institution's CC8.1-declared floor at launch; rejects below-floor seals before dispatching reconstruction. Single comparison; no per-event cost. | S + C-min + VEC | yes |open|
97
+
| 10.1 |`additional_verifications: ['attestation_chain_validated']` closed-enum marker for Security #4 (Adversary F chain-tail attestation). Add to §10.12 enumeration table. Core's verifier emits the marker when TPM-quote / Nitro attestation validates. | S + C-min + VEC | yes |**done**|
98
+
| 10.2 |`sign_payload_version` pre-dispatch floor check in §7. Verifier reads institution's CC8.1-declared floor at launch; rejects below-floor seals before dispatching reconstruction. Single comparison; no per-event cost. | S + C-min + VEC | yes |**done**|
99
99
100
100
**Code path summary for Batch 10:** Two Core dispatcher additions; both data-driven, both behind feature detection. Old verifier binaries continue to dispatch as before (no floor declaration → no rejection).
Copy file name to clipboardExpand all lines: spec/chain-of-custody-DRAFT-0.1.0.md
+6-1Lines changed: 6 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1538,6 +1538,8 @@ The trailing line is emitted on every verifier run regardless of exit code or ve
1538
1538
1539
1539
The label `Verdict-Object: ` (capitalization, hyphen, colon, single-space separator) is exact; line terminator is `0x0A`. Implementations MAY append further diagnostic lines (e.g., `Hint: ...`, `Detail: ...`) after the verdict-object line; the verdict-object line itself is the last normative line and harnesses parsing the verdict object scan for the `Verdict-Object: ` prefix anchored after the line-oriented form. Existing examiner harnesses parsing the first three lines and ignoring the rest remain conformant under this discipline; new harnesses obtain the structured verdict deterministically by prefix match without flag dependency.
1540
1540
1541
+
**`sign_payload_version` floor check (normative when applicable).** Institutions whose CC8.1 names a `sign_payload_version` floor (the minimum seal version the verifier accepts; e.g., `v1.0b` floor means seals carrying `v1.0a` are rejected before dispatch) declare the floor via one of the four declaration sources the §7 step 11 case (c) framing permits: (i) a flat file at an institution-controlled URL or filesystem path; (ii) a registry entry in the institution's tenant key registry (`min_sign_payload_version` field per tenant); (iii) a field in the seal record (the seal carries `declared_sign_payload_floor` alongside `sign_payload_version`); or (iv) an inline declaration in the verifier's invocation parameters (`--min-sign-payload-version v1.0b`). Whichever source the institution chooses, the institution's control description names the source, the source's authentication, and the change-management procedure governing floor changes. The verifier reads the floor at startup; the comparison runs once per seal during step 11 BEFORE dispatching to the reconstruction form. A seal carrying `sign_payload_version` strictly below the declared floor is rejected with reason `sign_payload_version "X" below institution-declared floor "Y" (CC8.1-named source: <source>)` and exit code 1. The check has no per-event cost (it runs once per seal, before form dispatch) and is data-driven — the floor is a single string comparison against the seal's declared version using the ordered v1.0a < v1.0b < v1.0c relation. Feature detection: when no floor is declared (the institution's CC8.1 is silent, AND no `--min-sign-payload-version` is passed), the verifier behaves identically to v1.0a/v1.0b/v1.0c behavior without the floor check (the dispatch proceeds per the §7 step 11 form-table). This preserves backwards compatibility for old verifier invocations.
1542
+
1541
1543
**Pre-flight JCS self-test (normative).** Before any chain verification, the verifier MUST canonicalize a baked-in fixture and assert byte-for-byte equality with a baked-in expected output. The fixture is the minimum element of the `008-jcs-edge-cases/` corpus (per §5 line referring to test vector 008); the expected output is the corresponding canonical bytes pinned in the fixture. The verifier compiles both the fixture JSON and the expected canonical bytes into the verifier binary at build time so the self-test is independent of any runtime configuration or external file. On startup (or, equivalently, before processing the first chain), the verifier runs its JCS implementation over the baked-in fixture and constant-time compares the output against the baked-in expected bytes. Equality → proceed to chain verification. Inequality → the verifier MUST report `verifier JCS self-test failed: canonicalization implementation does not conform to RFC 8785` and exit with code 3 (configuration error per §10.12), rejecting all chain processing for the run. The self-test catches an implementer who shipped a verifier with a non-conformant JCS path and has been silently passing all-ASCII chains; divergence would otherwise surface only on the first non-ASCII event years later. The self-test runs once per verifier process invocation, not per file or per chain entry, so the cost is negligible. Implementations MAY cache the self-test result across files within a single process invocation; the result MUST NOT be cached across process invocations because a binary patch or library upgrade between invocations could change the JCS implementation. The self-test is normative — a verifier that omits it is non-conformant regardless of whether its JCS implementation happens to be correct.
**Per-day Merkle and signature (per tenant-day).**
1568
1570
1569
1571
10. **Merkle recomputation.** Stream the day's events in `(run_id, seq)` order; compute the streaming RFC 6962 Merkle root from each event's `payload_hash`. Compare against `seal.merkle_root`. Mismatch → `merkle root mismatch — ledger contents do not produce sealed root`.
1570
-
11. **Signature verification.** Reconstruct `sign_payload` per §4.3, dispatching on the seal record's `sign_payload_version` field: absent → pre-amendment 6-line form; `"v1.0a"` → v1.0a 10-line form (binds `algorithm`, `format_version`, `tenant_id`, `seal_date`, `merkle_root`, `hkdf_inputs_digest`, `cadence`, `dev_mode`, and `sign_payload_version` itself); `"v1.0b"` → v1.0b 12-line form (additionally binds `key_versions_canon` and `hex(kms_handle_uris_digest)` per §4.3 v1.0b amendment); `"v1.0c"` → v1.0c 13-line form (additionally binds `hex(operational_events_log_root)` per §4.3 v1.0c amendment + §10.79; the verifier also recomputes the operational-event Merkle root from `chain_kind = "operational"` entries and rejects with `operational events log root mismatch — sibling-log contents do not produce sealed root` if the recomputed root differs from the bound value); unrecognized value → fail with `sign_payload_version "X" not supported by this verifier (running v1.0c)`. Verify the signature against the tenant public key, dispatching on `algorithm`. Mismatch → `signature verification failed`. If the seal's `algorithm` does not match the public key's algorithm (e.g. the seal claims `"ed25519"` but the resolved public key is a Dilithium key), report `algorithm/key-type mismatch at signature verification` rather than the generic message.
1572
+
11. **Signature verification.** **Floor pre-dispatch check.** When the institution's CC8.1 declares a `sign_payload_version` floor (per the pre-flight discipline above), the verifier first compares the seal's `sign_payload_version` against the declared floor: seals strictly below the floor are rejected with reason `sign_payload_version "X" below institution-declared floor "Y" (CC8.1-named source: <source>)`. The floor check runs once per seal before dispatch. When no floor is declared, this check is skipped (back-compat with chains under unbounded posture). **Reconstruction dispatch.** Reconstruct `sign_payload` per §4.3, dispatching on the seal record's `sign_payload_version` field: absent → pre-amendment 6-line form; `"v1.0a"` → v1.0a 10-line form (binds `algorithm`, `format_version`, `tenant_id`, `seal_date`, `merkle_root`, `hkdf_inputs_digest`, `cadence`, `dev_mode`, and `sign_payload_version` itself); `"v1.0b"` → v1.0b 12-line form (additionally binds `key_versions_canon` and `hex(kms_handle_uris_digest)` per §4.3 v1.0b amendment); `"v1.0c"` → v1.0c 13-line form (additionally binds `hex(operational_events_log_root)` per §4.3 v1.0c amendment + §10.79; the verifier also recomputes the operational-event Merkle root from `chain_kind = "operational"` entries and rejects with `operational events log root mismatch — sibling-log contents do not produce sealed root` if the recomputed root differs from the bound value); unrecognized value → fail with `sign_payload_version "X" not supported by this verifier (running v1.0c)`. Verify the signature against the tenant public key, dispatching on `algorithm`. Mismatch → `signature verification failed`. If the seal's `algorithm` does not match the public key's algorithm (e.g. the seal claims `"ed25519"` but the resolved public key is a Dilithium key), report `algorithm/key-type mismatch at signature verification` rather than the generic message.
1571
1573
1572
1574
**Dual-algorithm transitional period (v1.x post-quantum).** When the institution operates dual-algorithm posture (Ed25519 + a post-quantum algorithm coexisting per §4.3.2), the verifier's behavior is dispatched on the seal record's `signatures` list (§4.2 schema):
1573
1575
@@ -2022,6 +2024,7 @@ Implementations MAY define additional exit codes ≥ 4 for vendor-specific diagn
2022
2024
| `privileged_investigation_redacted_with_existence_attestation` | §10.70 | Non-cleared reader walk completed; existence-attestation form returned |
2023
2025
| `cross_institution_chain_verified` | §10.71 | Fedwire / ACH cross-institution cross-anchors bound on both sides |
2024
2026
| `device_revoked_seen_at_seq_N` | §10.32 (added under remediation Batch 3) | Verifier observed a `device.revoked` event during chain walk |
2027
+
| `attestation_chain_validated` | §10.77 | Verifier observed host-attestation artifacts (Intel TDX / AMD SEV-SNP / AWS Nitro / vTPM) bound to one or more chain entries AND validated the attestation evidence against the institution's published trust roots; institution declares the discipline operational in CC8.1 per §10.77 |
2025
2028
2026
2029
The enumeration is closed at v1.0; extending requires a spec-version amendment per §0 Version policy. A verifier emitting a marker not on this list is non-conformant. Vendor-specific markers MAY appear in the parallel `additional_diagnostics` field (which is opaque and NOT closed-enumerated) but MUST NOT contaminate `additional_verifications`.
2027
2030
@@ -4196,6 +4199,8 @@ The conformance witness for the manifest JCS form is `spec/test-vectors/008-jcs-
4196
4199
4197
4200
**Attestation binding for non-edge deployments (normative when applicable).** §10.35 normates device attestation for edge deployments. The HQ/datacenter analog: institutions operating SDK processes in cloud VMs or bare-metal servers SHOULD bind the SDK's emitted chain entries to a host-attestation artifact (Intel TDX attestation, AMD SEV-SNP attestation, AWS Nitro Enclaves attestation, vTPM attestation). The host-attestation discipline is institution-named per CC8.1; the v1.0 spec recommends it but does not require it for non-edge deployments (the §10.5 HSM custody + IKM registry discipline is the primary defense; host attestation is layered defense-in-depth).
4198
4201
4202
+
**Verifier-side attestation validation (normative when applicable).** When the institution's CC8.1 declares the host-attestation discipline operational AND the verifier is invoked with the attestation-trust-root artifact (per `--attestation-trust-root` flag or institution-named configuration), the verifier walks each chain entry's `ffiec.chain.attestation` attribute (per §4.4), validates the attestation evidence against the trust root (TPM Attestation Key signature chain to the TPM manufacturer's root, AWS Nitro PCR-bound attestation document signature to the Nitro root, vendor-equivalent), and emits `additional_verifications: ['attestation_chain_validated']` on PASS. The marker is closed-enumeration per §10.12. Feature detection: when the institution's CC8.1 does NOT declare the host-attestation discipline operational, OR the verifier is invoked WITHOUT the attestation-trust-root artifact, the verifier does NOT walk attestation evidence and does NOT emit the marker — the chain entry's `ffiec.chain.attestation` attribute is treated as opaque institution-side evidence. This preserves backwards compatibility: old verifier invocations (no attestation-trust-root) walk the chain identically to v1.0a/v1.0b behavior; new invocations with the trust root opt into the attestation-walk pass. The verifier MUST emit the marker only when at least one chain entry's attestation evidence was found AND validated; chains with zero attestation evidence do NOT emit the marker (the discipline's absence is the marker's absence, not a marker indicating "validated zero artifacts"). Chains where attestation evidence is present BUT validation fails surface as `Status: FAIL` with reason `attestation evidence at seq N failed validation against published trust root: <vendor-specific detail>` (exit code 1).
4203
+
4199
4204
**Detection complement (informative).** The four disciplines above bound the attack surface; they do not eliminate it. The detection complement is institution-side anomaly detection on the captured chain stream (unusual emission patterns from the SDK process, out-of-band agent-behavior monitoring, third-party intrusion detection). The chain's forward-only damage property (§1.2) means past entries are unaffected by SDK-process compromise; the window the institution's controls bound is the dwell time of the compromise.
4200
4205
4201
4206
**Cross-reference.** §1.2 SDK-process compromise as fourth class; §9 Adversary F; §10.5 HSM custody; §10.10 IKM rotation (the upper-bound rotation discipline that backs up the TTL ceiling); §10.32 per-device key derivation (the edge analog); §10.35 edge attestation (the host-attestation primitive this section recommends extending to non-edge).
0 commit comments