No. 19 · JUN 2026 · 6 Min Read
A Credential Broker for User Code
Abstract
Apps and Connectors over a credential broker that mints short-lived, per-user tokens, so user code runs as the accessing user and never as a service account.
The substrate is built. Your Users Already Run AI-Generated Code made the case for letting them. Where User Code Runs put it in a microVM. A Sandbox for User Code gave it an interface and a tenant boundary. When User Code Acts as the User carried a real identity into the sandbox. What none of them describes is the thing your users actually touch. That shape has two nouns, App and Connector, and one service underneath doing the quiet, dangerous work: a credential broker.
One rule is worth adopting early. Everything you expose to an agent as an MCP server should also be reachable as a plain API. The agent building an App speaks MCP while it works. The App’s own code, running later for some user, speaks HTTP. Same capabilities, two front doors. The transport is not what keeps either one safe. The credential is: who gets one, scoped to what, for how long. The broker is the thing that answers that, and it is the only thing that needs to.
The Two Nouns
An App is what a user builds: a frontend and a backend, authored with an agent, the backend running in the sandbox from the earlier pieces. It is untrusted, in the exact sense from the first piece, first-party in purpose and third-party in trust. And it is multi-tenant’s smaller cousin: one App, used by many people inside a single customer, each signing in through your SSO. The definition persists. Each request executes briefly, as whoever made it.
A Connector is a declarative grant attached to an App. “This App may request credentials for the BI API.” It is not a stored key. It is a capability the platform agrees to honor, and the place consent and scope live. Adding a connector adds a line to the App’s manifest. It never pastes a secret into the App.
This is the Lego framing from the first piece made literal. The connector is the stud on the brick. The App is what the user snaps together. The broker is what decides, at the moment a brick is used, whether it clicks.
The Broker
Given a verified user, an App, and a connector, the broker returns a short-lived credential scoped to that API and its audience, with a lifetime in minutes. It logs every mint. In OAuth terms it is your own token-exchange authorization server with a vault attached, which is the OAuth layer turned to face your own APIs.
Two backends sit behind one call:
- Internal connectors, your APIs and their MCP twins: you own the authorization server, so you mint a fresh token by exchange. Nothing is stored. The token carries subject Alice, actor SalesDash, audience BI, five minutes.
- External connectors, a SaaS the user linked: you hold the user’s OAuth token in a vault keyed to that user and connector, and refresh it. This is the half AgentCore Identity productizes, the one case where buying beats building.
The App asks for “credentials for the BI connector” and never learns which kind it hit. That sameness is the connector’s entire value.
One Request, End to End
A trace, step by step.
The broker’s check in step 03 is three questions, all of which must pass: SalesDash holds the BI connector, Alice consented to SalesDash acting as her, and Alice actually has BI access. Step 04 fails the first of those. Step 06 is where the design pays off, because BI sees Alice and applies Alice’s own row-level permissions, not the App’s and not a service account’s.
The payoffs are concrete. There is never a shared BI key in the sandbox, so the App is a lens and not a privilege; its author cannot reach one row past their own access. Offboarding and least privilege come for free, because Alice’s reach through every App she touches is just her reach, governed in one place, and killing her SSO stops every App for her at once. And the audit trail is complete: every mint and every downstream call carries the user, the App, the connector, the scope, and the time. That last one is the “in your logs” promise from the first piece made real, the record a regulated shop cannot get from code running on a laptop.
The Rule That Holds It Up
The accessing user’s identity must be injected by the runtime, never asserted by the App. The App says “credentials for BI” and gets back a token for whoever is currently signed in. It must have no way to say “as Bob.” The moment untrusted App code can choose its own subject, the broker stops being a credential service and becomes a privilege-escalation engine.
The fix is the one the whole series keeps returning to. The runtime authenticates to the broker as its own workload identity and relays a cryptographically verified assertion of who the user is. The broker trusts the runtime, not the code running inside it. The App never holds the user’s identity in a form it can edit, so editing it is not a mistake to guard against. It is unrepresentable.
The Sharp Edges
A few things bite if they go unhandled.
A confused deputy. The fix binds connectors to App identity and verifies it at mint time. The App’s own claim that it holds a connector is never trusted.
A leaked token. It lives briefly inside untrusted code, so it is eventually stolen. The lifetime stays short, each token binds to a single audience, and DPoP or mTLS sender-constrains it, so a copy lifted out of the sandbox cannot be replayed against a different API.
Caching across users. The App backend is long-lived and serves many people; the credential is neither. The fetch happens per request, scoped to the current user, and one user’s token never carries to the next. The strongest version binds the fetch interface to the request’s identity, so the App cannot fetch as the wrong person even when it tries.
Consent confused with login. SSO logs Alice into the App. Letting that App act as her against BI is a separate grant she makes once and can revoke. The two stay apart, the way the sandbox piece keeps Cognito, which says who, away from policy, which says what.
What You Built
None of this is exotic. Cognito for sign-in, STS and token exchange for the mint, KMS for the secrets, a vault for the external tokens, a manifest for the connectors. The parts are settled and boring. What is new is pointing them at code your own users wrote that afternoon, and deciding, before a line of it runs, that it will run as them and only as them.
Your users get the full reach of building against your data. Every action their code takes downstream carries the name of a real person who was allowed to take it. That is what keeping it on the ranch is for.
One thread runs under every piece of this. The sandbox, the policy, the storage, the identity, the secrets, each is composed from a primitive the cloud already sells, which is what makes a per-customer workshop cheap enough to actually offer. That thread is Files Without S3, Cron Without EventBridge.