For AI agents: Documentation index at /llms.txt

Skip to content

Enterprise SSO

Internet Identity can authenticate your staff against your company’s existing OpenID Connect provider, such as Okta, Entra ID, Google Workspace, or Auth0. Staff enter your company domain on the sign-in screen and authenticate with the account they already have.

Setup is two steps and takes one OIDC client and one file on your domain. Nothing has to be registered with Internet Identity: it discovers your configuration from that file. A third, optional step controls access app by app.

This guide is for the SSO administrator. If you are building an application, see Internet Identity.

In your identity provider, create App Integration → OIDCWeb Application.

SettingValue
Redirect URIhttps://id.ai/callback
Grant typesAuthorization Code and Implicit (hybrid)
ID tokenAllow ID Token with implicit grant
Access tokenLeave Access Token unchecked
Scopesopenid, profile, email

Copy down the client_id, for example 0oaDEFAULT. You need it in step 2.

Serve a file over HTTPS at exactly this path on your company domain:

https://acme.com/.well-known/ii-openid-configuration
{
"client_id": "0oaDEFAULT",
"openid_configuration": "https://acme.okta.com/.well-known/openid-configuration",
"name": "Acme Corp"
}
FieldValue
client_idThe client from step 1
openid_configurationYour IdP’s OIDC discovery URL
nameOptional label on the sign-in screen

Serve it with Access-Control-Allow-Origin: * so applications can check the domain before sending a user into the flow.

That is the whole setup. On id.ai, staff choose Sign in with SSO, enter acme.com as their company domain, then authenticate against your IdP.

A sign-in stays valid for eight hours. Once that much time has passed since a member of staff authenticated, they authenticate against your IdP again. Set "session_max_age_seconds" to choose a different length:

{
"client_id": "0oaDEFAULT",
"openid_configuration": "https://acme.okta.com/.well-known/openid-configuration",
"session_max_age_seconds": 28800
}

The default of eight hours (28800) covers a working day, so staff re-authenticate at most daily. The ceiling is 30 days (2592000).

Applications choose their own session length as well, and this value caps it: an application asking for 30 days on a domain that allows eight hours gets eight hours.

By default your staff can sign in to any Internet Computer application with the client from step 1, and your provider’s assignment rules for that client apply everywhere. To govern one application on its own, give it a client of its own.

Repeat these three steps for each application you want to gate.

a. Add a client for the app. Register a second OIDC client, identical settings to step 1. Copy its client_id, for example 0oaPAYROLL.

b. Assign who is allowed. That client → Assignments → add the groups or users. This assignment is the access rule: assigned staff sign in as normal, anyone else is stopped by your IdP. On Entra ID, set Assignment required to Yes on the client as well. It defaults to No, which leaves the app open to your whole tenant.

c. Map the app to it. Add one app_clients line to the file from step 2, keyed by the application’s origin:

"app_clients": {
"https://payroll.acme.com": "0oaPAYROLL"
}

By default, an application missing from app_clients falls back to the organization’s client from step 1, so staff can sign in to it like any other. Set "gate_all_apps": true to refuse those sign-ins instead, and staff visiting an unlisted application are told your organization has not granted it access.

Use true when the list is meant to be exhaustive, so a new application cannot be signed in to until you have added it deliberately.

This applies only once an application has a client of its own.

Some providers, Entra ID among them, issue a different sub for the same person in each OIDC client. Sign-ins through the per-app client would then look like a different person from sign-ins through the organization’s client. Set "stable_identifier_claim" to a claim that stays the same across your clients: on Entra ID that is oid.

It defaults to sub, which is correct when your provider’s sub is already the same in every client.

The file is public, so any origin you list is visible to anyone who reads it. To map an application without naming it, use a salted hash of its origin as the key instead of the origin itself.

Run this in a shell, with origin set to the application’s URL:

Terminal window
origin=https://payroll.acme.com
salt=$(openssl rand -hex 8)
data=$origin$salt
out=$(printf %s "$data" | openssl dgst -sha256 -r)
hash=$(echo $out | cut -d' ' -f1)
echo "$hash:$salt"

It prints one value, in the form <hash>:<salt>. Use it as the key in place of the origin:

"app_clients": {
"9c8dbbd738e2e390267c7dd7350623c541907a66a1f064e22c13d954e08322af:9f86d081884c7d65": "0oaPAYROLL"
}

Internet Identity matches the key by hashing the origin of whichever application the user is signing in to, so cleartext and hashed keys can be mixed in one file.

Every field, with the optional ones filled in:

{
"client_id": "0oaDEFAULT",
"openid_configuration": "https://acme.okta.com/.well-known/openid-configuration",
"name": "Acme Corp",
"session_max_age_seconds": 28800,
"app_clients": {
"https://payroll.acme.com": "0oaPAYROLL",
"https://board.acme.com": "0oaBOARD"
},
"gate_all_apps": false,
"stable_identifier_claim": "sub"
}

client_id and openid_configuration are required. The rest are optional:

FieldDefaultPurpose
namethe domainLabel shown on the sign-in screen
session_max_age_seconds28800 (eight hours)How long a sign-in stays valid before staff authenticate again
app_clientsnoneMaps an application’s origin, or a salted hash of it, to the client that governs it
gate_all_appsfalseRefuse applications that are not listed in app_clients
stable_identifier_claimsubThe claim that identifies the same person across your clients