Skip to main content

Set up single sign-on (CLI)

On a self-hosted deployment you can connect the whole deployment to your organization's identity provider, so people sign in with their work account in every tenant. This is a system connection, and you set it up from the command line with da admin sso. It speaks OpenID Connect: this page walks through Microsoft Entra ID, and Other identity providers lists what changes for Okta, AD FS and the rest.

A system connection differs from a tenant's own connection, which that tenant's administrators set up on the Security page (Single Sign-On):

System connection (this page)Tenant connection
Set up byYou, the operator, with the admin API keyThe tenant's administrators, on the Security page
Signs people in toAny tenant its mappings nameIts own tenant
Email domainYou declare it; no DNS record neededProven with a DNS TXT record
Available onSelf-hosted deploymentsEvery deployment

A typical self-hosted deployment has one tenant and one system connection, set up at install time next to SMTP.

This guide assumes you have installed the CLI and pointed it at your deployment. If not, follow System Administration (CLI) first.

How access works​

Your identity provider decides who is in which group. DocAI Fabric decides what each group may do:

Entra group → DocAI Fabric group (in a tenant) → roles
"DocAI Admins" "Admins" in Acme Admin, whole tenant
"Finance Reviewers" "Invoice Reviewers" in Acme Reviewer on project Invoices

A mapping links an identity provider group to a DocAI Fabric user group in a given tenant. At every sign-in DocAI Fabric reads the groups in the person's token, adds them to the mapped groups (and to those groups' tenants), and removes them from mapped groups the token no longer names. Someone whose token names no mapped group cannot sign in. This is the default, identity provider mode; see Managing access in DocAI Fabric instead for the alternative.

The full rules (administrators through a group, accounts, sessions, MFA, what happens when someone leaves) are the same as for a tenant connection and are described in the Single Sign-On guide.

Before you start​

  • The application URL is your public address. The redirect URI the identity provider calls back is built from it: <application URL>/auth/sso/oidc/callback. Check it with da admin config get app.url and set it if needed (Configure the application URL). It must be the https:// address your users type, not http://localhost:8080.
  • The deployment can store secrets. The client secret is stored encrypted with CREDENTIAL_ENCRYPTION_KEY. On an on-premises Docker install, generate it and add it to .env and to docker-compose.yml as described in Create your settings file. Without it, da admin sso create is refused with the deployment has no encryption key configured.
  • The tenant and its user groups exist. Create the tenant with da admin tenant create (Tenants and sign-up). Its administrator then signs in and creates a group for each kind of access, with its roles, on the Team page, Groups tab (Groups). Groups are created in the application, not with the CLI.
  • An administrator who signs in with a password stays as your way back in if the identity provider is down or misconfigured. The tenant's first administrator is that person: keep their password.
  • An email domain your people sign in with, for example contoso.com. Their sign-in names in Entra must be at that domain; onmicrosoft.com addresses cannot be used.
  • The server can reach the identity provider. For Entra, outbound HTTPS to login.microsoftonline.com. An identity provider on your own network (for example AD FS) is reachable by default.
  • Admin access to Microsoft Entra ID, to register an application.

Step 1: Register DocAI Fabric in Microsoft Entra ID​

In the Microsoft Entra admin center:

  1. App registrations → New registration. Name it (for example DocAI Fabric), choose Accounts in this organizational directory only, and under Redirect URI choose Web and enter <application URL>/auth/sso/oidc/callback, for example https://docai.contoso.com/auth/sso/oidc/callback. Register.
  2. On the app's Overview, copy the Application (client) ID and the Directory (tenant) ID.
  3. Certificates & secrets → New client secret. Copy the secret's Value at once; Entra shows it only once. The Secret ID next to it is not the secret. Note its expiry date: when it expires, sign-in stops until you set a new one (Changing a connection).
  4. Token configuration → Add groups claim. Choose Groups assigned to the application if your Entra plan allows it, otherwise Security groups. Under ID, choose Group ID. Save.

The Single Sign-On guide explains these choices in more detail.

Step 2: Create the connection​

da admin sso create --name "Contoso Entra ID" \
--issuer https://login.microsoftonline.com/<Directory (tenant) ID>/v2.0 \
--client-id <Application (client) ID>

The CLI asks for the client secret with the input hidden, so it never lands in your shell history. Paste the secret's Value. To pass it from a script or a secrets manager instead, pipe it in and add --client-secret-stdin.

The name is shown on the sign-in page as Sign in with Contoso Entra ID. The connection starts as a draft: nobody can use it yet. The output shows its connection_id, which the next commands take, and the redirect URI: check that it is exactly the one you registered in step 1. If it is not, your application URL is wrong; fix it, then da admin sso show <connection-id> shows the corrected URI.

The defaults suit Entra. Options you can add to create, or change later with set:

OptionDefaultChange it when
--slugMade from the nameYou want a different sign-in address, /sso/<slug>.
--group-claimgroups, rolesYour provider sends groups in a claim with another name (repeat the option for several).
--email-claimemailYour provider puts the address elsewhere. If the token has no email, the sign-in name is used when it is an email address.
--scopeopenid email profileYour provider needs another scope to send groups.
--require-mfaOffDocAI Fabric should refuse a sign-in whose token shows no multi-factor authentication. Run a test first: the report says whether your provider reports it.
--session-hours12Between 1 and 24. After it, people sign in again through the identity provider.
--accessidpSee Managing access in DocAI Fabric instead.

Step 3: Declare your email domain​

You run the deployment, so you declare the domain yourself; no DNS record is needed. Then add it to the connection:

da admin sso domain declare contoso.com
da admin sso set <connection-id> --domain contoso.com

Repeat --domain for each domain your people sign in with. --domain replaces the connection's list, so name all of them each time. A domain a tenant has already verified for its own connection is refused (belongs to another organization); da admin sso domain list shows who owns each domain.

Step 4: Map your groups​

List the tenant's groups and their roles:

da admin sso groups "Acme"

You can name a tenant or a group by its id or by its exact name. In Entra, open each group that should have access and copy its Object ID. Then map it:

da admin sso map <connection-id> <Entra group Object ID> \
--tenant "Acme" --group "Invoice Reviewers" --label "Finance Reviewers"

The label is for you: Entra sends group ids, and the label tells you which group an id is. da admin sso mappings <connection-id> lists the mappings and da admin sso unmap removes one.

A system connection can serve several tenants: map groups in each of them, and a person joins every tenant in which one of their groups is mapped.

Map an identity provider group to a group that holds Admin only when that is intended: everyone in it becomes an administrator of the tenant, and the tenant's administrators get an email when someone joins such a group.

Step 5: Test, then activate​

da admin sso test <connection-id> --open

This opens a one-time test sign-in in your browser (without --open, it prints the URL; open it within 10 minutes). Sign in at Entra as a person who should have access, in a private window if you are already signed in to Entra as someone else. The browser then shows the test report: whether the sign-in passed, the account it would create or link, the groups the person would join and leave, the group values Entra sent that are not mapped, whether multi-factor authentication was reported, and the claims received. A test changes nothing in DocAI Fabric.

If the test fails, the report names the reason (Troubleshooting). A failed test with no_mapped_group is also a quick way to find group ids: the report lists every value Entra sent. Map one and test again.

When a test has passed:

da admin sso show <connection-id> # "last test: passed"
da admin sso activate <connection-id>

A connection can be activated only after a test passed and once it has a client secret and a domain.

After activation​

  • Signing in. The sign-in page shows Sign in with Contoso Entra ID. People can also choose Sign in with single sign-on and enter their work email. The sign-in URL shown by da admin sso show (<application URL>/sso/<slug>) goes straight to Entra: use it for the app's tile in your organization's app launcher.
  • New people get an account at their first sign-in, with no password. You do not invite them: adding someone to a mapped group in Entra is how they join.
  • Tenant administrators see the connection on the Security page, Single Sign-On tab. They cannot change its settings, but they can add and remove the mappings for their own tenant.
  • Making single sign-on the only way in is a per-tenant decision: the tenant's administrators switch on Require Single Sign-On on the same tab and add break-glass exemptions. A system connection counts for it. See Require single sign-on.
  • Audit. Every sign-in and every change to the connection, its domains and its mappings is recorded in the audit log (sso.login.succeeded, sso.login.failed, sso.user.provisioned, sso.config.updated, sso.group_mapping.updated). See Audit log and retention.

Managing access in DocAI Fabric instead​

If your identity provider cannot send groups (Google Workspace, for example), or you prefer to manage access in DocAI Fabric, use app mode. A new person joins one default group, in one tenant, at their first sign-in; after that the tenant's administrators manage their groups on the Team page, and the identity provider only proves who they are:

da admin sso set <connection-id> --access app \
--default-tenant "Acme" --default-group "Viewers"

No mappings are needed in this mode, so a test sign-in does not depend on the person's groups.

Changing a connection​

da admin sso list # all system connections
da admin sso show <connection-id> # settings, provider values, mappings, last test
da admin sso set <connection-id> --session-hours 8 # only the options you give change
da admin sso set <connection-id> --client-secret # asks for a new client secret

When the Entra client secret approaches its expiry, create a new one in Entra and set it with --client-secret. Changing how the connection signs in (issuer, client, secret, claims, domains, access) clears its last test. An active connection keeps working, but run a test again to confirm the change.

To stop sign-in through the connection, da admin sso disable <connection-id>; activate switches it on again after a passing test. To remove it, disable it, then da admin sso delete <connection-id>. Accounts it created stay, and can sign in again once another connection covers their domain or an administrator gives them a password. da admin sso domain remove <domain> takes a domain off every connection that lists it; a connection left with no domain is disabled.

Other identity providers​

Steps 2 to 5 are the same for every provider. What changes is the issuer and how the provider sends groups:

Provider--issuerGroups
Oktahttps://<your-org>.okta.com (or your authorization server's issuer)Add a groups claim to the ID token with a filter, for example Starts with DocAI-. Okta sends group names, so you map names instead of ids.
AD FShttps://<your-adfs-host>/adfsSend group names or SIDs in a groups claim with a claim rule.
Google Workspacehttps://accounts.google.comThe token carries no groups: use app mode.
Others (Ping, OneLogin, JumpCloud, Keycloak)The issuer from the provider's OpenID Connect settingsSend groups or roles in a claim, and name it with --group-claim if it is not groups or roles.

Register the redirect URI as an allowed redirect (or callback) URI of a web application, with the authorization code flow. Entra app roles work too: they arrive in the roles claim, which is read by default, so map the role values as you would group ids.

Use it with an AI agent​

The playbook your deployment serves to agents (da skill show system-administration, see System Administration) covers these commands, and the admin MCP server offers each of them as a tool. You can ask your agent, for example, "set up single sign-on with our Entra ID" or "why does the single sign-on test fail". Either way the client secret never passes through the agent: you enter it yourself when da admin sso set <id> --client-secret asks for it.

Troubleshooting​

da admin sso show <connection-id> repeats the reason of the last test. The Single Sign-On guide lists the messages people see when they sign in.

Message or reasonWhat to check
Secrets cannot be stored: the deployment has no encryption key configuredCREDENTIAL_ENCRYPTION_KEY is not set. See Before you start.
System single sign-on connections are available on self-hosted deployments onlyThe deployment runs as SaaS. Use a tenant connection on the Security page.
The domain ... belongs to another organizationA tenant has verified the domain for its own connection. Use that connection, or remove the domain from the tenant with da admin sso domain remove after agreeing it with them.
The connection cannot be activated yet. Missing: ...Add what it names: a client secret (set --client-secret), a domain (step 3), or, in app mode, a default tenant.
Run a successful test sign-in through the connection before switching it onRun da admin sso test until it passes (step 5).
An error from Entra before you come back (for example AADSTS50011)The redirect URI in Entra is not exactly the one da admin sso show prints. Fix the application URL or the Entra registration.
issuer_mismatch, idp_metadata_invalid, idp_unreachableThe issuer must be exactly the one the provider publishes, and reachable from the server. For Entra it is https://login.microsoftonline.com/<Directory (tenant) ID>/v2.0, not common.
client_secret_unavailableThe stored client secret cannot be decrypted: CREDENTIAL_ENCRYPTION_KEY was removed or changed after it was saved. Restore the original key from your backup, or set the secret again with set --client-secret. Everyone is refused until then.
token_exchange_failed, audience_mismatchWrong client id, or a wrong or expired client secret: set the secret's Value again with set --client-secret.
clock_skew, token_expiredThe server's clock is off by more than two minutes. Fix time synchronization (NTP) on the host.
email_domain_not_allowedThe person's email is not at one of the connection's domains, or their Entra sign-in name is at another domain (for example onmicrosoft.com).
no_email, email_not_verifiedThe token carries no usable email. In Entra, add the optional email claim, or give the account a mail address.
no_mapped_groupNone of the person's groups is mapped. The report lists the values Entra sent: map one (step 4). No values at all means Entra sends no groups claim: add it under Token configuration. With Groups assigned to the application, also assign the group to the enterprise application.
group_overageEntra sent "too many groups" instead of the list (over 200). Send only the groups assigned to the application, or use app roles.
mfa_required--require-mfa is on and the token shows no multi-factor authentication. Enforce it in Entra (Conditional Access), or turn the option off with --no-require-mfa.
This sign-in link has expired or was already usedA test link works once, for 10 minutes. Run da admin sso test again.