Protocol Specification
Bot ID derivation, proof model, policy engine, and trust delegation.
Protocol Specification
Bot ID
A Bot ID is a deterministic identifier derived from a public key:
urn:bot:sha256:{hex(SHA-256(pk))}The same Ed25519 public key always produces the same Bot ID. No central authority assigns them — identity is derived from cryptographic material alone.
The pk bytes are the raw 32-byte Ed25519 public key (not multibase-encoded). The SHA-256 hash is hex-encoded (lowercase, 64 characters).
Bot Record
The identity document for a bot. A Bot Record contains:
| Field | Type | Description |
|---|---|---|
bot_id | string | Server-assigned URN identifier |
version | integer | Monotonically incrementing version |
status | enum | active, deprecated, or revoked |
display_name | string? | Human-readable name |
description | string? | Purpose/description |
owner | object? | Owner metadata (name, contact, org) |
public_keys | array | Ed25519 public keys with purpose, revocation status |
endpoints | array? | Service endpoints (URL, protocol, description) |
capabilities | array? | Declared capabilities (e.g. calendar.read) |
controllers | array? | Delegated controller bots with permissions |
policy | object? | m-of-n threshold rules per operation |
attestations | array? | Third-party attestations received |
The bot_id, version, created_at, and updated_at fields are server-managed. All other fields are client-provided and signed.
Proof Model
Every mutation (register, update, revoke, key rotation) must include a cryptographic proof. The proof is a JWS (JSON Web Signature) over the JCS-canonicalized request payload.
Signature Process
- Build the request payload as JSON (without proof fields)
- Canonicalize the payload using JCS (RFC 8785)
- Sign the canonical bytes with Ed25519
- Encode as a compact JWS (detached payload)
- Attach as
prooffield in the request
Single Signature
{
"proof": {
"algorithm": "Ed25519",
"key_id": "k1",
"created": "2026-02-15T00:00:00Z",
"jws": "<detached-jws>"
}
}Multi-Signature (proof_set)
For operations requiring m-of-n approval, provide a proof_set array instead:
{
"proof_set": [
{
"algorithm": "Ed25519",
"key_ref": { "key_id": "k1" },
"created": "2026-02-15T00:00:00Z",
"jws": "<detached-jws-1>"
},
{
"algorithm": "Ed25519",
"key_ref": { "key_id": "k2", "controller_bot_id": "urn:bot:sha256:..." },
"created": "2026-02-15T00:00:00Z",
"jws": "<detached-jws-2>"
}
]
}Policy Engine
Bots can define threshold policies per operation type. A policy specifies how many signers are required and from which set of keys.
Operation Types
| Operation | Description |
|---|---|
update | Update mutable record fields |
add_key | Add a new public key |
revoke_key | Revoke an existing key |
rotate_key | Atomic key rotation (revoke + add) |
revoke_bot | Revoke the entire identity |
Threshold Rules
Each rule specifies a threshold (minimum required signers) and a signers set. Signers can reference the bot's own keys or keys from controller bots.
{
"policy": {
"rules": [
{
"operation": "revoke_bot",
"threshold": 2,
"signers": {
"keys": ["k1", "k2"],
"controllers": ["urn:bot:sha256:..."]
}
}
]
}
}Controller Delegation
A controller is a bot-to-bot trust relationship. A controller bot can be granted specific permissions over another bot, enabling hierarchical management.
Delegation Model
- A bot lists controller bots in its
controllersarray - Each controller entry specifies the controller bot ID and allowed permissions
- Controller keys can be used in
proof_setentries with acontroller_bot_idreference - The registry resolves controller keys during signature verification
Controller bots must be registered in the registry and have active status. Revoked controllers cannot sign on behalf of other bots.
Attestations
An attestation is a signed statement one bot makes about another. Attestations are first-class objects stored on the subject bot's record.
Attestation Fields
| Field | Description |
|---|---|
issuer_bot_id | Bot ID of the attestation issuer |
type | Attestation type (e.g. capability, compliance) |
statement | Structured claims (JSON object) |
signature | Issuer's Ed25519 JWS over canonical attestation payload |
issued_at | Issuance timestamp |
expires_at | Optional expiration timestamp |
The registry verifies that the issuer bot exists, has active status, and that the referenced key is valid before accepting the attestation.
Auth Flow
The complete authentication flow for mutation operations:
Client Registry
| |
| 1. GET /v1/nonce |
|--------------------------------------->|
|<--- { nonce: "abc123" } |
| |
| 2. Build payload (JSON) |
| 3. JCS-canonicalize payload |
| 4. Sign canonical bytes (Ed25519) |
| 5. Attach JWS as `proof` field |
| |
| POST /v1/bots { ...payload, proof } |
|--------------------------------------->|
| 6. Strip proof, re-canonicalize |
| 7. Verify JWS against bot's keys |
| 8. Check nonce (anti-replay) |
| 9. Evaluate policy thresholds |
|<--- 201 Created |For multi-signature operations, include a proof_set array. Each entry references a key_ref with key_id and optional controller_bot_id.