Skip to content

Single Sign On

Info

Atfinity officially supports SAML via Azure Active Directory. Other providers, and OpenID Connect, may work, but have not been tested.

Atfinity can use SAML or OpenID Connect to authenticate users with your identity provider. To set up Single Sign On, you need access to the Server itself, so this is only available for Enterprise customers or customers using Atfinity deployed on their own premises using our Kubernetes Helm Chart.

Single Sign On never creates users. A user can sign in only when they are an existing user who is active, not locked and not past their valid until date. SAML finds them by their email address, ignoring upper and lower case. The first OpenID Connect sign-in of a user finds them by an email address that matches theirs apart from the case of the letters A to Z, so an address that differs by an accent does not match, and later OpenID Connect sign-ins find them by their link to the identity provider, as described in Recognising Users. The valid until date does not apply to a user provisioned from Entra ID while provisioning is on. A refused user returns to the login page with an error, and the refusal is recorded in the user access log. OpenID Connect replaces SAML while it is enabled, and Atfinity's own two-factor authentication is skipped for both.

Getting Started with SAML

In general, you need a url to your identification providers federation metadata to get started

Single Sign On creates no users. It logs in the user whose email address matches the one the identity provider sends, so the user has to exist in Atfinity already, for example created by an administrator or provisioned from Entra ID through SCIM.

Getting Started

If you are running Atfinity using Docker Compose, you need to set up these environment variables:

SSO_ENABLED Boolean
SSO_NAME String The name displayed to users when logging in, e.g. "MyBank Active Directory"
SSO_METADATA_URL String The url to your identification provers federation metadata. This should point to a hosted .xml file containing the service metadata. Usually, these urls end in "federationmetadata.xml"

If you are running Atfinity using our Kubernetes Helm Chart, you have to configure the same values, but provide them as extra Values in the helm chart. The values are called sso.enabled, sso.name and sso.metadataUrl.

Getting Started with OpenID Connect

Info

New in Atfinity 18.

Register Atfinity with your identity provider using the redirect URI https://<your base url>/auth/oidc/callback/. The provider has to support the authorization code flow with PKCE, sign its ID tokens with RS256 and return an email claim. Its discovery document has to list a userinfo_endpoint. Atfinity reads the userinfo on every sign-in and refuses it when the sub there differs from the one in the ID token.

If you are running Atfinity using Docker Compose, you need to set up these environment variables:

OIDC_ENABLED Boolean
OIDC_PROVIDER_NAME String The name shown on the login button, e.g. "MyBank Entra ID"
OIDC_ISSUER_URL String The issuer URL of your provider. It has to match the issuer in the provider's discovery document exactly
OIDC_CLIENT_ID String
OIDC_CLIENT_SECRET String
OIDC_REQUIRE_VERIFIED_EMAIL Boolean Refuses to find a user by email address unless the provider confirms it in the claim named below. A user already linked to their provider account signs in regardless. Off by default
OIDC_EMAIL_VERIFIED_CLAIM String The claim that holds that confirmation, e.g. "email_verified". Required when the setting above is on, or the server does not start

If you are running Atfinity using our Kubernetes Helm Chart, the values are called oidc.enabled, oidc.providerName, oidc.issuerUrl, oidc.clientId, oidc.requireVerifiedEmail and oidc.emailVerifiedClaim. The client secret is not a value. Store it in a Kubernetes secret under the key OIDC_CLIENT_SECRET, and name that secret in oidc.clientSecretName. Create the secret before you set oidc.enabled: while it does not exist, the API pod does not start and password login is down with it. If the secret exists without the OIDC_CLIENT_SECRET key, the API starts and logs a warning, and every sign-in fails when Atfinity exchanges the authorization code. Restart the API after you change any of these values or the secret.

Recognising Users

The first OpenID Connect sign-in of a user finds them by email address and links them to the sub your provider sends, under its issuer and the client ID. Every later sign-in finds the user by that link, so a user whose email address changes in your provider keeps signing in to the same account. A sign-in with the email address of a linked user but another sub is refused, as it usually means the address now belongs to someone else.

A new issuer or client ID links each user again by email address on their next sign-in. This happens when you register Atfinity with your provider again or copy a database to an environment with its own registration.

When a user is refused after their account was recreated in your provider, confirm it is the same person and remove their link inside the API container:

cd api && python manage.py forget_single_sign_on_identities <email>

--all instead of an email address removes the links of every user, for example after you rebuild the users in your provider. Removing a link is recorded in the user access log and leaves the user signed in, with their AI clients still authorised. The next sign-in links them by email address again. When the wrong person was linked to an account, lock or deactivate the user instead, as removing their link would let the next sign-in with that email address link them again.

Roles and Groups

Roles, groups and admin rights come from a claim your identity provider sends, mapped per tenant under External directory in the administration. SAML and OpenID Connect have a tab each with the same settings.

With Load roles and groups on login off, a user keeps the roles and groups assigned in Atfinity. A user without a role is then refused, with the message a password login without permissions shows, unless they are an administrator. Load roles and groups on login cannot be on while roles come from Entra ID app roles. With it on, each login replaces the roles and groups of the user and grants admin rights:

  • The user is refused unless the claim contains the application access group. A tenant without one refuses everyone.
  • A value that matches a user group assigns that group, and any other value that matches a role assigns that role.
  • A value that matches the admin group makes the user an admin.
  • The user is refused when no value matches a role and none grants admin access.

A login never withdraws admin rights. A user who is removed from the admin group in your identity provider stays an admin in Atfinity until an administrator changes their access level in Atfinity.

With OpenID Connect, Atfinity reads the claim from the userinfo endpoint and falls back to the ID token. A group list the provider reports as truncated is refused.