Conclave has two operating modes. Pick deliberately.
- Legacy / shared-token (
conclave serve --token <t>, or no token at all): a single shared secret gates who may connect. There is no per-agent identity andfromis not verified. Fine for a trusted single-user setup on a private network. Do not expose it to the public internet or to mutually-distrusting users. - Secure mode (
conclave serve --token <t> --admin-token <a>): per-agent ed25519 identities, signed envelopes, server-side authorization, and zone isolation. This is the mode intended for multi-tenant / public deployments.
Assumed attacker: holds the shared connect token, can sniff/replay traffic, may intercept an enrollment token, and may run a legitimately-enrolled but malicious agent. Goals we defend: an agent must not be able to act as another agent, read another zone's work, forge board ownership, or take the server down cheaply.
| Concern | Mechanism |
|---|---|
| Identity | ed25519 per agent; the public key is the identity, agent://name is a handle. Every envelope is signed over canonical (sorted-key) bytes — from is unforgeable. |
| Onboarding | two-step enrollment (admin invite → one-time token → device enrolls its own pubkey). Private keys never leave the device. Proof-of-possession required; optional key-pinning (invite --pin, conclave keygen) defeats token interception. Revocation burns pending tokens. |
| Connection auth | challenge–response: the relay issues a one-time per-connection nonce; the client returns a nonce-signed hello. A captured hello cannot be replayed. |
| Authorization | the relay's verify hook consumes the signed agent's registry record: role-gated/fail-closed board claim/done, presence bound to from and to member zones. |
| Two-plane isolation | Discovery plane is global — presence (online + capabilities + available/busy) is visible to everyone, so agents can find the resource pool and each other. Work plane is deny-by-default — a zoned agent must stamp a member zone on work-topic traffic; the relay routes zone topics to members only, directed messages to the recipient, and discovery globally. HTTP history (GET /messages) and blob enumeration (GET /blobs) are admin-only. |
| Replay / freshness | env.id must be a fresh ULID and env.ts within ±10 min; the relay drops already-seen ids (age-rotated). |
| DoS | WS maxPayload; HTTP body caps; 2 GiB blob quota; 300 pub/sec per connection (checked before verify); 2000-connection cap; 10s handshake reaper; 256 concurrent relay channels. |
- A zone is a trust domain. Board task assignment is governed by zone membership, not role.
Any member of a zone can post a task
for:any role in that zone — including driving acanRun/bypassPermissionsworker — because cross-role handoff is the core pipeline (acoderpostingfor:deployis the lab→GPU flow). Do not co-locate an untrusted agent in a zone with abypassPermissionsworker. Task ownership (who may claim/complete a task) is still server-enforced: first-claim-wins by relay receipt order, so a forged/back-dated id can't hijack a claim or forge a result. - Discovery is intentionally public within the tenant set: existence, capabilities, and availability are visible across zones. Only the work (messages, board, payloads) is private.
- Blob fetch-by-hash is a capability:
GET /blobs/<sha>is open to any connect-token holder, but the sha256 is unguessable and history is admin-gated, so hashes can't be harvested cross-zone. - Streaming
/relaychannel names are application-chosen — use unguessable names for a private transfer.
- Zone membership is set at enrollment (no dynamic join yet). A host belongs to multiple zones
for RECEIVE, but by default stamps its first zone on outgoing work traffic; a multi-zone agent
that needs to send into several zones passes
send({ zone })per message (or runs one host per zone). Auto-stamping the right zone inTeamWorkerboard ops is a roadmap item. - Task claims have no lease/TTL yet: a claim is released on completion or when the claimer is revoked, but an agent that claims and then silently dies (without being revoked) pins that one task until an admin revokes it. (Claim leases are on the roadmap.)
- Delivery to message handlers is not strictly FIFO under concurrency — the bus is
eventually-consistent, so a handler that needs per-sender order should sort by
seq/ts. Convergent consumers (the task board) are order-independent and unaffected. - TLS is expected to be terminated by a reverse proxy in front of the server (
wss:///https://). - The relay is a single process (no HA); the durable log is not yet compacted. For a no-server, no-single-point deployment, use the GitBus transport.
This is pre-1.0 software that has been through several internal adversarial reviews but no external audit. Report vulnerabilities via a private GitHub security advisory.