Browse docs All docs
Docs / Single sign-on (SSO)
Docdeploymill://docs/sso-setup

Single sign-on (SSO)

DeployMill supports enterprise single sign-on so your team signs in through your identity provider (IdP), whether Okta, Entra ID, Google Workspace, or any standard OIDC/SAML provider, instead of a per-user DeployMill password. Once SSO is set up for your domain, teammates who sign in with a matching email address are automatically joined to your org.

SSO is an Enterprise capability. It is not part of the envelope a card lifts on, so Builder and Studio don't include it. Registering a connection for an org without the sso entitlement is refused with a coded sso_not_available. If you're on Builder or Studio and want SSO, talk to us about Enterprise before you start the IdP setup below. See Plans & quotas.

How SSO is configured: operator-managed

SSO connection setup is done by the DeployMill operator, not self-serve from the dashboard. Configuring SSO means handing DeployMill an IdP secret (an OIDC client secret, or a SAML signing certificate / private keys), and those secrets are infrastructure-level trust, like the platform's own provider keys. They're stored server-side only and are never exposed to an MCP client, returned by any API, or written to a log. So there is deliberately:

  • No MCP tool to register an SSO connection, and
  • No tenant self-serve flow in the dashboard to enter IdP credentials.

To turn SSO on for your org, give the operator your IdP details (below) and they register the connection. What you can see in the dashboard is a read-only status page confirming the connection. See The SSO status page.

SSO is modeled provider-neutrally: a connection is either OIDC or SAML, and no vendor name is baked into the configuration. OIDC is the common path, and the walkthrough below uses Okta as the example.

Domain auto-join

An SSO connection claims one or more email domains (e.g. acme.com). When a user signs in through SSO with an email in a claimed domain:

  • If they're not yet a member of the org that claims the domain, DeployMill

    automatically creates their membership with the member role (the least-privileged default, so auto-joined users never land as admin or owner). An admin can promote them afterward from /account/org.

  • If they're already a member, nothing changes and they just sign in.

A given email domain can be claimed by at most one org, so auto-join is never ambiguous.

SSO enforcement

By default, having an SSO connection doesn't force anyone to use it. Password and social ("Continue with Google" / "Continue with GitHub") sign-in still work for the claimed domain. SSO enforcement changes that: when enabled for your org, any sign-in attempt with an email in a claimed, enforced domain is blocked from the password and social (Google/GitHub) paths and steered to your IdP instead. This is how you guarantee everyone on your domain authenticates through your identity provider.

Like the connection itself, the enforcement flag is operator-set. Ask the operator to enable it for your org. The SSO status page shows whether enforcement is on.

Proving you own the domain (required before enforcement bites)

Enforcement only applies to a domain your org has proven it owns with a DNS-TXT record. This is deliberate: an unverified claim (a typo, an over-broad domain, one you don't own yet) must never lock people out of password and social sign-in, so until the proof is in place, enforcement quietly doesn't take effect even when the flag is on. Domain auto-join is unaffected either way.

The round-trip:

  1. Ask the operator for the challenge record. They read it out of DeployMill

    for your org and domain. It's a TXT record at _deploymill-challenge.<domain> whose value looks like deploymill-domain-verification=<token>. The token is specific to your org and that domain.

  2. Publish it in your DNS at that exact name, with that exact value.
  3. Tell the operator to verify. They re-check DNS; once the record resolves,

    the domain is recorded as verified and enforcement starts applying to it. If the record isn't visible yet (DNS propagation), verification simply reports "not found" — fix or wait, then ask them to re-run it. Re-verifying an already-verified domain is harmless.

You can leave the TXT record in place afterward; it's the same style of record used to verify a custom app domain.

Signing in with SSO

There are two ways a user reaches the SSO flow:

  • They click "Sign in with SSO" on the sign-in page (which routes to

    /sign-in/sso) and enter their work email. DeployMill resolves the domain to your IdP and redirects them there.

  • If enforcement is on for their domain, even an attempt to use

    password or social (Google/GitHub) sign-in is redirected into the SSO flow automatically.

After the IdP authenticates them, they land back in DeployMill, are auto-joined to your org (if they weren't already a member), and are signed in.

Okta setup walkthrough (OIDC)

This is the information you collect from Okta and hand to the DeployMill operator. The operator then registers the connection.

  1. Create an OIDC app in Okta. In the Okta admin console, create a new

    OIDC – Web Application integration (Authorization Code flow).

  2. Set the sign-in redirect URI (callback URL). Point it at DeployMill's SSO

    callback:

   https://<your-deploymill-host>/api/auth/sso/callback/<providerId>

The <providerId> is the stable connection id the operator assigns your org (for example acme-oidc). Confirm the exact value with your operator before you save the Okta app, since it must match on both sides.

  1. Collect the credentials. From the Okta app, note:

      https://<your-org>.okta.com, from which DeployMill fetches discovery at {issuer}/.well-known/openid-configuration),

      • Decide your claimed domain(s). Tell the operator which email domain(s)

        this connection should claim (e.g. acme.com). This is what drives domain auto-join, and it must not already be claimed by another org.

      • Hand it to the operator. They register the OIDC connection (issuer, client

        id, client secret, claimed domain, and the providerId). The client secret goes straight into server-side storage and is never echoed back.

      • (Optional) Ask for enforcement. If you want everyone on the domain forced

        through Okta, ask the operator to enable SSO enforcement for your org — and publish the DNS-TXT proof for the domain, since enforcement doesn't take effect until the domain is verified. See Proving you own the domain.

      SAML works the same way (operator-registered, secret-free status page), with the operator supplying the IdP issuer/entityId, the SSO entry point, and the signing certificate (or IdP metadata XML) instead of an OIDC client id/secret.

      The SSO status page

      Admins and owners can view a read-only SSO status page at /account/org/sso (linked from /account/org; plain members don't see it). It confirms, without ever revealing any secret:

      • whether SSO is configured for your org,
      • the provider type (OIDC or SAML),
      • the issuer and connection id,
      • the claimed email domain(s), and
      • whether enforcement is on.

      Because configuration is operator-managed, this page is view-only, with nothing to edit here. To change the connection, the claimed domains, or the enforcement flag, contact your operator.

      Where to go next

      • Team management: roles, invites, and seats

        (auto-joined SSO users land as member and can be promoted here).