Governed Connections: Agents and Automations That Act as You
Route every caller — a resident agent, an external app, an unattended automation — through one registry, each a small revocable grant bound to specific accounts and permissions.
An agent, an external app, and an unattended automation each act as one of your users against a KDCube app's own services — every caller a separate grant, bound to specific connected accounts and to specific permissions on each, editable or revocable from one place, live.
More than a browser reaches a user's data. An agent inside the app wants their memory mid-turn; a tool they connected wants their mail; a nightly job holds a token for it. Route all of them through one registry and each stays a small, named, revocable grant — never the user's whole session.
Current code and descriptors still say bundle in names such
as bundle_id and bundles.yaml. In this recipe,
app = bundle: one deployable KDCube runtime unit.
The two directions in one minute
INBOUND # who is calling KDCube as the user resident agent → public MCP door # kind: mcp, delegated: true resident agent → named-services network # kind: named_service, in-process external app → public MCP door # OAuth automation → minted token # operator picks the grants Gate 1 selected operation + effective caller authority OUTBOUND # KDCube using the user's connected account Gate 2 exact selected account + provider claim enforced for this caller's account_scope → the provider call runs on the user's account
The caller never receives the provider token. Connection Hub keeps that credential and uses it only after effective caller authority satisfies Gate 1 and the provider broker enforces the selected account and claim at Gate 2.
- A KDCube app that serves a user's data — memory, mail or Slack via named services, knowledge, conversations
- Connection Hub reachable in that deployment
- At least one connected provider account under Delegated to KDCube
- Two accounts, both approving read and write, to exercise per-account claims
- Permission to edit the consuming agent's descriptor
- An authenticated user who may delegate the selected grants
OP 10OF 70 Connect a resident agent over the public MCP door INBOUND · A CALLER
Declare a delegated MCP connection to the app's own named-services door.
delegated: true makes the connection carry the agent's consented
bearer, never the raw session.
tools: - name: named_services kind: mcp delegated: true url: https://<host>/api/integrations/bundles/<t>/<p>/kdcube-services@1-0/public/mcp/named_services resource: "*/api/integrations/bundles/*/*/kdcube-services@1-0/public/mcp/named_services*" transport: streamable_http scopes: [named_services:use]
The first card binds only the MCP door. Ask the agent to use the capability and
the named-service bridge derives mail:read or another operation requirement
from the live catalog. Provider-backed permission is then selected per account
on this caller's account_scope; it is not a static connection scope. Each
card names the exact missing decision for this agent's deterministic
kdcube-agent:<app>:<agent> identity.
The grant lands under Connection Hub → Delegated by KDCube with an agent badge; the agent's next turn uses the capability without asking again.
OP 20OF 70 Or reach the named-services network in-process INBOUND · A CALLER
The same resident agent can reach named services in-process instead of over the HTTP door. Governance is identical: the same per-agent grant is checked before each call, the same one-click chat consent applies. The choice is transport only.
Granted the same claims, the network-path agent and the MCP-door agent refuse and resolve identically — same consent card, same behavior.
OP 30OF 70 Connect an external app over the public MCP door INBOUND · A CALLER
An app outside KDCube — any OAuth MCP client the user connects — reaches the same public door. It consents through an OAuth screen, and its grant becomes an editable card in Connection Hub.
The external app appears under Delegated by KDCube with an Edit control; narrowing a claim there stops that capability on the bearer the app already holds — no reconnect.
OP 40OF 70 Provision an automation by hand INBOUND · A CALLER
For a script or a scheduled job there is no card to click. An operator mints a delegated-access token and picks its resource grants directly — least privilege by construction. The token represents the platform user the automation runs as, and is listed and revoked like every other delegated client.
The automation calls the delegated resource with its minted token and nothing wider; revoking the token stops it on the next call.
OP 50OF 70 Pass the two consents INBOUND + OUTBOUND
Whichever way the caller connected, a call reaching a connected account
crosses two consents in order. Gate 1 checks the selected catalog operation
against the caller's effective live authority from OP 10–40; for a hosted
named-service call, account_scope can satisfy the matching provider
requirement without a duplicate outer grant. Gate 2 makes the provider broker
enforce that exact account and claim. A permitted caller still cannot touch a
provider the user has not connected; a connected account never admits a caller
on its own.
With the account connected but the caller ungranted, the call raises the Gate-1 demand; with the caller granted but no account connected, it raises the Gate-2 connect demand — never a silent pass.
OP 60OF 70 Bind the accounts and their permissions OUTBOUND · TO AN ACCOUNT
On the caller's card — or its first consent card — pick, per connected account, which permissions this caller may use there. Connect two accounts, both write-capable, and set:
Google you@example.com [x] read [x] write ops@example.com [x] read [ ] write # read-only for THIS caller
The binding decides, not the account's capability: an account's own claims are shared across everyone who uses it, so read-only for one caller has to live on the grant.
The read-only-bound caller reads ops@example.com fine, but a write through it is refused — naming the account it may write from — even though ops@example.com is itself write-capable.
With several eligible bound accounts and no account_id, the
call returns account_required with labeled choices. Resending
with one candidate passes that same selector through preflight and provider
execution. Naming an account outside this caller's binding returns
agent_account_binding_required; the recovery URL identifies the
existing caller card, KDCube resource, account, and claim. It is presented
to the user, never opened or replayed automatically.
OP 70OF 70 Edit or revoke, live INBOUND + OUTBOUND
The grant card is the authority; the token is only a handle to it. So change takes effect without a reconnect.
- Edit a card — add or drop a claim, change which account and which permissions — and it applies on the caller's next call.
- Revoke a card and the caller drops immediately: a resident agent's tool falls back to its consent-gated stub, an external app's calls stop, an automation's token stops resolving.
For a manual automation token, the bearer keeps working while
delegated_access_update replaces its resource grants, account
bindings, or named_service_operations. The current existing-card
UI preserves the nested namespace selection but does not yet show its picker;
that inner edit is currently available through the update operation rather
than the form.
Tick write on the read-only account, then ask the caller to write from it — it succeeds on the next call; revoke the card and the same call is refused.
- A resident agent reaches KDCube services over the public MCP door under a per-agent grant.
- A resident agent reaches the same services over the named-services network, governed identically.
- An external app holds its own editable grant.
- An automation runs on a hand-provisioned token scoped to its grants.
- Every account-reaching call passes both consents in order.
- A caller is bound per account AND per permission — read+write from one account, read-only from another — enforced by the grant, not the account.
- Two eligible accounts return
account_required; an explicit unbound account returnsagent_account_binding_requiredfor the existing card. - An edit applies on the next call; a revoke drops the caller immediately.