Skip to main content
NorenDocs← Main siteSandbox

Identity and keys

Every Noren install holds a single ed25519 keypair. The same key signs capability grants and appears as the issuer on audit events and memory records. Noren does not maintain a secondary key system.

Persistence

The keypair is stored as the raw 32-byte seed at $NOREN_HOME/identity/local.key with mode 0600 (owner read/write only). The daemon refuses to start if the key file has broader permissions; restrict the file with chmod 0600 to recover.

The corresponding public key is derived from the seed and attached to every AgentId the daemon emits as issuer.

The AgentId shape

AgentId {
  display: "user@local",          // human-readable label
  pubkey:  [u8; 32]               // raw ed25519 pubkey
}

The display half is set on first daemon start (default user@local, kept generic so logs and commits do not leak the operator's hostname). The public key is derived from the seed and is the cryptographically meaningful identifier; display strings may collide, public keys cannot.

Signing helpers

The noren-identity crate exposes:

  • LocalIdentity::generate(display): fresh ed25519 keypair plus display string.
  • LocalIdentity::load_or_create(path, display): loads from disk if present, else generates and persists.
  • LocalIdentity::sign(&self, message): signs arbitrary bytes.
  • verify_with_pubkey(pubkey, message, signature): read-side verification; returns Result<(), IdentityError>.
  • verifying_key_from_bytes(pubkey): converts a 32-byte pubkey to an ed25519_dalek::VerifyingKey.

The signing helpers are deliberately minimal and do not prescribe a canonical message encoding. The capability layer (noren-permissions) supplies its own encoder and passes the resulting bytes to the signing helpers.

Roles

The same ed25519 keypair is used to:

  • sign capability tokens (SignedCapability);
  • authorize settlement actions once the Robinhood Chain flush ships (coming soon). On-chain transactions need a secp256k1 key, so the EVM signer (noren-evm-signer) uses a separate operator key that is never the ed25519 seed;
  • appear as the issuer on audit events and as the owner on memory records.

A single ed25519 key across these roles keeps the local key-management surface to one artifact to back up, rotate, and protect. The trade-off is that compromise of the key affects all of them. EVM payments and attestations use their own secp256k1 key, supplied to a sidecar signer and kept out of the daemon's address space.

Rotation

Rotation is deliberate and disruptive. Re-issuing the keypair invalidates every capability signed under the prior key: verification fails because the expected granter public key no longer matches the daemon's active key. Plan the corresponding re-grant in advance of rotation.

Procedure:

  1. Stop the daemon.
  2. Move the existing key file aside, or delete it once no other state references the corresponding public key.
  3. Start the daemon. A new keypair is generated on first run.
  4. Re-grant the capabilities required by registered agents. The audit log records the rotation implicitly through the change of issuer on subsequent events, and explicitly through the new grant events.
  5. Update any external systems bound to the prior public key (contract authority records on Robinhood Chain once deployed, third-party integrations).

Subordinate keys

The current implementation provisions one keypair per host. A later milestone introduces subordinate keys for delegated agents, each signed by the root key, so that compromise of an individual subordinate does not require a full root rotation. Until that capability ships, the single keypair carries the same protection requirements as a host SSH key.

Related

  • Capability tokens: everything that depends on the signing helpers.
  • Settlement: the planned Robinhood Chain side; EVM transactions are signed by a separate secp256k1 operator key.
  • Security model: the file-permissions, threat-model context.