Skip to main content

Configure single sign-on with Okta

Connect your Okta org to Measured Cloud so your team signs in with their Okta accounts. OpenID Connect (OIDC) is the recommended setup; SAML 2.0 is covered at the end.

Goal​

People assigned to the Measured Cloud app in Okta sign in through Okta. Someone signing in for the first time gets an account automatically (if you turn that on), and you can then require Okta for everyone in your org.

Prereqs​

  • The super admin role in Measured Cloud. Only a super admin can add or change an identity provider.
  • An Okta administrator who can create app integrations.
  • A Measured Cloud deployment with PUBLIC_BASE_URL set (see Configuration). Every URL you paste into Okta is built from it. If it isn't set, the Add provider form says so and SSO can't work.

1. Start the provider in Measured Cloud​

  1. Open Settings → Single sign-on → Add provider.
  2. Set Provider to Okta.
  3. Leave the form open. The Copy these into Okta box shows the Sign-in redirect URI, for example https://dq.example.com/auth/sso/<your-org-slug>/callback. You need it in the next step.

2. Create the app integration in Okta​

In the Okta Admin Console:

  1. Applications → Applications → Create App Integration.

  2. Sign-in method: OIDC - OpenID Connect. Application type: Web Application. Click Next.

  3. Fill in the New Web App Integration form:

    Okta fieldValue
    App integration nameMeasured Cloud
    Grant typeAuthorization Code only. Measured Cloud doesn't use Okta's refresh tokens, so leave Refresh Token unticked.
    Sign-in redirect URIsThe Sign-in redirect URI from Measured Cloud, exactly as shown.
    Sign-out redirect URIsOptional: https://dq.example.com/login
    Controlled accessPick who may use the app. Only assigned people can sign in.
  4. Save. On the app's General tab, keep Client authentication set to Client secret (Okta's default). Measured Cloud sends the secret in an HTTP Basic header (client_secret_basic).

  5. Copy the Client ID and the Client secret.

  6. Under Login, set Login initiated by to App Only. Measured Cloud doesn't accept a sign-in started from the Okta dashboard tile: every sign-in must start from Measured Cloud's sign-in page, which issues a one-time state that the callback checks.

3. Finish the provider in Measured Cloud​

Back in the Add provider form:

Measured Cloud fieldValue
Display nameWhat your team sees on the sign-in page, e.g. Okta.
Okta domainYour Okta org's domain, e.g. acme.okta.com (or your Okta custom domain). No https://, no path.
Authorization server ID (optional)Leave blank to use Okta's org authorization server. Enter default, or a custom server's ID, only if you use Okta API Access Management.
Client ID / Client secretFrom step 2. The secret is encrypted at rest under your org's data-encryption key.
Default role for new usersThe role a person gets the first time they sign in. Viewer is the safest start.

The Issuer URL fills itself in from the domain:

  • org authorization server: https://acme.okta.com
  • custom authorization server: https://acme.okta.com/oauth2/<server-id> (for example .../oauth2/default)

Click Discover. Measured Cloud fetches <issuer>/.well-known/openid-configuration and fills in the endpoints. The issuer in that document must be exactly the one shown. If Okta reports a different issuer, Discover fails and tells you which issuer it found.

Tick Auto-provision new users on first sign-in if people who don't have a Measured Cloud account yet should get one. Leave Enforce unticked for now. Click Save.

4. Test it​

  1. In a private browser window, open https://dq.example.com/login, choose Sign in with SSO and enter your org slug.
  2. Sign in to Okta as an assigned user.
  3. You land in Measured Cloud, signed in.

If you're a super admin or technical admin with an existing password account, link it first: see Link a super admin or technical admin account. Admin accounts are never linked automatically.

When everything works, edit the provider and tick Enforce to turn off password sign-in for your org. Do this only after a super admin has signed in through Okta at least once.

What Measured Cloud reads from Okta​

Measured Cloud asks for the scopes openid email profile and reads these ID token claims:

ClaimUsed for
iss, aud, exp, nonceChecked on every sign-in. iss must equal the configured issuer, aud the client ID, and nonce the value Measured Cloud sent. The token's signature is checked against Okta's published keys.
subThe person's permanent link to this provider.
emailThe account's email address.
email_verifiedMust not be false. An existing Measured Cloud account is matched by email only when it is true.
name (or given_name + family_name)The display name of a new account.
groupsOptional team mapping (below).

Map Okta groups to teams​

Measured Cloud can put people into teams from the groups claim on every sign-in:

  • With a JIT team prefix on the provider (e.g. dq-), each group that starts with the prefix becomes a team the first time someone in it signs in (dq-finance becomes the team Finance), and members are added to it. A new team has no workspace access until a super admin grants it.
  • A team whose external group id equals a group name gets that group's members. Set it with PATCH /api/v1/organizations/{org_id}/teams/{team_id} and {"external_group_id": "<group name>"}.

Only memberships added this way are removed when someone leaves the group. If the claim is missing from a sign-in altogether, nothing is removed.

To send groups:

  • Org authorization server (no server ID): on the app's Sign On tab, edit OpenID Connect ID Token and set Groups claim type to Filter, name groups, and a filter such as Starts with dq- (or Matches regex .*).
  • Custom authorization server: Security → API → Authorization Servers → your server → Claims → Add Claim: name groups, include in ID Token (Always), value type Groups, with a filter.

Map Okta groups to roles​

The same groups claim can also set a person's org role. Edit the provider and add rows under Role mappings: a group name exactly as Okta sends it (for example dq-editors) and the role it grants (viewer, editor, technical admin, or super admin).

Mappings are checked when someone is provisioned and again each time a person linked to this provider signs in:

  • The highest matching role wins. Someone in dq-viewers and dq-editors becomes an editor.
  • A match sets the role. A technical admin who is now only in a group mapped to viewer becomes a viewer at their next sign-in.
  • No match, no change. Someone in none of the mapped groups keeps the provider's Default role for new users the first time, and their current role after that. Mappings never demote a person who matches nothing.
  • Super admin needs an opt-in. A group can grant super admin only after you tick Allow a group to grant super admin. Without it, the provider can't create super admins, and it never changes the role of an existing super admin.
  • The last super admin stays. A mapping never demotes the org's last super admin.

Every role a mapping changes is written to the audit log as org_membership.role_mapped_by_sso, with the actor sso, the old and new role, and the groups that matched. The change applies from the person's next session.

Use groups that only Okta administrators can change. Whoever can add people to a mapped group can grant that role.

Use SAML instead​

Pick Okta (SAML) as the provider. The form shows the ACS URL and the SP entity ID.

In Okta: Applications → Create App Integration → SAML 2.0, then:

Okta fieldValue
Single sign-on URLThe ACS URL from Measured Cloud. Tick Use this for Recipient URL and Destination URL.
Audience URI (SP Entity ID)The SP entity ID from Measured Cloud (your PUBLIC_BASE_URL).
Name ID formatPersistent (or EmailAddress)
Application usernameOkta username or Email
Attribute statementsemail = user.email, given_name = user.firstName, family_name = user.lastName
Group attribute statementsOptional: groups, filter Starts with dq-

Leave the response and assertion signed (Okta's default). After saving, copy the Metadata URL from the app's Sign On tab (https://acme.okta.com/app/<app-id>/sso/saml/metadata), paste it into IdP metadata URL in Measured Cloud and click Fetch. That fills in the entity ID, SSO URL and certificate.

SAML assertions carry no "email verified" signal, so over SAML an existing Measured Cloud account can't be matched by email. SAML signs in people who don't have an account yet (with auto-provisioning on) and people already linked to the provider. If your users already have accounts, use OIDC.

SAML needs the optional dq-cloud-api[saml] install on a self-hosted deployment; see Configure SSO.

Troubleshooting​

SymptomLikely cause
Discover says issuer mismatchThe authorization server ID is wrong or missing. With the org authorization server leave it blank. With API Access Management use the server's ID exactly.
Okta shows redirect_uri errorThe sign-in redirect URI in Okta doesn't match the one Measured Cloud shows, character for character.
sso_error=idp_error after OktaThe client secret is wrong, or the app's Client authentication isn't Client secret. The server log line sso_callback_failed has the detail.
sso_error=email_unverifiedOkta sent email_verified: false for this person, or an existing account was matched over SAML.
sso_error=not_provisionedThe person has no Measured Cloud account and auto-provisioning is off. Invite them, or turn auto-provisioning on.

More codes are listed in Configure SSO.