This is the cross-cutting trust flow. For the identity domain — accounts, the access-control model,
what’s built, and the roadmap — see Identity.
A dispatch is often launched by a non-human (a 3am schedule entry, a Gmail webhook). We cannot trust
the launcher by virtue of it running — it must prove it was authorized, and that proof must survive
every hop to the tool that finally sends an email. The agent is untrusted and carries proof but never
enforces it.
The flow — authenticate the launcher (OIDC session, or a signed delegation grant) → the identity
service mints a short-lived signed dispatch token → the runtime attests the workload → every
boundary verifies:
- Workspace store mounts only granted workspaces,
rw only where the token says.
- Tool calls route through the MCP Gateway, which does an RFC 8693 token exchange (the agent’s
SPIFFE identity → a token scoped to that one tool’s audience) and acts with brokered creds — the agent
never holds the credential.
- Stream tags every event with
dispatch_id; audit resolves it to (subject · launcher · scope).
We adopt kagenti: SPIRE (workload identity) + Keycloak
(RFC 8693) + Envoy MCP Gateway. Dev uses a token-bound secret behind the same interface; k8s uses SPIRE.
The agent (LLM) is outside the trust boundary. Compromise it via prompt injection and it still
cannot exceed the token’s scope — the boundaries enforce, not the model.
The same posture covers user-supplied secrets and URLs. A calendar’s ICS address is a
credential: it is stored server-side, every user-facing read returns it masked, and it crosses
in the clear only on the internal, secret-gated hop the sync poller calls. And because the poller
dereferences a user-controlled URL, the fetch runs on the same IP-pinned, SSRF-guarded
transport as webhook delivery — re-resolved and validated at connect time, so a DNS-rebinding
flip can never turn calendar sync into an internal-network probe.