identity

Portable identities for signing, recovery, and derived encryption keys.

@ternent/identity defines the capability root used across the Ternent stack. The identity itself is Ed25519 and seed-backed. From that same portable model, the package derives public keys, stable key IDs, X25519 keys, and age-compatible helpers when encryption surfaces need them.

One portable identity root. Signing keys first. Encryption helpers derived explicitly.

Identity is not a wallet, auth server, hosted keystore, or encryption protocol by itself.

Identity surfaces

Portable
Root material
32-byte seed
Signing model
Ed25519 identity
Lookup handle
derived keyId
Encryption helpers
X25519 + age-compatible

Identity Model

One identity, several key surfaces

@ternent/identity keeps the core model small. The portable object stores seed material plus derived public metadata. The package then exposes the key surfaces you need for signing, verification, recovery, and encryption interoperability.

Seed-backed root

The serialized identity stores seed material as the durable root capability. Mnemonics are a human recovery format for regenerating that same root.

Ed25519 signing identity

The main cryptographic identity is Ed25519. Use it for signing actions, proofs, and payloads where authenticity matters.

Stable public references

The package derives a public key and a keyId so the identity can be referenced, shared, and verified without exposing seed material.

Derived encryption surfaces

When encryption is needed, the same identity can derive X25519 keys and age-compatible recipient or secret key helpers without changing the root model.

Serialized Form

A portable identity object

The core artifact is plain JSON. It stores the signing identity root, public metadata, and enough information to move the identity between runtimes without redefining the contract.

proof.json
{
  "format": "ternent-identity",
  "version": "2",
  "algorithm": "Ed25519",
  "createdAt": "2026-03-13T00:00:00.000Z",
  "publicKey": "BASE64URL-RAW-ED25519-PUBLIC-KEY",
  "keyId": "identity_...",
  "material": {
    "kind": "seed",
    "seed": "BASE64URL-RAW-32-BYTE-SEED"
  }
}

X25519 keys and age-compatible strings are derived from this identity when needed. They are helper surfaces, not a second identity format.

Key Types

What keys are involved?

@ternent/identity is primarily an Ed25519 identity package, but it derives a few adjacent key forms so the same identity can cross signing and encryption boundaries cleanly.

Ed25519 identity

The primary key type. This is the signing identity used for signatures, verification, and proof-oriented flows.

Public key and keyId

The public key is the verification surface. The keyId is a stable derived identifier for references, indexes, manifests, and user-facing handles.

X25519 key pair

Derived from the identity for encryption use cases that need an X25519 public or private key instead of Ed25519 signing material.

Age-compatible helpers

Recipient and secret key helpers expose the derived encryption capability in formats that fit age-compatible tooling and Armour.

The Suite

Identity is the capability root across the stack.

Other Ternent packages build on this identity model instead of redefining their own. That keeps signing, encryption, and replayable application history aligned around one portable root.

Identity defines the capability root. Other packages define what that capability is used for.

Armour

Armour

Derives age-compatible recipients and decryptors from the same identity model for explicit encryption flows.

Explore Armour
Seal

Seal

Uses the signing identity for portable proofs and signed artifacts without changing the core identity contract.

Explore Seal
Concord

Concord

Builds replayable application history on the same identity root for authored, signed, and optionally encrypted workflows.

Explore Concord

How it works

Derive the right capability from one root

Start from seed material or a 12/24-word mnemonic, derive the signing identity, and only then derive the adjacent key surfaces a flow actually needs.

  1. 1

    Create or restore the root

    Generate a fresh identity from random seed material, or restore the same root from a mnemonic phrase.

  2. 2

    Derive the Ed25519 signing identity

    Use the root to derive the signing keypair and the public key that other systems can verify against.

  3. 3

    Compute a stable keyId

    Derive a stable identifier from the public key so references stay portable without inventing a separate registry.

  4. 4

    Derive encryption helpers when needed

    Only derive X25519 or age-compatible recipient and secret key helpers when the consuming surface actually needs encryption capability.

The root identity remains Ed25519. Encryption-oriented keys are derived surfaces, not a change in identity type.

For Developers

A small package with one identity contract

The package keeps creation, recovery, signing, verification, and key derivation on top of one serialized contract. It does not mix in storage, auth sessions, or encryption envelopes.

Create and restore

Sign and verify

Derive encryption helpers

SerializedIdentity

Serialized identity contract

type SerializedIdentity = {
  format: "ternent-identity";
  version: "2";
  algorithm: "Ed25519";
  createdAt: string;
  publicKey: string;
  keyId: string;
  material: {
    kind: "seed";
    seed: string;
  };
};

Portable JSON stores the seed-backed identity root plus public metadata. That is the contract other surfaces build on.

View package source

Boundaries

What Identity does not do

  • It does not host, sync, or escrow keys for you.
  • It does not define login sessions, user profiles, or account recovery services.
  • It does not encrypt data by itself. Armour owns encryption flows.
  • It does not define proof artifacts or replayable state. Seal and Concord own those layers.

Ready

Start from one portable identity model.

Use @ternent/identity when you want seed-backed Ed25519 identities, mnemonic recovery, stable key IDs, and explicit derivation into encryption-friendly key surfaces.