Bind CBCL address atoms to cryptographic identity (design) #10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Address atoms (
@planner,@router,@email-service) are just CBCL symbols today. There is no cryptographic identity tied to them — a producer can address an ask to@plannerregardless of who@planneractually is, and a worker can advertise that it speaks dialect X without binding the dialect's@plannerreferences to a verifiable identity. The router resolves recipient atoms by registry lookup, which itself is keyed by self-chosen agent-id at hello time.Under the threat model "honest workflow easy, dishonest no wire harm," this is the deepest open gap: a malicious worker who connects as
agent-id=plannercan intercept messages addressed to@plannerfrom any dialect that uses that symbol, with no way for producers or other workers to detect the substitution.Direction: W3C DIDs
The chosen long-term direction is W3C Decentralized Identifiers for agent identity handles. Address atoms become (or carry) DIDs; resolution returns a DID Document with public keys; the substrate verifies that a connecting agent controls the keys associated with the atom they claim.
Why DIDs:
did:key:(key-as-identifier) for self-contained dev/test,did:web:(DNS-anchored) for hosted services,did:plc:/did:peer:etc. for production scenarios. The substrate doesn't pin a method.verificationMethodentries in a DID Document.Routing implications
Identity and routing are the same design problem from two angles. With DID atoms, the substrate gains a routing primitive it doesn't have today: precise, cryptographically-attributable addressing alongside the existing capability-based dispatch.
Current routing modes:
(lang <dialect> (ask @router "verb" …))select-agent <dialect>, least-loaded(meta (teach @<agent-id> …))Routing modes after DIDs land:
(lang <dialect> (ask @router "verb" …))(lang <dialect> (ask @did:key:… "verb" …))(ask @did:key:… "raw" …)What direct DID routing enables that capability dispatch cannot:
(ask @router …)and the router picks; with DIDs, A can address a specific known peer(ask @did:key:Y "…"). Still routes through the hub, but the destination is precise.@did:web:router-a.example/agent/planneris unambiguous across hubs. Today self-chosen agent-ids collide between deployments.:thread "rcp-…"chain plus DIDs on each frame gives a cryptographically-attributable transcript. Material for compliance and dispute resolution.did:web:legacy.example.com). The substrate can't bridge directly, but the addressing is unified — the producer doesn't have to know whether@did:web:planneris a CBCL agent or an HTTPS adapter.Required substrate changes for routing
cbcl-agent-registrygrows adid → pidindex alongside the existingagent-id → pid. Newfind-by-did/1anddispatch-to-did/1parallel the existing functions.did:key:is zero-network (entire identity is in the atom).did:web:is HTTPS + DNS. Cache with TTL; respectupdatedtimestamps for rotation.Open routing question
Should direct DID routing also require dialect-advertisement consistency, or can a producer address a DID that hasn't advertised the dialect?
(lang Y (ask @did:key:X …))and X doesn't advertise Y, returndialect-not-advertised. Preserves the dialect-as-capability commitment ("advertising is committing"). Producers must consult the registry before direct-addressing.errorif it doesn't speak Y. More flexible, but undermines the speaker-contract guarantee.Lean: reject by default with an explicit
:bypass-capability-checkkeyword on the ask for the forward case. Captures the trust commitment in the wire form rather than at the router config.Open design questions
These need a SPEC entry before implementation:
@did:key:z6Mk…) or namespaced binding (@plannerresolves to a DID via a registry)? Bare DIDs are honest but ugly; binding via registry is ergonomic but reintroduces the squatting question (who controls the binding registry, and how).did:key:is the lowest-friction starter — entire identity is in the atom, no resolver needed.did:web:is the next step for production-like deploys.:signatureclause becomes "signed by a key in this DID's verificationMethod set at sign-time." Verification needs a DID resolver in the cbcl-rs pipeline.cbcl-base(well-known router/dev atoms); user-defined dialects must use DID atoms.Acceptance (for the design phase)
dispatch-to-did, capability-check policy).did:key:atoms; verify R4 signature against the key embedded in the DID; route a direct-addressed ask through the registry'sdid → pidindex.Out of scope for this issue
did:key:/did:web:.See discussion in hark conversation on the dialect-distribution threat model.