Task
The node's derived BLS peer key sits at rest UNSEALED, at:
<cache_dir>/peer-net/identity/node.key
So sealing the machine seed into a DIGOP1 container (dig-node PR #342, eco#2168) does not make
peer_id copy-resistant. An attacker who reads that one file has the node's network identity without
touching either half of the sealed pair.
Why this matters, precisely
PR #342 built a real boundary for the seed: recovering it requires both
<config_dir>/dig/machine-identity.dks and the sibling <config_dir>/dig-device/device.dks. That
separation is the partial-exfiltration boundary §16.4 describes, and it holds.
But the derived key is the thing that actually authenticates the node on the wire, and it is stored
plainly one directory away. The seal protects the ability to re-derive; it does not protect the
derived material.
The consequence for claims, which is the part to get right: any surface that says the node's identity
is "sealed" or "protected at rest" is true of the seed and false of the key that peers actually see.
That is the money/custody-lie class one step removed — it is not user funds, but it is a shipped surface
asserting a protection that does not cover the artifact a reader would assume.
peer_id = SHA-256(TLS SPKI DER), so possession of node.key is possession of the node's identity for
every purpose the network cares about — dialing as it, serving as it, and any authorization keyed on it.
Scope
Either seal node.key the same way the seed is sealed, or state plainly — in SPEC.md and on every
surface that reports protection tier — that the derived key is not covered and what that implies.
Prefer sealing. But if the derived key must stay readable for a startup path that has no key material
yet, say so explicitly rather than leaving the gap implicit; an honest documented gap is far better than
an unstated one.
Note the recovery hazard before choosing: dig-keystore SPEC.md §17.5b establishes that
HardwareUnwrapFailed cannot distinguish a blob copied to another machine from a wiped device. A key
that cannot be re-derived after a device-key loss is a bricked node identity, so any sealing here needs
the re-derivation path from the sealed seed to remain reachable — which is an argument for sealing
node.key with the same device key rather than a new one.
Evidence
- Prove the negative:
node.key copied to another host must fail to authenticate, and the failure
must be distinguishable from an ordinary dial failure.
- Confirm
peer_id is unchanged across whatever change lands — a changed peer_id silently orphans
every peer holding the old one.
- Read passed-counts, never
ok. Any mutation must assert its patch applied, and parse the
test result: line rather than stderr (cargo test prints error: test failed on a legitimately red
run).
- Never print a key, seed, or mnemonic — key ids and public material only.
Cross-references
Found by the security gate on: #342 (eco#2168, machine-key sealing)
Related: dig_ecosystem#2177 (assert the dig-keystore custody feature never enables — the enforcement
that makes custody OFF an invariant rather than a default)
Task
The node's derived BLS peer key sits at rest UNSEALED, at:
So sealing the machine seed into a
DIGOP1container (dig-node PR #342, eco#2168) does not makepeer_idcopy-resistant. An attacker who reads that one file has the node's network identity withouttouching either half of the sealed pair.
Why this matters, precisely
PR #342 built a real boundary for the seed: recovering it requires both
<config_dir>/dig/machine-identity.dksand the sibling<config_dir>/dig-device/device.dks. Thatseparation is the partial-exfiltration boundary §16.4 describes, and it holds.
But the derived key is the thing that actually authenticates the node on the wire, and it is stored
plainly one directory away. The seal protects the ability to re-derive; it does not protect the
derived material.
The consequence for claims, which is the part to get right: any surface that says the node's identity
is "sealed" or "protected at rest" is true of the seed and false of the key that peers actually see.
That is the money/custody-lie class one step removed — it is not user funds, but it is a shipped surface
asserting a protection that does not cover the artifact a reader would assume.
peer_id = SHA-256(TLS SPKI DER), so possession ofnode.keyis possession of the node's identity forevery purpose the network cares about — dialing as it, serving as it, and any authorization keyed on it.
Scope
Either seal
node.keythe same way the seed is sealed, or state plainly — inSPEC.mdand on everysurface that reports protection tier — that the derived key is not covered and what that implies.
Prefer sealing. But if the derived key must stay readable for a startup path that has no key material
yet, say so explicitly rather than leaving the gap implicit; an honest documented gap is far better than
an unstated one.
Note the recovery hazard before choosing: dig-keystore
SPEC.md§17.5b establishes thatHardwareUnwrapFailedcannot distinguish a blob copied to another machine from a wiped device. A keythat cannot be re-derived after a device-key loss is a bricked node identity, so any sealing here needs
the re-derivation path from the sealed seed to remain reachable — which is an argument for sealing
node.keywith the same device key rather than a new one.Evidence
node.keycopied to another host must fail to authenticate, and the failuremust be distinguishable from an ordinary dial failure.
peer_idis unchanged across whatever change lands — a changedpeer_idsilently orphansevery peer holding the old one.
ok. Any mutation must assert its patch applied, and parse thetest result:line rather than stderr (cargo testprintserror: test failedon a legitimately redrun).
Cross-references
Found by the security gate on: #342 (eco#2168, machine-key sealing)
Related: dig_ecosystem#2177 (assert the dig-keystore
custodyfeature never enables — the enforcementthat makes
custodyOFF an invariant rather than a default)