Workflow Callers & Delegation
Automation platforms connect to mcpgate as MCP clients. The default mode is service-account: the flow holds its own gateway credential and acts under its own identity. A Windmill flow can additionally act as its owner through a scoped, revocable, audited delegation grant — without ever holding that user's service tokens.
Two ways to connect
Any tool that speaks the Model Context Protocol can register as an MCP client of the gateway, complete the standard OAuth flow once, and from then on drive the gateway's tools the same way an interactive AI client does. That is the universal path; everything below builds on it.
| Mode | How the call is attributed | Available for |
|---|---|---|
| Service-account user | The flow runs as its own gateway user (the identity that completed OAuth). The audit log records that user as both subject and actor. | Any MCP-compatible client: n8n, Make, Zapier, custom MCP clients, … |
| Delegated (act-as-owner) | The flow presents a delegation grant. The audit log records two identities: the user the flow is acting for (subject) and the workflow caller (actor). The user's service tokens stay in the gateway; the flow never sees them. | Windmill flows today. The mechanism is RFC-8693 token exchange behind a pluggable caller-verifier; other platforms can land as the verifier surface for them is built. |
The two modes are not mutually exclusive on the same platform — a Windmill instance can run some flows as the service-account user and others as their owners, depending on whether the flow declares a gateway-services: block (see the Windmill jobs guide).
The shape of a delegation grant
The grant is RFC-8693 (OAuth Token Exchange). Subject = the user the flow is acting for. Actor = the workflow caller. Both end up in the audit log, so a row reads "Windmill flow X created a Jira issue on behalf of user@example.com", not "Windmill did a thing".
A grant narrows down four axes from what the user can do:
- Services — only the services the workflow declares it needs (capped by what the owner can reach). A flow that only touches Jira cannot quietly start reading Drive.
- Risk classes — read, write, high-risk. High-risk is never granted automatically — an admin grants it explicitly per delegation. Deletes, archives, dashboard PUTs all require the explicit grant on top of the user's own permission.
- Lifetime — bounded and sliding. A grant's expiry moves forward on each validated use, so an actively-used flow never lapses; an idle grant self-evicts within its window. Same lifetime model as a user's own refreshable connection — bounded by inactivity and revocation, not by a hard cap.
- Caller binding — the grant is tied to a specific workflow caller. A grant signed for one flow cannot be presented by another.
The gateway evaluates the grant against the action's risk classification (see the action classification system) on every call. A flow that tries to delete a Jira issue on a read-only grant is refused at the gateway, with the refusal recorded in the audit log.
Why this is structurally different from a token vault
Three consequences of the delegation model that a "give the workflow OAuth tokens" approach cannot match:
- The workflow never sees a service token. The Jira API key, the Google OAuth refresh token, the Slack bot token — none of these leave the gateway. The flow holds only its own MCP client credential, and a delegation grant naming the user it acts for. A compromise of the workflow runtime does not exfiltrate per-service credentials.
- Audit reads cleanly. Every action records subject + actor. "User created issue" alone is misleading when an automation did it; "user_X via Windmill flow Y created issue" is the truth, and that is what lands in the audit log.
- Revoke without re-credentialling. Off-board a person: revoke their grants. Flows acting as them stop. The workflow's own MCP client credential is unchanged; it can keep acting as other users it has grants for, or as a service account.
Authenticating the workflow itself
Two identity layers, both have to clear before a delegated call goes through:
- The MCP client OAuth flow — the workflow registers as an MCP client of the gateway and completes the standard authorization-code flow. This proves which platform-and-instance is calling. Universal across all MCP clients.
- Caller verification — the gateway independently verifies the caller's claim about who it is. For Windmill, this uses the flow's own job token and path (the gateway calls back to the configured Windmill workspace to verify the claim). The grant is bound to a verified caller identity; a grant signed for one flow cannot be presented by another.
Setup
Sidebar → General → Clients for the unified panel that manages every MCP client connecting to the gateway, the redirect-host allowlist that lets a self-hosted client complete OAuth, service accounts, and delegated access.
1. Enable delegated access
Default off. Admin toggle on the Delegated Access section of the Clients page. With the flag off, the delegated path is entirely absent — workflow callers can still connect as service-account users, but cannot present grants.
2. Connect the workflow platform's Windmill instance (for delegated mode)
On the same panel, point the gateway at the Windmill instance the flows will run from: its URL and workspace. The gateway uses these to verify a flow's caller claim on each delegated call. Configuration is admin-UI only, no environment variables or restart needed.
3. Authors declare what each flow needs
A Windmill flow opts into delegation by declaring a gateway-services: block in its job definition (the services and risk classes it needs). The gateway mints a least-privilege grant per call from that declaration, capped by the owner's own access. See the Windmill jobs guide for the author-side details.
4. Review and revoke
The Delegated Access panel lists every live delegation grant — not only an individual admin's own — with subject, the originating workflow, scope, and expiry, each revocable in one click. A single oversight surface for all standing automated access.
What this is not
- Not a service-account workaround. A pure service account (workflow connects with its own gateway user) is the simpler path when nobody specific is "the user". Delegation is for the case where the workflow should act as a specific person, with that person's permissions and that person's audit trail.
- Not a token vault for workflows. The workflow does not store the user's Jira / Slack / Google credentials. It stores its own gateway credential plus a delegation grant. The gateway is the vault.
- Not silent. Every delegated action is double-attributed (subject + actor) in the audit log. The user can see what was done in their name; the operator can see which workflow did it.
- Not high-risk-permissive by default. Even a grant for "all services" denies high-risk actions unless the admin explicitly grants them per delegation.
Maturity
The MCP-client connect path is production-ready — any MCP-compatible client connects as a service-account user through the standard OAuth flow. The delegation-grant mechanism (RFC-8693 token exchange, scope narrowing, sliding lifetime, audit double-attribution, high-risk denied by default) ships as a beta capability behind the admin flag. The caller-verifier is pluggable: Windmill ships today, other platforms land as their verifier surface is built. A workflow with no grant still operates as its own service-account user — the platform connect itself does not depend on delegation being enabled.
Related
- Windmill jobs guide — the author-side view: how to declare
gateway-services:, how to write a delegated flow, the three configuration paths. - Access Model — roles, permissions, audit; delegation is a fourth axis on top of the role model.
- Audit Log — the forensic substrate where every delegated action's subject + actor is recorded.
- Compliance — the umbrella surface; delegation refusals and grant lifecycle events land on the same compliance layer.
- Destructive-action governance — the high-risk classification the delegation gate respects.