Conduit is the authorization server
Conduit implements the MCP specification’s authorization model directly: it is a full OAuth 2.1 authorization server, not a proxy or a pass-through to your identity provider.- An unauthenticated request to
/mcpreturns401with protected-resource metadata, which leads the client to Conduit’s authorization-server metadata at the standard.well-knownlocations. Clients discover everything; nothing is configured client-side but the URL. - The client walks the authorization-code flow with PKCE: authorization request → the person signs in to Conduit — the normal login page, single sign-on included — → an explicit consent screen naming the client → code → token. The consent screen cannot be embedded by another site, and its Approve action activates only after the screen has been visible briefly.
- Every token a client holds is issued by Conduit. Your identity
provider’s role is to authenticate the human in the middle of that flow; its
tokens are never given to MCP clients, and externally issued tokens are
not accepted at
/mcp. Equivalent controls to a JWT-validating gateway are enforced behind the endpoint instead: every request re-validates the bearer and the caller’s live workspace membership, and every auth event is audited.
How clients register
There are no API keys to create. Clients establish an identity in one of three ways:- Dynamic Client Registration (RFC 7591) — what most MCP clients do
(Claude, Cursor, VS Code, and others): the client registers itself at
/oauth/register, unauthenticated, and each registration is a distinct client identity per user. Everything such a client says about itself is unverified. Whether such clients may connect is each workspace’s decision (below). Instance admins can additionally stop accepting new registrations (Settings → Sign-in) once the clients you expect are connected, or on instances that want only URL-based client IDs; clients already registered keep working. - URL-based client IDs (Client ID Metadata Documents) — the client
identifies itself by an
httpsURL it controls, where its metadata is published. One shared identity across all users of that app, and the only registration form with a domain-control proof behind it. Conduit accepts anyhttpsclient ID; each workspace decides which of these clients may reach it (below). - The device grant — the Conduit CLI’s
conduit loginshows a short code to approve in a browser, on any device. The CLI setup UI is feature-flagged and hidden by default.
The tokens
- Opaque, not JWTs. A Conduit token carries no claims to inspect or mis-validate; it is a random 256-bit value that Conduit resolves on every request. Nothing about a caller’s access is decided client-side.
- Stored hashed. Like every bearer credential Conduit issues (session tokens, refresh tokens, authorization codes), only a one-way hash is stored, so a database dump contains nothing replayable.
- Audience-bound. A token minted for MCP (RFC 8707 resource binding) is
valid at
/mcpand nowhere else — it cannot drive the management API or the web UI, and a web session cannot be replayed as an MCP bearer. - Short-lived, with rotating refresh. Access tokens last 24 hours; clients refresh silently with single-use refresh tokens that are rotated on every use (OAuth 2.1) and expire after 90 days of disuse. Authorization codes are single-use and expire in 10 minutes; the device grant’s codes likewise, though the credential it mints for the CLI lasts 90 days.
- Revocable immediately. Revoking a client or a user’s sessions takes effect on the next request, because every request resolves the token — see below. Removing a user from a workspace ends their access on that workspace’s endpoint the same way, mid-session.
Scopes limit each client
The consent screen shows a coarse ceiling for the client. The two ordinary permissions are required; administrative permissions are optional and only appear when your current role can grant them.
Scopes are only a limit on the application. Conduit still checks your live
role and access policies on every listing
and direct call, so selecting a scope cannot grant a connector or admin action
you could not otherwise use. A
scopes entry in client configuration may
limit the optional administrative permissions requested, but the ordinary
permissions remain part of the grant.
Workspace API clients — machine credentials with no
person in the flow — use a separate, finer-grained scope set granted by a
workspace admin at registration; the permissions on this page apply only to
clients a person authorizes interactively.
Governing connected clients
A token authenticates a person and works at every workspace they belong to (the URL picks the workspace), so each workspace decides which clients may reach it — and which clients it knows. The instance holds only the one setting that cannot be per workspace: whether the authorization server accepts new self-registrations at all (below).Workspace: MCP Clients
Settings → MCP Clients (workspace admins, in both deployment shapes) is two things: who can connect, and one table of clients. Who can connect is one choice among three cards:- Any client (the default). Members connect with whatever they like; you can still block a client in the table.
- Verified clients only. Clients that prove who they are — URL-based client IDs and the Conduit CLI. A self-registered client has no verified identity and is blocked unless you allow it.
- Only allowed clients. Only the clients you allow connect. A client Conduit recognizes starts allowed when it proves who it is — Claude Code, Claude Desktop, Codex, ChatGPT and VS Code identify with a published document, and Conduit’s own CLI is its own — while a client that only registers itself (Cursor, MCP Inspector, an install that merely claims to be one of the above) is blocked until you allow it in the table’s Access column, which is also where you take one off.
[label](https://url). Left empty, a blocked member reads only the
posture’s own sentence, which the field shows as its placeholder.
Clients is the one table, one row per client the workspace has any
relationship with: the clients Conduit recognizes, the ones you added, and
anything that has connected — admitted or refused. A client appears once it
has made a request to this workspace (a member’s authorization lets a client
reach every workspace they belong to, so only a request says which), or
because Conduit knows it, or because you added it. Facets above the table
select from the same rows: All, Allowed, Blocked, Connected.
Add a client takes a name and the https URL of the client’s client ID
metadata document; only the vendor can host that URL, which is what makes an
install that identifies with it verified, and it is the whole of how Conduit
recognizes the client — a site or a path is refused. A client you add is
decided about on its own, even when its document sits under a vendor Conduit
recognizes: one connector of ChatGPT’s, added by its own document URL, is that
row’s client rather than ChatGPT’s, so it can be blocked while ChatGPT is
allowed, or the reverse. The dialog also sets up
the client’s tab on Home: whether it is shown, its icon, and its steps,
prefilled with Conduit’s generic ones for you to edit. A client members have
already tried needs no adding: it is a row, and its Access cell lets it in.
Each row shows:
- The client, with its icon, and Identity: a blue check when it proves who it is (a URL-based client ID, a metadata document only its vendor can host, which Conduit fetched and validated — or Conduit’s own CLI), a grey question mark when it only registered itself and presented signals any client could imitate. Claude, Claude Code, ChatGPT, Codex, and VS Code publish such documents; Cursor and MCP Inspector connect by registering themselves. A recognized client whose members also use installs that merely claim to be it gets a second row, unverified installs, so each row’s mark and Access hold for every install behind it.
- Access — one word: Allowed; Blocked, for your own decision; or, when “Who can connect” is what refuses, the reason itself — Unverified, Not allowed. It is a control with three choices: Workspace default, shown with what “Who can connect” currently gives the client; Allow; and Block, which asks for an optional message that overrides the workspace’s for this client, shown beside the word as a speech-bubble icon you hover to read. Choosing the default drops the client’s own decision rather than pinning it, so only clients that differ from the posture carry one — and keep it when the posture changes. A decision on a client Conduit recognizes covers every install recognized as it; on an unknown client it covers clients with exactly that identity — which is the client’s own claim, so a block on one holds only until it registers again under another. To keep self-registering clients out for good, use Verified clients only or Only allowed clients, which refuse anything unproven that you have not allowed.
- The leading column — for a client that can be a tab under How to use Conduit on Home, a drag handle and a house: solid while the tab is shown, faint while you have hidden it; click to switch. A blocked client has no tab while it is blocked, whatever the house says, and gets it back when allowed again; hiding an allowed one says nothing about access. The clients with tabs are the top rows, in the order members see them; drag a row by its handle (or use Move up / Move down in its menu) to rearrange them. The first shown, allowed tab is the one Home opens with. A client with no tab (MCP Inspector, the CLI, an unknown client) has neither handle nor house.
- Members, Sessions and Last active: who has connected with the client here, their live sessions, and when it was last used in this workspace.
{{server_url}} stands for the workspace’s server URL and
{{client_name}} for the client’s name, filled in when shown, so the text
never carries a URL that changes per workspace. The steps can’t be saved
blank; Use Conduit’s instructions in the menu brings the shipped steps
back. None of this changes who may connect.
View members in a row’s menu lists the members using the client, with when
they authorized it, when they were last active here, and their live sessions,
and offers Revoke per member or for all: the client stops reaching this
workspace on that member’s behalf at once, and access here returns once they
authorize the client again. Nothing is deleted: the member’s token keeps
working at their other workspaces until its next refresh, which is refused
while any workspace holds a revocation, so the client returns to the consent
screen — and that approval, which the member gives on their own, lifts the
revocation everywhere. A revocation makes a member re-approve a client; to
keep a client out, block it. Remove client
takes a client you added out of the workspace’s knowledge, with its tab and any
decision on it.
Members see a block in the client’s error and on the consent screen before
they approve (which lists each of their workspaces that will refuse the
client, and offers nothing to approve when none would admit it). The home
page offers setup steps only for the clients the workspace admits: a blocked
client has no tab there, and when “Who can connect” itself refuses clients
the page says so above the tabs, in the posture’s sentence and your message.
Instance: accepting registrations
Settings → Sign-in (instance admins) carries the one client setting that cannot be per workspace: whether clients may register themselves at/oauth/register at all. Registration happens before anyone signs in and
names no workspace, so it is the authorization server’s own switch. Turning it
off keeps the registry from filling with unknown clients — new clients must then
identify with a URL-based client ID, and clients already registered keep
working. It does not decide who may connect; each workspace does, and a
workspace that wants no self-registered clients sets Verified clients only.
Each user’s own sessions can be revoked from Settings → Users.
Sign-ins, consents, token grants, and revocations are all audit-logged (a workspace
revoke lands in that workspace’s audit log), and rejected MCP requests are
counted by reason in the metrics — a burst
of invalid_token is either a fleet with stale credentials or someone
guessing.
Protocol versions
Conduit speaks the stateless MCP revision2026-07-28 and the handshake
revisions 2025-03-26, 2025-06-18, and 2025-11-25, selected per request;
the MCP client reference describes how each is
negotiated. Newer-version features — like URL elicitation, which powers the
in-client
account-connection prompts
— degrade gracefully for clients that predate them.