> ## Documentation Index
> Fetch the complete documentation index at: https://pipedream.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Single Sign-On

> Connect your identity provider, understand what Conduit reads from it, and control how people sign in.

Conduit signs users in through any OIDC-compliant identity provider — Okta,
Microsoft Entra, Google, or a custom issuer. SSO covers every surface:
the web UI, the MCP endpoint's OAuth flow (an AI client's
browser window lands on the same login page), and the CLI's device login flow.

## Registering Conduit with your provider

Create a **web application** OIDC client in your provider with a
client secret. Each Conduit provider has its own redirect URI:

```
https://<your-conduit-host>/api/auth/callback/<key>
```

You can copy it from the new provider screen before you save.

The host comes from `CONDUIT_BASE_URL`, which must be the address users
actually reach — the provider redirects the browser there, so a mismatch
breaks sign-in.

Then add the provider in Conduit under **Settings → Sign-in**: instance admins
add instance providers there, and workspace admins add their workspace's
providers (see [Instance sign-in vs. workspace SSO](#instance-sign-in-vs-workspace-sso)).
Presets for Google, GitHub, Microsoft, and Okta prefill the issuer and
scopes; **Custom OIDC** covers any other compliant provider. You supply:

* **Issuer URL** — Conduit discovers the authorization, token, and JWKS
  endpoints from `<issuer>/.well-known/openid-configuration`. Providers
  without discovery can be configured with explicit authorization and token
  URLs instead.
* **Client ID and secret** — the secret is write-only: no API response ever
  returns it, and it is stored encrypted. Editing a provider keeps the stored
  secret unless you change the client ID, issuer URL, or token URL; those
  changes need the secret re-entered.
* **Scopes** — editable per provider; the default is `openid email profile`.
  Add your provider's groups scope (e.g. `groups`) if you use group claims in
  [provisioning rules](/docs/conduit/configure/access-control#user-provisioning).
* **Request fresh sign-in** — available for Okta, Microsoft, and Custom OIDC;
  on by default. Asks the provider to authenticate
  users again each time Conduit starts a sign-in. Turn it off to let the provider
  reuse an existing session. The provider can still require sign-in or MFA
  according to its own policy.

For these provider types, the setting is available at both instance and
workspace scope. When on, Conduit sends the [OIDC `prompt=login` parameter](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest);
when off, it omits `prompt`. Turning it off does not request silent sign-in
(`prompt=none`). It is useful when a provider cannot satisfy a fresh-authentication
request through every sign-in method it supports.

The Google and GitHub presets always omit `prompt`, including for existing
configurations. They do not expose this setting because neither documents
support for `prompt=login`.

Each provider also carries an optional **access-denied message**: admin-written
help shown to a user whose sign-in the *provider* refused (typically someone
not assigned to the app in the IdP). Write it for the person staring at the
error — "Request access to Conduit in the IT portal", with a link. It's
public: the login page (and a workspace provider's workspace login page) shows
it next to the provider's button before anyone signs in.

## What Conduit reads from your provider

Conduit reads identity claims from the **ID token** — never from the
provider's access token. This has practical consequences worth knowing before
you file a ticket with your identity team:

* **No custom authorization server or access-token audience is needed.** Your
  provider's default/organization authorization server works as-is, because
  Conduit never inspects the access token or calls it against your APIs.
* **`sub` is stored exactly as your provider asserts it.** Identities are
  keyed by (provider, subject) — never by email — so an email change in the
  directory follows the same person rather than creating a new one, and no
  claim-mapping logic is required on the provider side.
* **`email` and `email_verified`** name the account. Sign-in follows the
  directory when the address changes.
* **`name`**, or **`given_name`** and **`family_name`** when `name` is absent,
  is the person's display name. With neither, Conduit uses the part of the
  email address before the `@` (`dylan.sather@company.com` becomes
  "dylan.sather") and replaces it the first time a sign-in asserts a name. A
  name set in Conduit or asserted earlier by a provider is kept.
* **A groups claim**, when your provider includes one in the ID token, is
  available to [provisioning rules](/docs/conduit/configure/access-control#user-provisioning) —
  "members of directory group X land in Conduit group Y" — and is evaluated on
  every sign-in.

The ID token's nonce is verified against the flow state (replay protection),
and raw tokens are never logged.

To see exactly which claims your provider asserted — for example, whether a
groups claim arrived at all — set `CONDUIT_LOG_LEVEL=debug` and sign in; the
verified claims are logged at debug level.

Signing in through SSO is what provisions an account: the first sign-in
creates the user, later sign-ins follow email changes from the directory. To
provision users *before* they sign in — and deprovision them when they leave —
pair SSO with [SCIM](/docs/conduit/configure/scim).

## Instance sign-in vs. workspace SSO

Providers exist at two scopes, and the difference is who manages them and how
users reach them:

* **Instance providers** (**Settings → Sign-in**, instance admins) appear as
  buttons on the login page. In a single-workspace deployment they are the
  only providers, and the same page carries the workspace settings that apply
  there: each provider's **Domains** action (below), the **Domains** list, and
  **Ask members to sign in again**.
* **Workspace providers** (**Settings → Sign-in**, workspace admins) belong to one
  workspace and never appear as buttons on the main login page. People reach
  them through the workspace's own login page, or by **home-realm discovery**:
  a user types their email address, and its domain routes them to their
  workspace's provider. Signing in through a workspace provider also grants
  membership in that workspace automatically.

Disabling or deleting any identity provider, the workspace's own or the
instance's, signs out everyone who signed in through it, in the web app and
in MCP clients alike, members of other workspaces included, so turning off a
compromised provider takes effect at once. Turning it back on revives none
of those sign-ins. Nobody can disable or delete the provider they're signed
in through; sign in another way first.

### The main login page

In a multi-workspace deployment the main login page shows the instance
providers' buttons, then an email field with **Continue with email**. An email at a
domain a workspace has verified, with a provider chosen for it, goes straight
to that provider with the address already filled in, and the session starts in
that workspace. Any other email reveals the password field. With password
sign-in off, the page says so and points at the provider buttons instead. A
routed email is offered the password field only when its provider can't be
reached. The lookup behind **Continue with email** only says whether a domain routes,
never whether an account exists, and it's throttled per IP. A
single-workspace deployment's login page asks for the email and password
together.

Because a routed email gets no password field while its provider works, keep
the break-glass account (`CONDUIT_ADMIN_EMAIL`) at an address no workspace
verifies, such as the default `admin@localhost`.

Once **Continue with email** reveals the password field, the page shows only the email
and password, with **Sign in another way** at the top right of the sign-in box
to bring back everything else. The login page also leads with the method a
browser last signed in with: the email and password fields, that one
provider's button, or the email step for a workspace's provider. **Sign in another way** shows the
full page and forgets the choice. The browser remembers only the method, never
the email address or the workspace, since anyone at the machine can see the
login page.

### The workspace login page

In a multi-workspace deployment, a workspace has a login page at
`/login/<workspace-id>`, where `<workspace-id>` is the same id as in the
workspace's MCP URL (`/mcp/<workspace-id>`). It shows the
workspace's name, logo and the sign-in methods it accepts (see below): its
own providers, the instance providers it accepts, then email and password
fields when it accepts them. It doesn't ask for the email first, since it
already knows the workspace. **Sign in another way** at the top right of the
sign-in box leads to the main login page.

When the workspace has exactly one provider of its own, the page goes straight
to it; its other methods are there when the person comes back. A workspace with
no provider of its own does the same for an instance provider when that is the
only method it accepts. It does this once per browser tab: signing out, or coming
back after the provider refused the sign-in, shows the page in that tab
instead of starting the provider again, and a new tab starts it again. A
refused sign-in's error page links back to the workspace login page. A
workspace left with nothing to offer says so, and its owners sign in another
way to fix it.

Its address is under **Login page** on **Settings → Sign-in**. Share it with
your members: it works before any domain is verified. A sign-in from it starts
the session in that workspace for anyone who belongs to it, and someone already
signed in who opens it goes on in that workspace. The page is public: anyone
with the workspace's id, which is in its MCP URL, can see the workspace's
name, logo and the sign-in methods it accepts. The id can't be guessed, and an
unknown one answers as if no such workspace existed.

When an MCP client or the CLI asks you to approve it, the approval screen
names any workspace that doesn't accept how your browser signed in, since the
client would be refused there too, and offers to sign in to it again first.

Home-realm discovery runs on the workspace's **email domains**, under
**Domains** on the same page. Add a domain, then prove your organization owns
it: Conduit issues a DNS challenge, you publish it as a TXT record —

```
conduit-domain-verification=<token>
```

— and check it with the domain's **Verify** button. Which provider a domain
signs in with is set in the provider's dialog, under **Domains**; each
provider lists its domains, marked verified or not, and clicking an
unverified one opens its verification. A new domain starts with the
workspace's provider when it has exactly one. A domain sends sign-ins to its
provider once it is verified and the provider is enabled. Verification is
what stops one workspace from capturing another organization's sign-ins by
claiming a domain it doesn't own: a verified domain belongs to one workspace
across the instance. Public email services such as gmail.com can't be added.
Removing a provider keeps its domains, verified, in the workspace.

Keep the TXT record published after verifying. Verification doesn't expire,
and deleting the record changes nothing on its own, but the record is what
keeps the domain yours: if another workspace later publishes its own record on
the domain while yours is gone, verifying moves the domain to that workspace.
Control of the domain's DNS is what verification rests on, so whoever controls
it decides. Your workspace keeps the domain, unverified; the audit log records
the change, and its owners and admins are emailed when email is configured.

### Who joins through a workspace provider

Signing in through a workspace provider makes someone a member of the
workspace only when the provider confirms their email (`email_verified`) and
it is at one of the provider's **Domains**, the domains that sign in with that
provider (one added there joins the workspace's Domains, unverified). The
domains don't need to be verified for this, so joining works as soon as you
add them, without a DNS record, and you can list a partner's domain you
don't own. Public email services such as gmail.com can't be listed, so a
provider like Google lets in only the accounts at your domains, not anyone
with a Google account.

At a domain you've verified, the person joins as they sign in. At one you
haven't, they're asked first: the sign-in ends on a **Join Acme?** page, and
they become a member only if they choose to. Any workspace can list a domain
without proving it owns it, so this keeps a workspace from making someone a
member without their knowing; verifying the domain skips the question. The
question stays open for 7 days, and a later sign-in asks again.

A provider that doesn't send `email_verified` at all, such as Microsoft Entra
ID, is trusted only for the domains you've verified: its people join once
their domain is verified.

Anyone else the provider authenticates gets in only with an account it
already signs in: one SCIM provisioned, or one that signed in through it
before. Everyone else is refused before Conduit creates an account for them,
and the refusal appears in the workspace's audit log as a failed sign-in with
the reason: an address outside the provider's domains, or one the provider
didn't confirm. Someone outside those domains, such as a contractor, joins
through SCIM or through their domain listed on the provider. Removing a
domain changes who joins from then on; members who joined through it stay
members until you remove them.

A workspace provider needs at least one domain, when you add it and after:
Conduit refuses a change that would leave it with none.

The provider dialog checks what the provider publishes about itself (the
`claims_supported` list in its OIDC discovery document). If the provider
lists its claims without `email_verified`, it never confirms addresses, and
the dialog warns that only people at a domain you've verified join through
it. If it publishes no list, the dialog notes the same may apply.

### Which sign-in methods a workspace accepts

**Settings → Sign-in → Sign-in methods** lists every way to sign in to the
workspace, each with a switch (the API is `GetWorkspaceSignInPolicy`,
`UpdateWorkspaceSignInPolicy`, and `UpdateWorkspaceInstanceProvider` for one
instance provider):

* **The workspace's own providers** are accepted while they're enabled.
* **The instance's providers and email and password** are switched on or off
  for the workspace. A workspace with all of them on accepts an instance
  provider added later too; once any is off, a new instance provider starts
  off there. Email and password can only be on while the instance offers
  password sign-in.
* **Ask members to sign in again** makes a sign-in older than 1, 7 or 30 days
  stop letting members into the workspace.

The workspace login page offers exactly the methods that are on.

While a workspace accepts every method (password and every instance
provider, none restricted to its domains), it also admits a sign-in through
another workspace's provider, and a session that recorded no sign-in
method. Once it narrows anything, those are refused, and the person signs
in again one of the ways it accepts.

An instance provider's menu opens its **Domains** and an **Only allow
accounts from these domains** setting: with the setting on, someone
signing in through it gets into this workspace only if their Conduit account's
email is confirmed and at one of its domains. The instance provider still signs
them in to Conduit; the workspace just doesn't admit them. The email and
whether it's confirmed are the account's, as recorded when the account was
created (a directory sync can update the email): confirmed when the provider
said so, or said nothing about it, since an instance provider is the
instance's to trust. The domain matches the email as it's written, so an
internationalized domain written in Unicode doesn't match the same domain
listed in its ASCII (punycode) form. Owners are exempt, so the setting can't
lock them out, and instance admins are never refused. Those domains join
the workspace's **Domains**, and once one is verified, people who enter an
address at it on the main login page go straight to that instance provider
and land in this workspace. This doesn't make anyone a member:
members still come from invites, SCIM, or signing in through one of the
workspace's own providers at its domains.

A person whose session doesn't meet the workspace's policy is refused
there: the web app shows **Sign in to Acme again**, which leads to the
workspace login page, and an MCP client is sent to authorize again (a 401),
where the approval screen offers the fresh sign-in. It applies to sessions
already open. A session that recorded no sign-in method is admitted only
while the workspace accepts every method. Owners can
always sign in with a password or an instance provider, so a broken provider
can't lock the workspace out, and instance admins are never refused.

A workspace always keeps a way in. Conduit refuses a change that would leave
it accepting no sign-in method, leave a provider that admits only its
domains with none, or refuse the admin making it. That covers switching off
or removing the workspace's own providers and removing domains as well as the
switches on this page. A stricter **Ask members to sign in again** is always
allowed; it may ask you to sign in again too. Only the instance can take away
the last method, by no longer offering the ones the workspace accepts. Then
the workspace login page says the workspace has no sign-in methods set up,
and **Settings → Sign-in** warns that only owners and instance admins can
sign in until an admin switches another one on. An instance provider the
instance turns off stays in the list, marked as such, while the workspace
has a choice about it; its switch still changes that choice.

## The sign-in policy

Alongside the providers sits the instance-wide sign-in policy — which methods
exist at all. Instance admins manage it through the API or the
`get_auth_policy` and `update_auth_policy` built-in admin tools:

* **Password sign-in** can be disabled entirely once SSO works, leaving your
  identity provider as the only way in. There is deliberately no open
  self-service sign-up, email verification, or password-reset flow to disable
  alongside it: accounts come from the first-run wizard, SSO, SCIM, or an
  [invite](/docs/conduit/configure/access-control#invites) (which creates a password account only
  while password sign-in is on), and password recovery for the operator is
  the break-glass credential below. Turning password sign-in off signs out
  everyone who signed in by password, in the web app and in MCP clients,
  except instance admins (the break-glass credential is a password sign-in);
  turning it back on revives none of those sign-ins.
* **Workspace creation** can be limited to instance admins, and **personal
  workspaces** (a workspace of one's own for each new user, in multi-workspace
  deployments) can be switched off.

### Break-glass access

If SSO misconfiguration ever locks everyone out, the bootstrap credential is
the recovery path: with both `CONDUIT_ADMIN_EMAIL` and
`CONDUIT_ADMIN_PASSWORD` set in the environment, the bootstrap admin can
always sign in with them, without touching the stored password. The login
page keeps its email and password fields visible while the credential is
configured, even with password sign-in disabled by policy, so there is
always somewhere to type it — and the instance Sign-in settings show a
warning in that state, reminding you to restart without the variables once
recovery is done. See the
[configuration reference](/docs/conduit/configure/reference#bootstrap-admin). Leave both unset in
normal operation.

Each user can own one workspace. Workspaces they join as a member do not count
toward that limit, and instance admins are not limited.

## How SSO threads through MCP and the CLI

Nothing extra to configure — but useful to understand when reviewing the
flows:

* An **AI client** connecting to `/mcp` goes through Conduit's own
  [OAuth flow](/docs/conduit/use/mcp-authorization): the browser window it opens is
  the same login page, SSO included. Your provider authenticates the human
  mid-flow; the token the client ends up holding is issued by Conduit, and
  your provider's tokens are never given to the client.
* The **Conduit CLI**'s `conduit login` shows a short code to approve in the
  browser — again the same login page and providers. The CLI setup UI is
  feature-flagged and hidden by default.

Every sign-in — and every failure, with its reason — is recorded in the audit
log and exported through the configured telemetry exporters.
