Proposal 059: Participant, Nym, and Routing-Subject Key-Role Derivation¶
Based on:
doc/project/20-memos/participant-seed-contract-v1.mddoc/project/20-memos/nym-layer-roadmap-and-revocable-anonymity.mddoc/project/40-proposals/014-node-transport-and-discovery-mvp.mddoc/project/40-proposals/015-nym-certificates-and-renewal-baseline.mddoc/project/40-proposals/025-seed-directory-as-capability-catalog.mddoc/project/40-proposals/030-identity-recovery-service.mddoc/project/40-proposals/031-participant-key-passphrase-lock.mddoc/project/40-proposals/037-generic-signing-service.mddoc/project/40-proposals/038-key-roles-and-key-use-taxonomy.mddoc/schemas/pseudonym-vault.v1.schema.json
Promoted to:
doc/project/60-solutions/026-pseudonym-vault-and-key-roles/026-pseudonym-vault-and-key-roles.md
Status¶
Accepted - Node MVP runtime implemented
Date¶
2026-05-16
Executive Summary¶
Orbiplex already has one concrete role split in the Node networking layer:
Ed25519 signs long-lived identity artifacts while a static X25519 key-agreement
surface is deterministically derived for session establishment. Participant,
nym, and routing-subject handling, however, still mostly speaks in terms of one
signing key and does not yet define a coherent model for encryption, local
secret storage, or private recovery without publicly exposing participant-id.
This proposal extends the same layered discipline to participant, nym, and routing-subject material.
Key decisions:
- The current
orbiplex-participant-seed-v1signing derivation remains stable and backward compatible; existingmnemonic -> participant:did:key:...mapping must not change. - New key roles are added through deterministic, versioned derivation from a participant root seed, not by ad-hoc chaining from one private key into the next.
participant/vault-wrapis a local symmetric wrapping purpose for encrypted vault storage, not a public wire identity.- Nyms SHOULD use random per-nym local seeds stored inside an encrypted participant-owned vault rather than being fully deterministically derived from the participant root.
- Routing subjects (
routing:did:key:...) SHOULD follow the same private vault discipline as nyms, but with delivery/contact semantics rather than authorship semantics. pseudonym-vault.v1is the first schema seed for this private vault. It MAY be synchronised to external storage, but only as an opaque, encrypted, versioned blob with no publicparticipant-iddisclosure.- Public envelopes and encrypted payload metadata MUST NOT expose participant
recovery recipients or otherwise reveal
nym -> participantorrouting-subject -> participantlinkage.
MVP implementation decisions:
participant/vault-wrapdefaults to the root-only compatibility profile; an optionalroot+local-passphraseprofile adds a local second factor without changing the public role purpose.- The participant root remains implicit behind mnemonic/recovery flows; it is not materialized as a separate public or syncable artifact.
- Vault synchronization uses a single-writer latest-snapshot model: importing an older version is rollback rejection, and importing a higher version that does not supersede the local latest snapshot is explicit conflict rejection.
route:...remains an advisory routing identifier with no mandatory keypair or recovery model.routing:did:key:...is the cryptographic routing-subject identity whose seed belongs in the encrypted vault.participant/dhis a local-only role: it may be derived on demand for controlled direct/sealed protocols, but it is not published as a standing Seed Directory, node advertisement, capability advertisement, vault metadata, or recovery-bundle metadata artifact.participant/recovery-wrapis implemented as a local sealed recovery-bundle wrapping purpose. It is not social recovery, escrow, or hardware custody.
Context and Problem Statement¶
Orbiplex currently freezes the following relevant pieces:
orbiplex-participant-seed-v1defines participant creation/import from a BIP39 mnemonic and yields one stable Ed25519 participant signing identity.participant-key-envelope.v1protects participant signing material at rest with a local passphrase-controlled envelope.- Node transport already uses a deterministic Ed25519-to-X25519 split for static key agreement in the peer-session handshake.
nym-certificate.v1defines pseudonymous authorship and certification, but does not yet define how nym private material is recovered, rotated, or stored without leaking participant linkage.routing-subject-binding.v1already defines a publicrouting:did:key:...delivery/contact surface with an Ed25519 signature plus a separateencryption/key/public, but it does not yet define how that routing-subject material is privately derived, stored, or recovered.
This leaves several gaps:
- There is no stable participant-facing model for key roles beyond signing.
- There is no private, syncable vault model for nym or routing-subject secret material.
- A naive multi-recipient encryption envelope that includes a participant recovery key on the wire would leak participant linkage in public metadata.
- A naive design that derives every nym or routing subject deterministically from one participant secret would maximize blast radius and reduce privacy isolation.
Orbiplex needs a design that preserves:
- stable participant identity derivation,
- pseudonymous nym publication,
- privacy-preserving routing-subject delivery/contact surfaces,
- no public
participant-idleakage in recovery paths, - deterministic recovery where it helps,
- and layered separation between signing, transport DH, and local sealed storage.
Existing Facts¶
requirements-006-node-networking-mvp.mdalready permits deterministic static X25519 derivation from the Ed25519 node identity for MVP transport.participant-seed-contract-v1.mdfreezes the participant signing path as BIP39 -> PBKDF2-SHA512 -> SLIP-0010 Ed25519 ->m/44'/2268'/0'.participant-key-passphrase-lock.mdprotects a participant signing key at rest, but still treats the protected payload as one signing secret rather than a role-partitioned vault.nym-certificate-and-renewal-baseline.mdmodels nym authorship and certification, but not nym encryption-key recovery or vault synchronisation.routing-subject-binding.v1already treatsrouting:did:key:...as a signed public routing subject and carries a separateencryption/key/publicfor delivery/contact use.
Goals¶
- Preserve the existing stable participant signing identity path.
- Introduce a participant-facing key-role derivation model that is compatible with the current signer and recovery-seed baseline.
- Provide a clean private-storage model for nym and routing-subject secret material without public participant linkage.
- Make encrypted backup and cross-device sync of nym and routing-subject material possible.
- Keep wire protocols and recovery storage stratified.
Non-Goals¶
- This proposal does not replace
orbiplex-participant-seed-v1. - This proposal does not define a public nym-to-participant recovery service API.
- This proposal does not add a public recovery recipient to message envelopes.
- This proposal does not define social recovery, threshold custody, or HSM-only operation.
- This proposal does not require all nyms or routing subjects to be deterministically derived from one root.
Options Considered¶
Option A: Fully deterministic pseudonym derivation from the participant root¶
Benefits:
- minimal local state,
- easy regeneration of all nym and routing-subject keys from one seed.
Risks:
- one participant-root compromise compromises all pseudonyms,
- weaker isolation between nyms and routing subjects,
- difficult partial retirement and migration,
- stronger pressure toward metadata linkage mistakes.
Option B: Public multi-recipient envelopes with participant recovery key¶
Benefits:
- conventional hybrid-encryption recovery pattern,
- participant can decrypt any nym-targeted or routing-targeted payload.
Risks:
- envelope metadata risks exposing a stable participant recovery recipient,
- public wire artifacts become a linkage oracle,
- directly conflicts with the requirement to avoid public
participant-idexposure.
Option C: Deterministic participant role roots plus encrypted private pseudonym vault¶
Benefits:
- preserves stable participant signing identity,
- adds explicit role split,
- keeps participant linkage off the wire,
- allows cross-device sync via ciphertext-only blobs,
- gives better per-pseudonym isolation than full deterministic derivation.
Costs:
- requires a private vault format and local sync lifecycle,
- requires a recovery/export story stronger than raw signing-key export.
Decision¶
Orbiplex adopts Option C.
1. Stable participant signing path remains unchanged¶
orbiplex-participant-seed-v1 remains the canonical signing identity path for
participant:did:key:....
The current mapping:
BIP39 mnemonic
-> PBKDF2-SHA512 seed
-> SLIP-0010 Ed25519
-> m/44'/2268'/0'
-> participant signing key
-> participant:did:key:...
MUST remain backward compatible.
New key-role derivation MUST be additive. It must not silently remap existing mnemonics to different participant identifiers.
2. Participant key roles are derived from a root-seed layer, not chained from ad-hoc private keys¶
The model introduces a conceptual participant root-seed layer.
For mnemonic-backed participants this is the mnemonic-derived seed material before the final signing-key projection. Future implementations MAY materialise that layer explicitly; current implementations MAY keep it implicit as long as compatibility is preserved.
Role-specific derivation must be deterministic, versioned, and domain-separated. Representative labels:
orbiplex/v1/participant/signing
orbiplex/v1/participant/dh
orbiplex/v1/participant/vault-wrap
orbiplex/v1/participant/recovery-wrap
The core invariant is:
- one root material,
- multiple role-specific derivation contexts,
- no informal “private key A becomes private key B” chaining.
3. Participant roles¶
The minimum role model is:
participant/signing- algorithm: Ed25519,
- public role: authorship, consent, capability issuance, governance-bound participant actions,
-
stable public identifier anchor.
-
participant/dh - algorithm: X25519 or later equivalent,
- private role: direct key agreement, sealed-session or recipient-side private communication where a participant-scoped DH surface is needed,
-
not required to be publicly advertised in MVP.
-
participant/vault-wrap - algorithm class: symmetric AEAD wrapping key derived from the participant root,
- private role: encrypting participant-owned vault snapshots and local secret stores,
-
never a public wire identity.
-
participant/recovery-wrap(deferred but reserved) - private role: future escrow or recovery-bundle sealing distinct from both signing and ordinary vault wrap.
4. Nym and routing-subject private material live in an encrypted vault¶
Nyms SHOULD NOT be fully and publicly predictably derived from the participant signing identity.
Instead, each nym SHOULD have its own local seed material:
nym-seed -> nym/signing
nym-seed -> nym/dh
The nym-seed SHOULD be random and per-nym.
This material is stored inside an encrypted participant-owned vault protected by
participant/vault-wrap.
This gives:
- stronger separation between nyms,
- easier retirement of one nym without touching the others,
- no public participant recovery recipient on the wire,
- local recoverability after node loss.
Routing subjects SHOULD use the same storage pattern:
routing-subject-seed -> routing-subject/signing
routing-subject-seed -> routing-subject/dh
Important boundary:
routing:did:key:...is not merely an opaque route label;- it is a delegated/public routing subject anchored in a signing key;
routing-subject-binding.v1additionally carries a separateencryption/key/publicfor reply/contact delivery.
This makes routing-subject closer to a delivery/contact pseudonym than to a
plain advisory route label.
5. Private vault sync model¶
The first schema seed for this model is:
doc/schemas/pseudonym-vault.v1.schema.json
The vault MAY be synchronised across devices or to external storage, but only as an opaque ciphertext blob.
For MVP / full v1 runtime, synchronization is deliberately not a multi-writer
merge system. A node stores and imports opaque snapshots with vault/version
and supersedes lineage. Import accepts only a higher version that supersedes
the current latest local snapshot. Older snapshots are rejected as rollback;
parallel higher-version snapshots are rejected as conflicts.
The remote store must see only technical metadata needed for retrieval and rollback detection, for example:
{
"schema": "pseudonym-vault.v1",
"vault/id": "pseudonym-vault:01JV...",
"vault/version": 17,
"vault/profile": "participant-private-pseudonyms",
"contents/kinds": ["nym", "routing-subject"],
"crypto/kdf": "hkdf-sha256",
"crypto/aead": "xchacha20-poly1305",
"crypto/wrap-purpose": "participant/vault-wrap",
"salt": "...",
"nonce": "...",
"ciphertext": "...",
"supersedes": "pseudonym-vault:01JU..."
}
The store SHOULD NOT learn:
participant-id,- nym public identifiers as explicit metadata,
- routing-subject public identifiers as explicit metadata,
- plaintext nym handles,
- vault contents.
A synchronised vault is therefore:
- encrypted,
- versioned,
- mutable as local secret state,
- but not a public append-only fact stream.
6. Advisory route ids are a separate class from routing subjects¶
Orbiplex currently has two route-like surfaces that must not be conflated:
route:...- an advisory route id, for example in TLS certificate CN extraction and endpoint consistency checks,
- may be an opaque operational label,
-
does not by itself imply a private keypair.
-
routing:did:key:... - a delegated/public routing subject,
- anchored in an Ed25519 signing identity,
- usually paired with a separate encryption public key for contact/delivery.
This proposal concerns the second class. Opaque advisory route: labels do not
need vault recovery semantics unless a future proposal explicitly elevates them
into cryptographic subjects.
7. Wire privacy invariant¶
Public or federated payloads MUST NOT expose a participant recovery recipient as an ordinary encryption recipient when the intention is pseudonymous delivery.
If a payload is addressed to a nym or routing subject, the public artifact may reveal:
- the nym or routing-subject public identity,
- the relevant signature,
- attached or inline proof material.
It MUST NOT reveal:
- a public
participant-idrecovery recipient, - a stable recipient handle that trivially maps back to the participant,
- explicit
nym -> participantorrouting-subject -> participantcorrelation metadata.
8. Recovery and export consequence¶
The current fallback export path that yields only raw participant private-key material is not sufficient for full future role recovery.
If Orbiplex wants recoverable participant DH roles and private vault restoration, then operators SHOULD preserve one of:
- the participant mnemonic / root recovery material,
- or a role-aware encrypted recovery bundle that includes enough material to restore the role tree and the private vault.
Raw signing-key-only export is therefore a legacy-compatible minimum, not a future-complete recovery shape.
Proposed Model / Sequence¶
Scenario: restore after node loss¶
- The operator creates a participant from
orbiplex-participant-seed-v1. - The node derives the stable participant signing identity.
- The node derives
participant/vault-wrapfrom the same participant root. - The node creates one or more nyms and routing subjects with random local seeds.
- The node stores those seeds and local metadata inside a private encrypted vault.
- The vault is encrypted locally and synchronised as ciphertext to one or more storage targets.
- The node fails or the device is lost.
- The operator imports the participant mnemonic or equivalent root recovery material on a new node.
- The new node recreates the same participant signing identity and
participant/vault-wrapmaterial. - The new node downloads the latest encrypted vault snapshot, decrypts it, and restores the nym and routing-subject seeds.
- The restored seeds recreate the nym and routing-subject signing and DH roles without any public disclosure of the participant recovery path.
Trade-offs¶
Benefits¶
- Preserves backward compatibility for participant identity.
- Reuses the same conceptual split already accepted for node networking.
- Keeps pseudonymous linkage off the wire.
- Supports private backup and cross-device sync.
- Covers both public-authorship pseudonyms and delivery/contact pseudonyms.
- Keeps signing, DH, and local sealed-storage semantics separate.
Risks and Constraints¶
- Introduces a new local-state artifact that must be versioned and audited carefully.
- Makes raw signing-key-only recovery increasingly insufficient.
- Requires care in KDF label stability and migration.
- Requires explicit operator UX for vault sync, restore, and conflict handling.
Failure Modes and Mitigations¶
| Failure mode | Impact | Mitigation |
|---|---|---|
| Participant root or mnemonic is compromised | All participant-scoped derived roles are compromised | Encourage passphrase lock, optional extra local secret factor, and explicit recovery hygiene. |
| One nym or routing-subject key is compromised | One pseudonymous surface is compromised, but others should remain isolated | Keep per-nym and per-routing-subject random seeds; do not derive every public pseudonymous surface directly from one public derivation path. |
| Vault ciphertext is tampered with or rolled back | Stale or corrupted nym/routing state | Use AEAD integrity, version counters, and supersedes / rollback detection. |
| Only raw signing-key export survives | Participant id can be restored but extended roles or private vault contents cannot | Mark raw signing-key export as legacy-minimum recovery only; add role-aware recovery bundle later. |
| Public envelope accidentally includes participant recovery recipient | Pseudonymous linkage leak | Make this a schema and policy violation at the envelope boundary. |
route: and routing:did:key: are conflated in implementation |
Wrong recovery model or false key assumptions | Keep advisory route: handling separate from cryptographic routing-subject handling. |
Open Questions¶
Resolved for MVP:
- The participant root-seed layer remains implicit behind recovery flows.
participant/vault-wrapis root-only by default, with an opt-inroot+local-passphraseprofile.- The minimal vault shape is
pseudonym-vault.v1: ciphertext-only outer artifact, semantic runtime validation for crypto fields, version lineage, and private local plaintext records for nym and routing-subject seeds. - Multi-device editing is intentionally not a merge problem in MVP: single-writer latest snapshots are accepted, rollback and conflict are rejected.
participant/dhremains local-only and non-discoverable.participant/recovery-wrapis a local sealed-bundle wrapping purpose.
Still open:
- Whether a future post-MVP vault-wrap profile should add hardware-backed wrapping in addition to the implemented local-passphrase profile.
Consequences¶
Short-term¶
- No existing participant identifiers change.
- Node and docs gain a clean target for participant/nym/routing-subject recovery work.
- Future pseudonym privacy work stops relying on public participant recovery recipients.
Long-term¶
- Role-aware participant recovery can replace signing-key-only export.
- Nym and routing-subject key rotation, vault sync, and cross-device restore gain one coherent foundation.
- Public protocol artifacts stay stratified: pseudonymous authorship and contact/delivery remain on the envelope/discovery boundary, while recovery and local secret storage remain private.
Next Actions¶
Completed in Node MVP:
- Promote
pseudonym-vault.v1from schema seed to runtime import/export support. - Add role derivation for
participant/dh,participant/vault-wrap,nym/{signing,dh}, androuting-subject/{signing,dh}without changing the existing participant signing vector. - Add local nym and routing-subject creation backed by private random seeds stored inside the encrypted vault.
- Add role-aware participant recovery bundle import/export.
- Add negative tests and runtime boundary policy for accidental participant recovery-recipient leakage in pseudonymous or routing metadata.
- Add local-only
participant/dhrole catalog projection without publishing a standing participant DH key. - Add
participant/recovery-wrapsealed-local recovery bundles. - Add optional
root+local-passphrasepseudonym-vault wrapping.
Remaining follow-up:
- Decide whether future hardware-backed vault wrapping is worth standardizing.
Tracking¶
Status legend: todo (no implementation work started), planned (design
defined, awaiting implementation), partial (partially implemented), done
(fully implemented and integrated), open (a design decision is still
required before implementation can proceed), deferred (explicitly post-MVP
for this proposal). Status values are kept consistent with other tracker
tables in this project (see Proposal 057 §Tracking and Proposal 058
§Tracking for precedent).
| ID | Feature | Status | Evidence |
|---|---|---|---|
| P059-001 | Backward-compatible orbiplex-participant-seed-v1 signing path preserved (existing mnemonic → participant signing identity unchanged) |
done | §1 Decision; existing implementation per participant-seed-contract-v1.md. Invariant: no remapping of existing mnemonics; this row tracks that no regression is introduced. |
| P059-002 | Conceptual participant root-seed layer with versioned, domain-separated derivation labels (orbiplex/v1/participant/{signing,dh,vault-wrap,recovery-wrap}) |
done | §2 Decision; Node crypto exposes stable role-purpose constants and derivation helpers while keeping the root implicit behind recovery flows. |
| P059-003 | participant/signing role (Ed25519 authorship / consent / capability / governance) |
done | §3 Decision #1; equivalent to today's participant signing key. |
| P059-004 | participant/dh role (X25519 key agreement for direct / sealed paths) |
done | §3 Decision #2; Node derives this role locally from the implicit participant root and keeps it non-discoverable. |
| P059-005 | participant/vault-wrap symmetric AEAD wrap key derived from the participant root |
done | §3 Decision #3; Node supports the root-only compatibility profile and the opt-in root+local-passphrase profile for pseudonym-vault.v1 sealing and opening. |
| P059-006 | participant/recovery-wrap role (escrow / recovery-bundle wrap) |
done | §3 Decision #4; Node implements the local sealed-bundle profile. Escrow, social recovery, and hardware custody remain separate future procedures. |
| P059-007 | Per-nym random local seed storage inside encrypted participant-owned vault (nym-seed → nym/signing, nym-seed → nym/dh) |
done | §4 Decision; Node creates local nym records from random per-item seeds inside private vault plaintext and reseals snapshots. |
| P059-008 | Routing-subject random local seed storage inside the vault (routing-subject-seed → routing-subject/signing, routing-subject-seed → routing-subject/dh) |
done | §4 Decision; Node creates cryptographic routing:did:key:... subjects from random per-item seeds inside private vault plaintext. |
| P059-009 | pseudonym-vault.v1 private vault format (versioned, AEAD-wrapped, supersedes chain) |
done | §5 Decision + doc/schemas/pseudonym-vault.v1.schema.json; Node mirrors the schema, validates import/export, and enforces runtime crypto semantics. |
| P059-010 | Vault sync / restore runtime in Node (encrypted blob upload / download, version conflict handling, rollback detection) | done | §5 Decision; daemon import/export uses opaque blobs, single-writer latest, rollback rejection, and conflict rejection. |
| P059-011 | Role-aware participant recovery bundle (supersedes raw signing-key-only fallback export) | done | §8 Decision; daemon recovery-bundle export/import supports legacy full-root and sealed-local profiles, restores latest sealed vault snapshots, and fails closed for raw signing-key-only recovery. |
| P059-012 | Explicit signer / sealer purpose labels for participant/signing, participant/dh, participant/vault-wrap in capability surfaces |
done | Node exposes a local role-purpose catalog with public, local-only, vault-private, and internal-wrap exposure tags without publishing private key material. |
| P059-013 | Wire privacy invariant enforcement — no participant-recovery-recipient and no participant-mappable handle in pseudonymous envelopes; negative tests and schema-gate policy | done | §7 Decision; Node rejects participant recovery-recipient leakage for pseudonymous/routing Artifact Delivery and Agora record paths and carries a negative vault-leak fixture. |
| P059-014 | Advisory route: vs cryptographic routing:did:key:... boundary kept distinct in implementation and recovery semantics |
done | §6 Decision; Node protocol tests cover route: as advisory endpoint metadata while routing:did:key:... is the vault-backed cryptographic routing subject class. |
| P059-015 | participant/dh protocol-visible projection decision (publicly discoverable vs controlled-direct only) |
done | MVP decision: controlled-direct/local-only. Node does not publish a standing participant/dh artifact in discovery, capability advertisement, vault metadata, or recovery-bundle metadata. |
| P059-016 | Participant root-seed layer materialization decision (explicit local artifact vs implicit behind recovery flows) | done | MVP decision: implicit root behind mnemonic/recovery flows; no separate public or syncable root artifact. |
| P059-017 | Minimal pseudonym-vault.v1 shape covering sync, restore, rollback detection, and future partial rotation |
done | MVP decision: ciphertext-only outer artifact with runtime semantic crypto validation, private plaintext seed records, vault/version, and supersedes. |
| P059-018 | Vault wrap derivation source decision (participant root only vs root + second local factor) | done | MVP decision: root-only remains the default compatibility profile; root+local-passphrase is implemented as an opt-in strengthened profile. |
| P059-019 | Multi-device concurrent vault edit merge strategy | done | MVP decision: no merge; single-writer latest accepts linear supersession, rejects rollback and concurrent conflict. |