Purpose: Step‑by‑step guide to federate a Microsoft Entra tenant (Azure AD) with Keycloak so users authenticated by Keycloak can access Power BI (Microsoft 365). This guide explains why SAML is required, prerequisites, exact configuration steps (PowerShell + Keycloak), mapper examples, testing checklist, troubleshooting, and references.
Power BI and the Microsoft 365 ecosystem rely on Microsoft Entra (Azure AD) for authentication. You cannot point Power BI directly to Keycloak. Instead, you configure domain-level federation in Entra so that when a user signs into Power BI with user@yourcompany.com, Entra redirects authentication to Keycloak (SAML). After successful authentication Keycloak returns a SAML assertion to Entra, Entra issues tokens for Power BI.
Bottom line: For Power BI → Entra → Keycloak federation, use SAML (SAML 2.0). OIDC is not supported for tenant-level Microsoft 365 sign-ins.

Conclusion: Use SAML for the scenario in this guide.
yourcompany.com).Connect-MsolService/MSOnline (or Microsoft Graph alternative).user@yourcompany.com.Option A — Use Keycloak Admin Console (recommended)
urn:federation:MicrosoftOnline (or a name you choose — the important part is consistent with metadata).samlhttps://login.microsoftonline.com/<TENANT_ID>/saml2emailemail
emailhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress (or simply email)givenName
firstNamegivennamesurname
lastNamesurnamegroups or roles if you need group/role claims passed to Entra..cer — Entra needs the certificate to validate signatures.Option B — Import SAML metadata XML
You can craft an EntityDescriptor XML with correct endpoints and X.509 certificate. Example snippet is provided later in the doc.
Approach 1 — MSOnline PowerShell (classic) — ready to run
Important: Replace placeholders (
<...>) before running. This example uses the MSOnline module andSet-MsolDomainAuthentication.
# Install & connect (run as admin)
Install-Module -Name MSOnline -Force
Connect-MsolService
# Variables - REPLACE these
$domainName = "yourcompany.com"
$keycloakHost = "auth.kc.example.com" # no trailing slash
$realm = "yourrealm"
$federationName = "KeycloakFederation"
$signingCertPath = "C:\temp\keycloak-signing.cer" # Exported X.509 public cert
# Read certificate into Base64 string
$certBytes = [System.IO.File]::ReadAllBytes($signingCertPath)
$base64Cert = [System.Convert]::ToBase64String($certBytes)
# Passive / Active login URIs (SAML endpoints in Keycloak)
$passiveLogOnUri = "https://$keycloakHost/realms/$realm/protocol/saml"
$activeLogOnUri = "https://$keycloakHost/realms/$realm/protocol/saml"
$issuerUri = "https://$keycloakHost/realms/$realm"
$logOffUri = "https://$keycloakHost/realms/$realm/protocol/saml/logout"
# Apply federation to domain
Set-MsolDomainAuthentication `
-DomainName $domainName `
-FederationBrandName $federationName `
-Authentication Federated `
-PassiveLogOnUri $passiveLogOnUri `
-ActiveLogOnUri $activeLogOnUri `
-IssuerUri $issuerUri `
-LogOffUri $logOffUri `
-SigningCertificate $base64Cert
# Verify
Get-MsolDomainFederationSettings -DomainName $domainName | Format-List
Notes:
Set-MsolDomainAuthentication, or your organization prefers modern modules, use the Microsoft Graph PowerShell or the AzureAD module. I can provide an equivalent script on request.PassiveLogOnUri and ActiveLogOnUri are typically the same Keycloak SAML endpoint.Approach 2 — Entra Admin Center (UI)
https://<KEYCLOAK_HOST>/realms/<REALM_NAME>/protocol/saml/descriptor).Choose based on lifecycle management and compliance requirements.
yourcompany.com.Set-MsolDomainAuthentication and verify with Get-MsolDomainFederationSettings.https://login.microsoftonline.com with user@yourcompany.com — expect redirect to Keycloak.email, givenname, surname.https://app.powerbi.com and confirm successful sign-in and access.NotBefore/NotOnOrAfter windows, and correct Audience/Issuer values.email and the value matches the Entra UPN.Issuer in SAML equals the value Entra expects.Replace placeholders and insert your base64 X.509 certificate in the
<X509Certificate>node.
<EntityDescriptor entityID="https://auth.kc.example.com/realms/yourrealm" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>
MIID...base64 certificate...
</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://auth.kc.example.com/realms/yourrealm/protocol/saml"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://auth.kc.example.com/realms/yourrealm/protocol/saml"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://auth.kc.example.com/realms/yourrealm/protocol/saml/logout"/>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
</IDPSSODescriptor>
</EntityDescriptor>
(Use the official Microsoft Learn pages and Keycloak docs as the authoritative source.)
End of document.