Spec Blog Products Services Contact Follow the Build
Build in Public · #4

We Had 5 Open Questions. Here Are Our Answers.

In the Phase 1 Identity Layer spec, we published five open design questions and said we'd resolve them before writing code. This post is where we do that — the tradeoffs, the leans, and the final calls.


Q1: Key Rotation

The question

Should v1 support key rotation — the ability to swap an Ed25519 keypair while keeping the same AgentID?

The tradeoff

Rotation is a security necessity long-term. But in a self-sovereign distributed system it's non-trivial: every verifier needs to handle key chains, not just current keys. Every Registry node needs to propagate succession records. The happy-path — 99% of users who never rotate — pays the complexity tax for the 1% who do.

Decision: skip rotation in v1. The AgentID is bound to its keypair. Compromised keypair = new AgentID. This is a real cost, but an honest one. We'll add rotation in v2, designed against real usage data instead of imagined patterns.

Q2: Self-Sovereign vs. Operator-Issued

The question

Should agents generate their own AgentIDs (self-sovereign), or should operators issue them on behalf of agents they deploy?

The tradeoff

Pure self-sovereignty: no gatekeepers, any agent generates an identity without permission. But there's no accountability link between the agent and the org that deployed it. Operator-issued: adds accountability, but creates a dependency and a centralization point.

Decision: self-sovereign by default, optional operator attestation. Any agent generates its own keypair and signs its own record — no permission required. Operators who want accountability can add an optional operator_attestation field: a signature over the record using the operator's keypair. Peers who care look for it; peers who don't, ignore it.

Q3: Mutability

The question

After creation, what fields in an AgentID record can be updated?

The tradeoff

Pure immutability is simple and secure — but too rigid. An agent's display name might legitimately change. Requiring a new AgentID for cosmetic updates creates churn. But every mutable field is a potential attack vector.

Decision: name and description are mutable; everything else is immutable.
  • id, public_key, created_at — immutable
  • name, description, capabilities_hint — mutable

Updates carry a new signature over the full updated record. The Registry stores the latest valid version. You can't update a field without holding the private key.

Q4: Capabilities in the Identity Record

The question

Should the AgentID record include a list of capabilities, or should capabilities live exclusively in Passports?

The tradeoff

Capabilities in the identity record makes discovery easy — one query, you know what the agent can do. But identity is self-sovereign, so those claims are unverified assertions. Capabilities also change more often than identity, creating update churn on the identity record. And it mixes two concerns that should be separated: "who" vs. "what can it do."

Decision: capabilities belong in Passports, not identity records. The AgentID may include a capabilities_hint — an advisory, unverified list useful for rough filtering, clearly marked as unverified. All authoritative capability claims live in Passports (Phase 2), which have issuers, signatures, and expiry.

Q5: Wire Format Versioning

The question

How do we version the wire format so future spec changes don't break existing implementations?

The tradeoff

If v1 records are stored in a distributed Registry and we publish a v2 spec with breaking changes — what happens to old records? Silent corruption is unacceptable. A versioning scheme that requires all nodes to upgrade simultaneously also doesn't work.

Decision: version field in every record; unknown major versions are rejected.

Backward-compatible changes leave "version": "1" unchanged — new optional fields are ignored by older implementations. Breaking changes bump to "version": "2"; v1-only implementations reject with UNSUPPORTED_VERSION. The signature covers the version field — you can't downgrade a v2 record by editing the field.


What Phase 1 Actually Looks Like

With these five decisions made, the AgentID record spec is locked for v1:

{
  "version": "1",
  "id": "agnt_01HZXYZ...",
  "name": "My Agent",
  "description": "Optional human-readable description",
  "capabilities_hint": ["tool:web_search", "domain:real_estate"],
  "created_at": "2026-04-01T00:00:00Z",
  "updated_at": "2026-04-01T00:00:00Z",
  "public_key": {
    "algorithm": "Ed25519",
    "value": "base64url-encoded..."
  },
  "operator_attestation": null,
  "signature": "base64url — self-signed over all fields except signature"
}

Fixed in v1

Next step: Write the library. packages/identity/ in TypeScript. generateIdentity(), verifyIdentity(), signClaim(), verifyClaim(). Web Crypto API throughout. Target: Node 18+, modern browsers, Cloudflare Workers.

We'll post the first implementation milestone — test suite passing, first successful cross-agent verification — as post #5.

Follow the build on GitHub →

— Ray & the Agentcy.Services team

← #3: What Is an Agent Passport? #5 coming soon