How the consent flow works
Learn what happens when a user connects an MCP client to Permit MCP Gateway: how the Consent Service signs the user in, lets the user choose an MCP server and a trust level, writes the agent's permissions to Permit, and starts a session. This page is for gateway admins and implementers who roll out the gateway, support users through consent, or debug a connection.
The Consent Service is the user-facing part of Permit MCP Gateway. It is the OAuth 2.1 authorization server for each gateway host, served at the host's subdomain, for example acme-brave-coral-37.agent.security. For the step-by-step setup that ends with a user's first consent, see Complete the consent flow.
The consent flow step by step
The consent flow runs the first time a user connects an MCP client, such as Cursor, Claude Desktop, VS Code, or Claude Code, to the gateway. The flow runs again when the session ends. See Session lifecycle.
1. The MCP client starts OAuth
The MCP client connects to the gateway and receives 401 Unauthorized. The client reads the gateway's /.well-known/oauth-authorization-server metadata, which points to the Consent Service's authorization endpoints. The client then opens a browser window for the user.
2. The user signs in
The user signs in with a method the admin turned on for the host: email and password, email one-time passcode (OTP), passkeys, Google, GitHub, or Microsoft OAuth, or SAML or OpenID Connect (OIDC) single sign-on (SSO). For each method and its setup, see the Authentication methods reference.

3. The user selects an MCP server
The consent screen lists the MCP servers the admin granted the user access to. The user selects one server. When the admin turns on Dynamic MCPs for the host, the user can also enter a custom MCP server URL. See Dynamic MCPs.

If the admin hasn't granted the user access to any MCP server, the consent screen shows an empty state and the user can't continue. The admin grants access first, and the user then reconnects.

After the user selects a server, the Consent Service connects to the server to check that it is reachable and to list its tools.

4. The user signs in to the upstream MCP server
If the selected MCP server requires OAuth, such as GitHub or Linear, the Consent Service runs the upstream OAuth flow:
- The Consent Service connects to the upstream MCP server and receives
401, which means the server requires OAuth. - The Consent Service discovers the upstream server's OAuth authorization server.
- The Consent Service registers as an OAuth client through Dynamic Client Registration (DCR), or uses pre-configured client credentials.
- The browser redirects the user to the upstream provider to authorize access.
- On the callback, the Consent Service exchanges the authorization code for upstream tokens.
- The gateway stores the upstream tokens in the user's session and uses them for the user's tool calls to that server.

If the MCP server doesn't require OAuth, the flow skips this step.
5. The user selects a trust level
The consent screen lists the server's tools and a trust level slider. Each tool shows an Allowed or Denied badge for the selected trust level, so the user sees what the agent can call before accepting.
| Trust level | Tools the agent can call |
|---|---|
| Low | Read-only tools, for example get_issues or list_repos |
| Medium | Low tools and write tools, for example create_issue or send_message |
| High | Low, medium, and destructive tools, for example delete_repo or remove_member |
The slider shows all three levels. Levels above the max trust level the admin set for the user on this server are disabled, and the user can't select them.
For a server the user added through Dynamic MCPs, the user can also change the trust level of individual tools, up to the max trust level.

6. The user accepts
The user clicks Accept to grant consent for the selected MCP server and trust level to this agent (MCP client). Deny ends the flow without granting access.
7. The Consent Service saves permissions and returns to the client

After the user accepts:
- Permit sync: the Consent Service creates the agent user
agent|{client_id}in Permit and assigns the agent a trust level role, such aslinear-medium, on the user's profile. The request fails if the trust level is above the user's max trust level for the server. - Session creation: the Consent Service sends the session data (upstream URL, upstream tokens, trust level) to the gateway, which stores the session in Redis. The Consent Service creates the session only after the Permit sync succeeds.
- Authorization code: the Consent Service issues an OAuth authorization code.
- Token exchange: the MCP client exchanges the code for a JSON Web Token (JWT) access token.
- Redirect: the browser returns the user to the MCP client, which can now call tools through the gateway.
Result: the agent appears on the Agents page of the gateway dashboard, and its tool calls appear on the agent's Audit Logs tab. See Audit logs.
What the Consent Service does behind the screens
This sequence shows the calls between the browser, the Consent Service, the upstream MCP server, Permit, and the gateway during one consent flow:
Tool discovery
When the user selects an MCP server, the Consent Service calls list_tools on the upstream server. The consent screen assigns each tool a trust level by the keywords in the tool name, the same classification the admin sees at MCP server import. The Allowed and Denied badges update as the user moves the trust level slider.
Permit objects the consent flow uses
| Permit object | Created by | Purpose |
|---|---|---|
Agent user agent|{client_id} | Consent Service, at consent | Represents the MCP client. |
Agent role on the profile, for example linear-medium | Consent Service, at consent | The trust level the user granted the agent on this server. |
User profile user_profile:{user_id} | Gateway admin dashboard, when the admin grants access | Represents the human. |
Profile-to-server relation, for example medium | Gateway admin dashboard, when the admin grants access | The user's max trust level on the server. The Consent Service checks the relation exists before it accepts consent. |
The agent's effective trust level on a tool call is the lower of the agent's role and the profile-to-server relation. The admin's max trust level caps what any agent can call. For the full model, see How Permit MCP Gateway works with Permit.io.
Session lifecycle
After the consent flow, the gateway keeps a session so the MCP client can reconnect without running consent again. The gateway stores the session in Redis, keyed by the agent's client ID and the user's subject.
Session types
| Session type | Storage | Purpose |
|---|---|---|
| Transport session | Gateway memory | Tracks the active MCP-over-HTTP connection. The gateway recreates the transport session on reconnect from the stored application session. |
| Application session | Redis | Stores the upstream MCP server URL, upstream OAuth tokens, consented trust level, and server key. Survives MCP client restarts. |
Session expiry
| Event | When | What happens |
|---|---|---|
| Inactivity | 90 days after the last tool call | Redis removes the application session. Each tool call resets the 90-day timer. The next connection runs the consent flow again. |
| Admin revocation | Immediately | An admin revokes an agent or a human's access. The agent's next tool call to that server is denied. |
Session expiry removes the application session in Redis. The agent's role and the admin's access grants in Permit stay in place until an admin revokes them.
Re-consent
When a session expires or access is revoked, the user runs the consent flow again on the next connection.
To change the trust level of an agent, the user disconnects the MCP server in the MCP client, reconnects, and selects a different trust level in the new consent flow. An admin can also change an agent's trust level on the Agents page. See Manage humans and agents.
Upstream token refresh
If the upstream MCP server issued a refresh token, the gateway refreshes the upstream access token when it is within 5 minutes of expiry. The user doesn't sign in to the upstream provider again.
Pre-select an MCP server in the gateway URL
Give users a gateway URL that pre-selects an MCP server in the consent flow. Add the upstream_mcp query parameter with the upstream server's URL:
https://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp
When a user connects with this URL:
- The consent flow opens, and the user signs in.
- The server selection step has the MCP server pre-selected.
- The user continues to trust level selection.
Use a pre-selecting URL in team onboarding docs or messages when a team uses one MCP server. The MCP server detail page in the gateway dashboard shows the upstream URL to use as the upstream_mcp value. For distributing these URLs, see Pre-selected MCP server URLs.
The upstream_mcp parameter only pre-selects the server. The user still needs an admin access grant for that server. Without a grant, the consent flow ignores the parameter and lists only the servers the user can access.
Path-based server selection
A path-based URL routes to one imported MCP server by its server key:
https://acme-brave-coral-37.agent.security/mcp/linear
In this URL, linear is the server key assigned at import. The consent flow still signs the user in and asks for a trust level, and it skips the server selection step. Use path-based URLs when each URL serves one MCP server.
Next steps
- Authentication methods reference: configure how users sign in.
- Manage humans and agents: grant access, set max trust levels, and revoke agents.
- How Permit MCP Gateway works with Permit.io: the policy model behind trust levels.
- Audit logs: review the tool calls an agent makes after consent.