File: crates/state/src/event.rs:62-176
Severity: security — integrity (low)
Obvious? no
Custom deserializer maps unknown permission names to Permission::__UnknownLegacy so the event "joins the DAG — preserving signatures + hash linkage — without mutating any role's permission set" (line 62-69).
required_permission() matches on EventKind::GrantPermission { permission, .. } only by variant, not by permission value, so GrantPermission { permission: __UnknownLegacy } is admin-gated correctly.
Risk: forward-compat. If a future Permission adds a new variant with stronger semantics (e.g. GrantAdmin-equivalent) that older nodes deserialize as __UnknownLegacy and silently drop, an admin on an old node sees state that diverges from a new node's view → split-brain authority.
Fix: version the wire schema, or explicitly reject __UnknownLegacy-carrying events at ingestion time on nodes that cannot interpret them, instead of silent drop.
Filed by /general-audit @ b901575 (2026-05-02). master: #513.
File:
crates/state/src/event.rs:62-176Severity: security — integrity (low)
Obvious? no
Custom deserializer maps unknown permission names to
Permission::__UnknownLegacyso the event "joins the DAG — preserving signatures + hash linkage — without mutating any role's permission set" (line 62-69).required_permission()matches onEventKind::GrantPermission { permission, .. }only by variant, not bypermissionvalue, soGrantPermission { permission: __UnknownLegacy }is admin-gated correctly.Risk: forward-compat. If a future
Permissionadds a new variant with stronger semantics (e.g.GrantAdmin-equivalent) that older nodes deserialize as__UnknownLegacyand silently drop, an admin on an old node sees state that diverges from a new node's view → split-brain authority.Fix: version the wire schema, or explicitly reject
__UnknownLegacy-carrying events at ingestion time on nodes that cannot interpret them, instead of silent drop.Filed by
/general-audit@b901575(2026-05-02). master: #513.