Integrations · SAML 2.0
Microsoft 365 SSO
Federate Microsoft 365 (Entra ID / Azure AD) with Clavex using SAML 2.0. Users sign in to Teams, Outlook, SharePoint, and every M365 service through Clavex, enabling EU-resident identity with passkeys, eID, and multi-factor authentication.
Architecture: Clavex is the SAML IdP. Entra ID (formerly Azure AD) is
configured as a federated domain — Microsoft redirects all login attempts for your
domain to Clavex. This requires a verified custom domain in Entra ID and
PowerShell or the Microsoft Graph API to set domain federation settings.
Prerequisites
- Microsoft 365 tenant with a verified custom domain (e.g.
acme.eu) - Global Administrator role in Entra ID
- Azure AD PowerShell module (v1 / MSOnline) or Microsoft Graph PowerShell
- Clavex at
https://id.acme.eu, org slugacme
Important: Federated domain setup affects all users on that domain.
Test with a non-production domain or a small pilot group first. Keep a cloud-only break-glass
admin account on
*.onmicrosoft.com at all times.
Step 1 — Collect Clavex IdP Values
$ curl -s https://id.acme.eu/acme/saml/idp/metadata | xmllint --xpath \
"string(//md:IDPSSODescriptor/md:SingleSignOnService/@Location)" -
https://id.acme.eu/acme/saml/sso
# Extract Base64-encoded certificate from metadata $ curl -s https://id.acme.eu/acme/saml/idp/metadata | \ grep -oP '(?<=<ds:X509Certificate>)[^<]+' MIIC... (long base64 string)
# Extract Base64-encoded certificate from metadata $ curl -s https://id.acme.eu/acme/saml/idp/metadata | \ grep -oP '(?<=<ds:X509Certificate>)[^<]+' MIIC... (long base64 string)
| Parameter | Value |
|---|---|
| Issuer URI (Entity ID) | https://id.acme.eu/acme/saml |
| Passive Sign-On URL | https://id.acme.eu/acme/saml/sso |
| Sign-Out URL | https://id.acme.eu/acme/saml/slo |
| Signing certificate | Base64 from metadata |
Step 2 — Set Domain Federation in Entra ID
Use the MSOnline PowerShell module to configure the federated domain:
# Install module if needed
Install-Module MSOnline -Scope CurrentUser
Connect-MsolService
# Replace values with your Clavex IdP details $cert = "MIIC..." # base64 certificate from Clavex metadata (no headers) Set-MsolDomainAuthentication ` -DomainName "acme.eu" ` -Authentication Federated ` -IssuerUri "https://id.acme.eu/acme/saml" ` -PassiveLogOnUri "https://id.acme.eu/acme/saml/sso" ` -SigningCertificate $cert ` -LogOffUri "https://id.acme.eu/acme/saml/slo" ` -PreferredAuthenticationProtocol SAMLP
# Verify Get-MsolDomainFederationSettings -DomainName "acme.eu"
# Replace values with your Clavex IdP details $cert = "MIIC..." # base64 certificate from Clavex metadata (no headers) Set-MsolDomainAuthentication ` -DomainName "acme.eu" ` -Authentication Federated ` -IssuerUri "https://id.acme.eu/acme/saml" ` -PassiveLogOnUri "https://id.acme.eu/acme/saml/sso" ` -SigningCertificate $cert ` -LogOffUri "https://id.acme.eu/acme/saml/slo" ` -PreferredAuthenticationProtocol SAMLP
# Verify Get-MsolDomainFederationSettings -DomainName "acme.eu"
Step 3 — Register Entra ID as SAML SP in Clavex
Microsoft 365 / Entra ID uses a fixed ACS URL and Entity ID for federated domains. Register it in Clavex Admin:
$ curl -X POST https://id.acme.eu/api/v1/organizations/acme/saml/sp \
-H 'Authorization: Bearer $ADMIN_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"entity_id": "urn:federation:MicrosoftOnline",
"acs_url": "https://login.microsoftonline.com/login.srf",
"name_id_format": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"sign_assertions": true,
"sign_response": true,
"encrypt_assertions": false
}'
Step 4 — Test Login
- Open a private browser window and navigate to
https://portal.microsoft.com - Enter a user email with your federated domain:
user@acme.eu - Microsoft detects the federated domain and redirects to Clavex
- After Clavex authentication, the user lands on the Microsoft 365 portal
Claim Mapping
| Entra ID attribute | SAML attribute | Clavex claim |
|---|---|---|
| UPN (required) | NameID (emailAddress format) | email |
| Display Name | http://schemas.microsoft.com/identity/claims/displayname | name |
| First Name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname | given_name |
| Last Name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname | family_name |
| Immutable ID | http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID | sub |
Troubleshooting
| Error code | Meaning | Fix |
|---|---|---|
AADSTS90019 |
No tenant found for domain | Domain not verified in Entra ID; verify domain first |
AADSTS50107 |
Requested federation realm does not exist | Re-run Set-MsolDomainAuthentication with correct -IssuerUri |
| Loop: Entra → Clavex → Entra | ImmutableID / NameID not matching Entra user object | Ensure NameID value matches UserPrincipalName in Entra |
| Certificate validation error | Clavex signing cert changed | Run Set-MsolDomainAuthentication again with new cert |
| Break-glass admin locked out | All admins on federated domain | Use @tenant.onmicrosoft.com cloud-only admin account |