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
{{ message }}
Repository navigation
security(validation): reject duplicate authority keys in Rubin activation receipts #519
The public draw-bound RubinProjectionActivationReceiptV1::from_json first deserializes the wire payload into serde_json::Value, removes complete_data_draws_sha256, then reserializes the remaining object into the inner typed receipt. serde_json::Value object parsing is last-write-wins for repeated member names, so duplicate complete_data_draws_sha256 members are collapsed before validation.
The inner activation receipt is a typed #[serde(deny_unknown_fields)] struct, but the new outer draw commitment does not currently inherit duplicate-field rejection. That creates parser ambiguity at an evidence-authority boundary: two components that do not resolve duplicate JSON members identically can disagree about which draw digest a raw receipt denotes, while TEPP later computes authority over a canonicalized receipt.
Required repair
Fail closed on duplicate top-level JSON member names before the public draw-bound receipt is interpreted. Preserve the current bounded payload check and do not require callers to use one whitespace/property-order serialization; the defect is duplicate-name ambiguity, not formatting variance.
RED should demonstrate that a canonical valid receipt becomes invalid when a second complete_data_draws_sha256 key is injected, even when both values are individually canonical lowercase SHA-256 values. The ordinary canonical receipt and non-duplicate alternate digest remain parseable subject to the existing authority rules.
Keep Rubin arithmetic unchanged and keep production approval registry empty. This is parser/evidence integrity only; it does not promote Draft #504 or create positive projection authority.
Do not simple-close until the repair is exact-head verified and inherited by the surviving Analysis Run vehicle.
Implemented on Draft #506 as forward-only RED -> repair.
RED 75615fc5a3f6c2880bc8c572459ca3201088e5a6: public integration contract injects two individually canonical complete_data_draws_sha256 members and requires InvalidEvidence.
causal fix 75e72b19779d3b34ffdb2a5eedc4c3128c983937: bounded from_json now scans the top-level object with a duplicate-key visitor before serde_json::Value interpretation, so last-write-wins collapse cannot erase the ambiguity. The fix does not require canonical whitespace/property order and does not touch Rubin arithmetic or production approval.
Exact-head Rust Foundation and Documentation Quality are currently queued with no runner assigned and zero execution steps, so hosted GREEN is not claimed. Keep this issue open until exact-head verification and verified inheritance by the surviving Analysis Run vehicle.
Edge coverage extended at a40dab07044c6d77ebe3514ee9ef215dc09970d7: the contract now also duplicates an inner authority field (validation_evidence_sha256) in the outer draw-bound wire payload. That matters because the outer serde_json::Value parse previously collapsed duplicates for all inner authority fields before the typed inner receipt reparsed them, not only for complete_data_draws_sha256. The top-level unique-key gate covers both cases.
Standards support: RFC 8259 §4 says JSON object member names SHOULD be unique and explicitly notes that behavior is unpredictable when names are not unique; some implementations keep only the last pair, others error, and others expose all duplicates. That is the interoperability/security reason for rejecting duplicate authority members here rather than relying on serde_json::Value last-write-wins behavior. https://www.rfc-editor.org/rfc/rfc8259.html#section-4
Activity
seonghobae commentedon Sep 14, 2026
Implemented on Draft #506 as forward-only RED -> repair.
75615fc5a3f6c2880bc8c572459ca3201088e5a6: public integration contract injects two individually canonicalcomplete_data_draws_sha256members and requiresInvalidEvidence.75e72b19779d3b34ffdb2a5eedc4c3128c983937: boundedfrom_jsonnow scans the top-level object with a duplicate-key visitor beforeserde_json::Valueinterpretation, so last-write-wins collapse cannot erase the ambiguity. The fix does not require canonical whitespace/property order and does not touch Rubin arithmetic or production approval.Exact-head Rust Foundation and Documentation Quality are currently queued with no runner assigned and zero execution steps, so hosted GREEN is not claimed. Keep this issue open until exact-head verification and verified inheritance by the surviving Analysis Run vehicle.
seonghobae commentedon Sep 14, 2026
Edge coverage extended at
a40dab07044c6d77ebe3514ee9ef215dc09970d7: the contract now also duplicates an inner authority field (validation_evidence_sha256) in the outer draw-bound wire payload. That matters because the outerserde_json::Valueparse previously collapsed duplicates for all inner authority fields before the typed inner receipt reparsed them, not only forcomplete_data_draws_sha256. The top-level unique-key gate covers both cases.seonghobae commentedon Sep 14, 2026
Standards support: RFC 8259 §4 says JSON object member names SHOULD be unique and explicitly notes that behavior is unpredictable when names are not unique; some implementations keep only the last pair, others error, and others expose all duplicates. That is the interoperability/security reason for rejecting duplicate authority members here rather than relying on
serde_json::Valuelast-write-wins behavior. https://www.rfc-editor.org/rfc/rfc8259.html#section-4