The mental model behind tools like Composio and Stytch: how one service brokers OAuth so your app — or your AI agent — can act across Gmail, Slack, GitHub and 500 others, without ever touching a raw credential. Roles, the handshake, connected accounts, token refresh, and the full architecture.
Say your app (or agent) needs to read a user's Gmail, post to their Slack, and open GitHub PRs for them. Each one is a separate OAuth integration: register an app with the provider, build the redirect/consent flow, securely store the returned tokens, and run a job to refresh them before they expire — per provider, per user. Add a fourth service and you do it all again.
A middle service — an auth broker like Composio (for consuming others' APIs) or Stytch (for issuing your own) — collapses that. You integrate with the broker once; it owns each provider's OAuth dance, encrypts and stores the tokens, and refreshes them silently. Your code goes from "maintain N integrations" to "call one API."
Everything a broker does is just OAuth 2.0 played well. OAuth defines four roles. The whole point is delegated access: the user lets a client act on their behalf without handing over their password — the provider issues a scoped token instead.
The mental unlock: the broker plays the "client" role. It holds the OAuth client_id/client_secret registered with each provider and drives the flow so your app or agent doesn't have to.
gmail.send, not mail.google.com/ full access. The provider shows the user exactly those scopes on the consent screen, and the token can never exceed them.This is the choreography the broker performs the first time a user connects a service. The clever bit is the authorization code: the browser only ever carries a short-lived, single-use code — the real tokens are fetched server-to-server using the client secret, so they never ride in a URL or sit in the browser.
// Step 5 — the broker's SERVER exchanges the code (client secret never leaves the backend) POST https://oauth2.googleapis.com/token { "grant_type": "authorization_code", "code": "4/0Ax…single-use…", "client_id": "<broker's id>", "client_secret": "<broker's secret>" } // → { "access_token": "ya29.…", "refresh_token": "1//0e…", "expires_in": 3599 }
state parameter the broker sends in step 2 comes back in step 4. It ties the redirect to the request that started it — without it, an attacker could trick a user into completing a flow the attacker began (CSRF). Brokers handle this for you.After the handshake, the broker stores the result as a connected account: an encrypted record keyed by your user id + the service, holding the access token, the refresh token, the granted scopes, and an expiry. (Composio calls this exactly that — a "connected account"; one user can even have several on the same toolkit.)
Access tokens are deliberately short-lived (~1 hour). The magic that makes a broker feel seamless: when your agent makes a call and the token is stale, the broker silently swaps in a fresh one using the refresh token, then completes the call. The agent never handles, sees, or refreshes a token.
"Middle service" covers two mirror-image jobs. Both broker OAuth — but the tokens flow in opposite directions, and that's the cleanest way to tell Composio and Stytch apart.
Your agent wants to act on other services. The broker holds the downstream tokens (from Gmail, Slack, GitHub…) and exposes them as clean, typed tools your LLM can call. This is the Composio model: managed auth for 500+ apps, just-in-time tool calls, native function calling.
GMAIL_SEND_EMAIL and the broker does the rest.You flip around and let others act on you. With Stytch Connected Apps, your app becomes a fully compliant OAuth 2.0 / OIDC provider — so other apps (and AI agents over MCP) get a "Log in with Your App" button and you issue them scoped tokens. Stytch runs the authorization-code handling, JWT issuance/verification via JWKS, refresh, and revocation.
Put the pieces together. The agent issues a plain intent ("post this to Slack"). The broker splits into two responsibilities you saw earlier: an auth layer that resolves which connected account to use and refreshes its token if stale (Sections 3–4), and the outbound call to the real service API. The agent holds no secret — only a broker handle + the target user id.
One integration replaces N. OAuth's four roles → the code flow → connected accounts + silent refresh → consume (Composio) or provide (Stytch) → an agent that acts everywhere and holds nothing.
No spam — just new posts and learning pages when they ship.
Drop your email and I will send new posts and learning pages your way.
Thanks — you are subscribed.
You can close this dialog now.
We will only email you when there is something new. Unsubscribe any time.