Skip to content

sec: the derived BLS peer key is at rest UNSEALED, so sealing the machine seed does not make peer_id copy-resistant #343

Description

@MichaelTaylor3d

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions