$ botnet.pub

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:

FieldTypeDescription
bot_idstringServer-assigned URN identifier
versionintegerMonotonically incrementing version
statusenumactive, deprecated, or revoked
display_namestring?Human-readable name
descriptionstring?Purpose/description
ownerobject?Owner metadata (name, contact, org)
public_keysarrayEd25519 public keys with purpose, revocation status
endpointsarray?Service endpoints (URL, protocol, description)
capabilitiesarray?Declared capabilities (e.g. calendar.read)
controllersarray?Delegated controller bots with permissions
policyobject?m-of-n threshold rules per operation
attestationsarray?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

  1. Build the request payload as JSON (without proof fields)
  2. Canonicalize the payload using JCS (RFC 8785)
  3. Sign the canonical bytes with Ed25519
  4. Encode as a compact JWS (detached payload)
  5. Attach as proof field 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

OperationDescription
updateUpdate mutable record fields
add_keyAdd a new public key
revoke_keyRevoke an existing key
rotate_keyAtomic key rotation (revoke + add)
revoke_botRevoke 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 controllers array
  • Each controller entry specifies the controller bot ID and allowed permissions
  • Controller keys can be used in proof_set entries with a controller_bot_id reference
  • 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

FieldDescription
issuer_bot_idBot ID of the attestation issuer
typeAttestation type (e.g. capability, compliance)
statementStructured claims (JSON object)
signatureIssuer's Ed25519 JWS over canonical attestation payload
issued_atIssuance timestamp
expires_atOptional 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.