Skip to content

Commit c24fd73

Browse files
smuchow1962claude
andcommitted
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>
1 parent 895c530 commit c24fd73

2 files changed

Lines changed: 9 additions & 4 deletions

File tree

docs/review-2026-05-11/remediation-plan.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ Closes the highest-leverage JCS canonicalisation Severe findings. SDK-side; Core
8888
| 9.11 | §10.69 estate / fiduciary procedure subsection (documentary evidence accepted for successor key-fragment delivery) | S + OVL | no | **done** |
8989
| 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** |
9090

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**
9292

9393
Both touches are deterministic, table-driven, no hot-path allocation. Behind feature detection.
9494

9595
| # | Item | Tags | F/A | Status |
9696
|---:|---|---|---|---|
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** |
9999

100100
**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).
101101

spec/chain-of-custody-DRAFT-0.1.0.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,8 @@ The trailing line is emitted on every verifier run regardless of exit code or ve
15381538

15391539
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.
15401540

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+
15411543
**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.
15421544

15431545
**File header pre-flight (per file).**
@@ -1567,7 +1569,7 @@ The label `Verdict-Object: ` (capitalization, hyphen, colon, single-space separa
15671569
**Per-day Merkle and signature (per tenant-day).**
15681570

15691571
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.
15711573

15721574
**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):
15731575

@@ -2022,6 +2024,7 @@ Implementations MAY define additional exit codes ≥ 4 for vendor-specific diagn
20222024
| `privileged_investigation_redacted_with_existence_attestation` | §10.70 | Non-cleared reader walk completed; existence-attestation form returned |
20232025
| `cross_institution_chain_verified` | §10.71 | Fedwire / ACH cross-institution cross-anchors bound on both sides |
20242026
| `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 |
20252028

20262029
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`.
20272030

@@ -4196,6 +4199,8 @@ The conformance witness for the manifest JCS form is `spec/test-vectors/008-jcs-
41964199

41974200
**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).
41984201

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+
41994204
**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.
42004205

42014206
**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

Comments
 (0)