Keys are the only thing in the system that cannot be re-issued without consequence. Everything else — documents, sessions, credentials — is derived from them. This page covers the lifecycle end to end, and where the SDK does the work for you.

The five-minute version

Everything derives deterministically from one 32-byte seed. Persist that seed (owner-only file, env var, or KMS); the whole identity restores from it.
Two keypairs come out of the seed:
  • Ed25519 signing keypair — the seed is the signing key (Ed25519 signing keys are 32-byte seeds). Signs challenges, lineage proofs, and ACT-related material.
  • X25519 encryption keypair — derived via BLAKE3 context-separated derivation (arsenal.agent.encryption_key), the same derivation across the Rust, TypeScript, and Python SDKs, so a seed moved between SDKs restores the same keys.

The lifecycle, shelf by shelf

Generation

Key pairs are generated with a CSPRNG: 32 bytes of entropy, then the Ed25519 pair from that seed. The public key is multibase-encoded (base58btc with the Ed25519 multicodec prefix) to form the DID identifier.
  • CSPRNG seed generation (32 bytes of entropy)
  • Ed25519 key pair derivation from seed
  • Multibase encoding of public key (z prefix + base58btc)
  • DID identifier construction from the multibase public key
The private key is wrapped in ZeroizeOnDrop immediately after generation. It never touches swap, logs, or debug output.

Derivation

Child keys derive from parent keys with HKDF-SHA256 (RFC 5869), enabling hierarchical key structures where one root deterministically produces unlimited children. Paths follow BIP-44/SLIP-0010 conventions.
  • HKDF-Extract: derive PRK from parent key + salt
  • HKDF-Expand: derive child key material from PRK + info
  • Ed25519 key pair generation from derived material
  • Path recording for audit and reconstruction
Intermediate key material (the PRK) is zeroed immediately after child key generation. Derivation paths are stored alongside the public key only.

Storage

Private keys are stored encrypted at rest: AES-256-GCM with a KEK derived from a passphrase via Argon2id. The sealed envelope contains the encrypted key, a random nonce, the Argon2 parameters, and a BLAKE3 integrity hash.
  • KEK derivation via Argon2id (memory: 256MB, iterations: 3)
  • AES-256-GCM encryption of the private key with a random nonce
  • BLAKE3 integrity hash over the sealed envelope
  • Storage in the configured key store (file, OS keychain, HSM)
The passphrase is zeroed after KEK derivation; the KEK is zeroed after encryption. Only the sealed envelope persists. Argon2 is tuned to ~1 second on target hardware. The SDK’s keys.saveSeed() writes the raw 32-byte seed file with owner-only (0600) permissions, in Arsenal’s identity_loader format — so a seed moves between the SDKs and the broker’s loader unchanged. At-rest encryption beyond the file permission is deployment policy (KMS, keychain, HSM), not SDK policy.

Usage

Signing: the private key is decrypted into memory, the payload is canonicalized with JCS (RFC 8785), the Ed25519 signature is computed, and the key is zeroed immediately after. All signing operations are constant-time.
  • Decrypt the private key from the sealed envelope
  • JCS canonicalization of the payload
  • Ed25519 signature computation (constant-time)
  • Immediate zeroing of the decrypted key
The decrypted key exists in memory only during signing. Constant-time signing prevents timing side-channels.

Rotation

Rotation replaces a key pair while maintaining identity continuity: the old key signs a rotation proof authorizing the new key, and the DID Document is updated with the new verification method.
  1. Generate the new Ed25519 key pair
  2. Create a rotation proof signed by the old key
  3. Update the DID Document with the new verification method
  4. Publish the rotation proof and updated document
  5. Archive the old key with a revocation timestamp
The old key remains valid for verifying historical signatures but cannot produce new ones. The grace period lets verifiers discover the rotation.

Recovery

Identity restoration when the primary key is lost. Three mechanisms:
  • Social recovery — collect t-of-n guardian signatures from pre-designated guardians
  • FROST recovery — reconstruct from threshold key shares (MHR entities)
  • HSM recovery — present a hardware attestation certificate
Recovery is rate-limited (one attempt per 24 hours), requires proof of relationship to the original DID, and failed attempts are logged in the audit chain.

Derivation path conventions

The rules that matter most

  1. Persist the seed, not the keys. One 32-byte secret restores the whole identity; everything else derives.
  2. Keys never appear in wire artifacts. Public keys and DIDs travel; private keys do not, ever. A token, document, or log containing private key material is an incident.
  3. Zero intermediate material. PRKs, decrypted keys, and passphrases are zeroed at the point of last use, not at cleanup time.
  4. Custody is the killer feature. An agent that can restore its own identity from a seed — across SDKs, across machines, across restarts — is what every other agent framework is missing. Build on it.

Next