Connections and consent
An agent or workflow runs on a vault’s data only after the vault owner connects it. Connecting does two things: the owner’s wallet signs an agreement, and the vault creates a connection that records what was granted. Consent is what the owner gives; the agreement is the signed record that proves it.
What the owner signs
The agreement is held in the agreement registry, not in the vault. It binds:
| Bound | Form |
|---|---|
| The owner’s wallet | the public key that signs |
| Your Agent Service | agentServicePubkey, the prefix of the agent id |
| The vault | the vault id |
| The scopes | the set of scopes the connection may use |
One agreement covers the whole scope set for one (Agent Service, owner) pair. Because the agreement is the authority, you cannot widen your own access; you can only ask the owner to sign again.
Where connecting happens
- In ROC. Running a workflow from the Workflow Builder connects its agents to the vault first. The first run asks for a passkey to sign the agreement.
- From your own app.
vault.agents.connect({ agentId, scope })in the Vault SDK builds the agreement, signs it with the configured signer, submits it, and creates the connection in one call.
The full walkthrough is Connect to a vault.
What the vault checks
A valid signature is necessary but not sufficient. At connect time the vault:
- Verifies the agreement is present and not revoked or expired.
- Fetches your agent’s manifest from your Agent Service’s registry by agent id. The manifest, not any listing, is the authority on what the agent declares.
- Checks that the agent id’s prefix matches the manifest’s Agent Service.
- Checks every requested scope is one the manifest asks for (
defaultwhen it declares none). - Validates the owner’s
settingsvalues against the manifest’s settings schema. - Provisions the cubbies the manifest declares, running their migrations.
Only then does the connection become active.
What a connection records
| Field | Meaning |
|---|---|
agentId |
<agentServicePubkey>:<alias> |
scope / scopes |
The scopes it may use. |
status |
provisioning → active → revoking → revoked. |
settings |
The owner’s values for the manifest’s settings schema. |
bundle |
The exact bundle the owner consented to run (see below). |
ceiling |
Optional spend ceiling: gpuUnits (platform-metered) and a2aTokens (self-reported by an LLM agent). The platform refuses new work once a ceiling is reached. |
The bundle is pinned
A connection runs the bundle the owner consented to, not whatever you published
last. Deploying a new version does not change what a connected vault runs.
To move a vault to new code, reconnect with the new bundle’s content id
(bundleCid):
| Code | When |
|---|---|
BUNDLE_CHANGED |
The bundleCid sent no longer matches the agent’s current manifest: something was published between review and connect. |
RECONSENT_REQUIRED |
A reconnect to a different bundle was sent without bundleCid. |
Workflows and connectors
A workflow’s access to the vault’s connectors is part of its consent. When you deploy a workflow, ROC grants it exactly the connector actions and events its graph uses, per connection, and removes access the graph no longer uses.
How a request proves authority
Every call into a vault traces back to a signature:
| Proof | Used by | How |
|---|---|---|
| Signed request | Apps acting with the owner’s or a member’s key | The body is canonicalized and signed; sent as X-Public-Key / X-Signature. |
| Delegation token | Clients acting on someone’s behalf without the key | Authorization: Bearer <token>, scoped and revocable. |
| Execution token | A running agent or workflow | Minted per task, short-lived, carrying the connection’s authority for that vault, scope, and run. Your code never sees a credential; ctx uses it. |
Ending access
| Action | Effect |
|---|---|
Disconnect (connection.disconnect()) |
Deletes the connection. Cubby data is kept, so a later reconnect resumes. |
| Revoke the agreement | Removes the root of authority. The vault checks the registry for every active connection and tears down any whose agreement is revoked or expired. |
Agreement reads are cached briefly, so revocation takes effect within that cache window rather than instantly. What the agent wrote stays in the vault.
Errors
Match on the error code, not the HTTP status.
| Code | Meaning |
|---|---|
AUTH_MISSING |
No usable signature or token on the request. |
AUTH_AMBIGUOUS |
Conflicting auth schemes on one request. |
AGENT_ALREADY_CONNECTED |
A live connection already exists for this agent. |
MANIFEST_NOT_FOUND |
No manifest for this agent id in the registry. |
CUBBY_PROVISION_FAILED |
A declared cubby’s migration failed. |
BUNDLE_CHANGED, RECONSENT_REQUIRED |
See The bundle is pinned. |