Motebit

Identity & Cryptography

How motebit creates and manages persistent sovereign identity

Session tokens expire. API keys are shared secrets managed by someone else. A motebit agent owns an Ed25519 keypair — the private key never leaves the device, and the identity persists across sessions, devices, and intelligence providers. This guide explains how the cryptographic identity works, from first launch through multi-device sync.

For the conceptual foundation, see Identity. For where identity sits in the package architecture, see Architecture.

The identity bootstrap

On first launch, the system runs a shared bootstrap protocol (bootstrapIdentity in @motebit/core-identity):

  1. Generate an Ed25519 keypair using @noble/ed25519 — a zero-dependency, audited library. The same signing scheme used by SSH, Signal, and WireGuard.
  2. Store the private key in the platform's secure storage. On desktop, the Tauri keyring. On CLI, PBKDF2-encrypted as cli_encrypted_key in ~/.motebit/config.json. On mobile, expo-secure-store. The private key never touches a plaintext config file.
  3. Generate a UUID v7 motebit_id (time-ordered, sortable) and a device_id.
  4. Register the device against the identity, binding the device's public key to the motebit_id.
  5. Write config — the motebit_id, device_id, and public key are persisted to ~/.motebit/config.json (non-secret metadata only).

On subsequent launches, the identity loads from config and the keypair from the keyring. No network round-trip required.

The motebit.md identity file

The motebit.md file is a human-readable, cryptographically signed identity document conforming to the motebit/identity@1.0 specification. It declares who the agent is, what it may do, and how it governs itself.

The file has two parts:

  • YAML frontmatter — identity metadata, governance thresholds, privacy rules, memory configuration, and registered devices
  • Signature comment<!-- motebit:sig:motebit-jcs-ed25519-hex-v1:{hex_signature} --> on the line immediately following the closing ---. The inline cryptosuite identifier makes the suite explicit on the wire so post-quantum migration is a registry addition, not a wire-format break.

The signature covers the canonical JCS (RFC 8785) JSON serialization of the parsed frontmatter under the motebit-jcs-ed25519-hex-v1 cryptosuite. Any modification — even a single character — invalidates it. The public key is embedded in the frontmatter, making the file self-contained: verification requires no external service. See the Identity Standard guide for the full file format, creation commands, and verification workflow.

Multi-device registration

A single motebit identity spans multiple devices. Each device has its own Ed25519 keypair — there is no shared private key.

StepWhat happens
Device registrationThe device generates a keypair and registers its public key with the IdentityManager. The device receives a device_id and device_token.
PairingA 6-character code exchange, relay-mediated, with no shared secrets. The new device proves it holds a valid keypair.
Sync authenticationTo communicate with the sync relay, the device signs a short-lived token with its private key. The relay verifies the signature against the registered public key.

Devices are listed in the motebit.md file under the devices array, each with its own device_id, name, public_key, and registered_at timestamp.

Signed tokens

Signed tokens authenticate sync requests between a device and the relay server. They are lightweight, short-lived, and require no server-side secret storage.

Format: base64url(payload).base64url(signature)

Payload fields:

All fields below are required — a verifier MUST reject a token missing any of them (spec auth-token@1.0 §3). Build the token with createSignedToken, which sets them for you; do not hand-assemble a {mid,did,iat,exp} payload — it will be rejected for missing jti/aud/suite.

FieldRequiredDescription
midyesThe motebit_id
didyesThe device_id
iatyesIssued-at timestamp (milliseconds since epoch)
expyesExpiration timestamp (default: 5 minutes from iat)
jtiyesUnique token nonce (UUID v4 recommended) — prevents replay. Must be unique per token.
audyesAudience — the endpoint/operation the token authorizes (e.g. "task:submit"). Prevents cross-endpoint replay.
suiteyesCryptosuite, always "motebit-jwt-ed25519-v1" today. Signed; missing/unknown is rejected fail-closed.

The device signs the raw UTF-8 bytes of the JSON payload (not the base64url form) with its Ed25519 private key. The relay verifies in two steps: (1) parse the base64url payload without crypto to extract the device_id — O(1) lookup; (2) verify the Ed25519 signature against the device's registered public key. Expired tokens, and tokens missing jti/aud, are rejected.

Encryption at rest

Sensitive data is encrypted before leaving the agent boundary:

ContextMechanism
Sync payloadsAES-256-GCM with a 256-bit random key and 12-byte nonce. The 16-byte authentication tag is appended to the ciphertext.
CLI private keyPBKDF2 key derivation (600,000 iterations, SHA-256) from a user passphrase, then AES-256-GCM encryption.
Desktop/mobilePrivate key stored in OS keyring (hardware-backed where available). No application-layer encryption needed.

All cryptographic operations use Web Crypto API or @noble/hashes and @noble/ciphers — zero-dependency, audited implementations. Sensitive byte arrays are securely erased (overwritten with random data, then zeroed) after use.

Verification

Anyone can verify a motebit's identity. The @motebit/crypto package has zero monorepo dependencies — only @noble/ed25519.

# CLI verification
npx create-motebit verify motebit.md
// Programmatic verification
import { verify } from "@motebit/crypto";
import fs from "node:fs";

const result = await verify(fs.readFileSync("motebit.md", "utf-8"));
if (result.valid) {
  console.log("Verified:", result.identity.motebit_id);
}

A valid result includes a did field — the W3C did:key derived from the Ed25519 public key. This bridges motebit to ecosystems that use Decentralized Identifiers (Verifiable Credentials, DIDComm, MCP-Identity).

if (result.valid) {
  console.log(result.did); // "did:key:z6Mk..."
}

A valid signature proves the holder has the private key. It does not prove the holder is trustworthy. Trust is accumulated at the application layer through history, governance, and memory — not by the identity file alone.

Key management

ConcernApproach
Key storageOS keychain (desktop/mobile) or PBKDF2-encrypted file (CLI). Never plaintext.
Key rotationSigned succession records (spec §3.8). The old keypair signs a tombstone declaring the new keypair as successor — both keys sign the canonical payload. The motebit_id persists across rotations. Rotate via motebit rotate (CLI) or npx create-motebit rotate (scaffolder). No centralized revocation — succession chains are verifiable by anyone.
Guardian recoveryEnterprise agents can declare an organizational guardian (spec §3.3). If the primary key is compromised, the guardian signs a recovery succession record — rotating to a new key without the compromised key. Guardian revocation requires dual authorization (both keys sign).
Secure erasuresecureErase() overwrites byte arrays with random data then zeros before garbage collection.
Private key scopeThe private key never appears in motebit.md, never crosses the network, and never enters a config file.

On this page