SAML2 and Microsoft Entra

SAML2 and Microsoft Entra

Overview

Syndeia Cloud supports Microsoft (MS) Entra out-of-the-box. This page will illustrate how to configure MS Entra as a SAML2 IdP (Identity Provider) and Syndeia Cloud as the SP (Service Provider). MS Entra was formerly known as MS Azure Active Directory (or Azure AD).

Requirements

(1) MS Entra service subscription

(2) Access to an admin account to MS Entra with the following Roles:

image-20260520-232018.png

(3) A Syndeia Cloud 3.6+ server deployed (FQDN + protocol + port should be known)

  • Check this URL in a web-browser and the SC Web Dashboard should come up. If not, then there is an issue with Syndeia Cloud.

Steps

MS Entra ID : Creating a new Syndeia Cloud application definition

(1) Login to MS Entra and navigate to Enterprise Apps in the sidebar on the left.

(2) Click the + New Application button

image-20250716-175015.png
Fig. 1 : MS Entra admin center > Enterprise apps > All applications

(3) Click + Create your own application button

image-20250716-175221.png
Fig. 2 : + New Application wizard: Create your own application button

(4) Type “Syndeia Cloud” and the “Integrate any other application you don't find in the gallery (Non-gallery)“ radio button.

image-20250716-175455.png
Fig. 3: Create your own application wizard

(5) Click the Create button at the bottom

image-20250716-175541.png

(6) You will now see a list of sections on the left side. Select Single sign-on.

image-20260527-211500.png
Fig. 4: Select Single sign-on

(7) Change the single sign-on method from Disabled to SAML:

image-20250716-175809.png
Fig. 5: Select SAML for Single Sign-on (SSO) Method

(8) You will now be presented with the following 5 sections of configuration parameters that need to be set:

image-20250716-180047.png
Fig. 6: Setup SSO with SAML
  1. ❶ (section 1): Click the Edit button and fill out the first 3 fields:
    - Identifier (Entity ID)
    - Reply URL (Assertion Consumer Service URL)
    - Sign on URL
    … like the below, replace mySCserver.domain.tld with the FQDN for your Syndeia Cloud (SC) server.
    Note, in this example we assume your SC server is called mySCserver.domain.tld and uses HTTPS on port 9443, ie: https://sc.domain.com:9443, modify appropriately if not.

    image-20250716-180214.png
    Fig. 7: Basic SAML Configuration
  2. ❷ (section 2): Skip

  3. ❸ (section 3): Do not change anything here and just click the Download link next to the Certificate (Base64) field. This will download MS Entra’s IdP certificate (it will be used later in the next section)

  4. You have now finished configuring the MS Entra (ID) side of the SAML2 configuration. Next, we will need to configure Syndeia Cloud (SC) to match these settings.

Syndeia Cloud : Configure Syndeia Cloud to work with MS Entra via SAML2

(1) SSH into the Syndeia Cloud server.

(2) Open /opt/icx/syndeia-cloud-current/web-gateway-3.7/conf/silhouette.conf on the server for editing.

If you have deployed the containerized version of Syndeia Cloud, this path will be /opt/icx/syndeia-cloud-3.7-docker/config/sc_service_configs/web-gateway/silhouette.conf instead

(3) Scroll down to the SAML2 section settings begin (around ~L149), it should look like the following snippet below:

image-20260527-190914.png
Fig. 8: SAML2 section in silhouette.conf
# SAML2 Provider # These settings are intentionally similar to what OneLogin needs for SAML2 # Service Providers and Identity Providers # Compression settings. Note that these are determined by OASIS Standard for SAML2 # false => Base64 encoded, true => Deflated Base64 encoded (which is compressed) # saml2.compress.request = true # saml2.compress.response = true # saml2.security.authnrequest_signed = true # saml2.security.want_messages_signed = true # saml2.security.want_assertions_signed = true # saml2.security.want_xml_validation = true # saml2.security.signature_algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" # saml2.security.requested_authncontext = "exact" # CAC/PIV authentications might need something like this, which is IdP-specific # saml2.security.requested_authncontext = "http://idmanagement.gov/ns/assurance/aal/3?hspd12=true" # Identifier of the SP entity (must be a URI) # saml2.sp.entityid = "http://MYSP.COM:SPPORT" # Specifies info about where and how the <AuthnResponse> message MUST be # returned to the requester, in this case our SP. # URL Location where the <Response> from the IdP will be returned # saml2.sp.assertion_consumer_service.url = "http://MYSP.com:SPPORT/authenticate/SAML2" # SAML protocol binding to be used when returning the <Response> # message. Onelogin Toolkit supports for this endpoint the # HTTP-POST binding only # saml2.sp.assertion_consumer_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # Specifies info about where and how the <Logout Response> message MUST be # returned to the requester, in this case our SP. # saml2.sp.single_logout_service.url = "http://MYSP.com:SPPORT/authenticate/SAML2" # SAML protocol binding to be used when returning the <LogoutResponse> or sending the <LogoutRequest> # message. Onelogin Toolkit supports for this endpoint the # HTTP-Redirect binding only # saml2.sp.single_logout_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # Specifies constraints on the name identifier to be used to # represent the requested subject. # Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported # saml2.sp.nameidformat = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" # Usually x509cert and privateKey of the SP are provided by files placed at # the certs folder. But we can also provide them with the following parameters # saml2.sp.x509cert = "-----BEGIN CERTIFICATE-----BIGLONGSPPUBLICCERTSTRING-----END CERTIFICATE-----" # Requires Format PKCS#8 BEGIN PRIVATE KEY # If you have PKCS#1 BEGIN RSA PRIVATE KEY convert it by openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem # saml2.sp.privatekey = "-----BEGIN PRIVATE KEY-----BIGLONGSPPRIVATECERTSTRING-----END PRIVATE KEY-----" # Identifier of the IdP entity (must be a URI) # saml2.idp.entityid = "http://OURIDP.COM:IDPPORT/SAMLIDP" # SSO endpoint info of the IdP. (Authentication Request protocol) # URL Target of the IdP where the SP will send the Authentication Request Message # saml2.idp.single_sign_on_service.url = "https://OURIDP.COM:IDPPORT/SSOPATH" # saml2.idp.single_sign_on_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # Instead of using the whole x509cert you can use a fingerprint in order to # validate a SAMLResponse (but you still need the x509cert to validate LogoutRequest and LogoutResponse using the HTTP-Redirect binding). # But take in mind that the fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass, # that why we don't recommend it use for production environments. # (openssl x509 -noout -fingerprint -in "idp_crt" to generate it, # or add for example the -sha256 , -sha384 or -sha512 parameter) # If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to # let the toolkit know which Algorithm was used. Possible values: sha1, sha256, sha384 or sha512 # 'sha1' is the default value. #saml2.idp.certfingerprint = "1234" #saml2.idp_certfingerprint_algorithm = "sha1" # saml2.idp.x509cert = "-----BEGIN CERTIFICATE-----BIGLONGIDPPUBLICCERTSTRING-----END CERTIFICATE-----" # These are the property keys used to retrieve Social Identity information from the SAML2 Response which an IdP # sends back to an SP. The names of the keys are standardized but are configurable here to support internationalization # and quirks by IdP vendors like Microsoft # saml2.social.attribute.key.uid = "uid" # saml2.social.attribute.key.firstname = "first_name" # saml2.social.attribute.key.lastname = "last_name" # saml2.social.attribute.key.fullname = "fullname" # saml2.social.attribute.key.email = "email" }

(4) Configure it using the values configured earlier from MS Entra as shown below, where mySCserver.domain.tld is the FQDN for your Syndeia Cloud (SC) server :

image-20260527-193801.png
Fig. 9: MS Entra (ID) Syndeia Cloud | SAML-based Sign on settings page
  1. Section :

    1. saml2.sp.entityid: Uncomment and change the value from http://MYSP.COM:SPPORT to https://mySCserver.domain.tld:9443, ie: your SC protocol, FQDN & port

    2. saml2.idp.entityid: Uncomment and change the value saml2.sp.assertion_consumer_service.url from http://MYSP.com:SPPORT to https://mySCserver.domain.tld:9443, ie: your SC protocol, FQDN & port

  2. Section

    1. saml2.social.attribute.key.uid : Uncomment and change the value from uid to user.userprincipalname

    2. saml2.social.attribute.key.firstname : Uncomment and change the value from first_name to user.givenname

    3. saml2.social.attribute.key.lastname : Uncomment and change the value from last_name to user.surname

    4. saml2.social.attribute.key.fullname : Uncomment (and keep the same value of fullname)

    5. saml2.social.attribute.key.email : Uncomment and change the value from email to user.mail

  3. Section

    1. saml2.idp.single_sign_on_service.url : Uncomment and change the value from https://OURIDP.COM:IDPPORT/SSOPATH to https://login.microsoftonline.com/yourEntityID /saml2

    2. saml2.idp.entityid : Uncomment and change the value from http://OURIDP.COM:IDPPORT/SAMLIDP to https://sts.windows.net/yourEntityID

  4. The remainder of the configuration steps do not require referencing the MS Entra (ID) website and are all done in silhouette.conf.

    1. saml2.security.want_messages_signed : Change the value from true to false

    2. saml2.security.signature_algorithm : Change the value from http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 to sha1

    3. saml2.security.* : Uncomment the first 5 lines ONLY, it should now look like the below:

      image-20260527-212243.png
      Fig. 10: saml2.security.* settings in silhouette.conf
    4. saml2.sp.assertion_consumer_service.binding : Uncomment (the value should already be set to "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")

    5. saml2.sp.single_logout_service.url : Uncomment and change the value from http://MYSP.com:SPPORT to https://mySCserver.domain.tld:9443, ie: your SC protocol, FQDN & port

    6. saml2.sp.single_logout_service.binding : Uncomment (the value should already be set to "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")

    7. saml2.sp.nameidformat : Uncomment (the value should already be set to "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")

    8. saml2.sp.x509cert : Uncomment and set the value to the 1-line, concatenated, base64-encoded .PEM certificate text used by the SP, it should look something like the below:

      image-20260527-215340.png
      Fig. 11: saml2.xp.x509cert 1-line, base64-encoded PEM certificate example
    9. saml2.sp.privatekey : Uncomment and set the value to the 1-line, concatenated, base64-encoded .PEM private key (this is your private key corresponding to the certificate set in saml2.sp.x509cert)

    10. saml2.idp.single_sign_on_service.binding : Uncomment (the value should already be set to "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" )

    11. saml2.idp.x509cert : Uncomment and set the value to the 1-line, concatenated, base64-encoded .PEM certificate used by IdP, ie: MS Entra
      Note, this is the certificate you downloaded in step 11 from the previous section earlier.

158,162c158,162 < # saml2.security.authnrequest_signed = true < # saml2.security.want_messages_signed = true < # saml2.security.want_assertions_signed = true < # saml2.security.want_xml_validation = true < # saml2.security.signature_algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" --- > saml2.security.authnrequest_signed = true > saml2.security.want_messages_signed = false > saml2.security.want_assertions_signed = true > saml2.security.want_xml_validation = true > saml2.security.signature_algorithm = "sha1" 169c169 < # saml2.sp.entityid = "http://MYSP.COM:SPPORT" --- > saml2.sp.entityid = "https://mySCserver.domain.tld:9443" 174c174 < # saml2.sp.assertion_consumer_service.url = "http://MYSP.com:SPPORT/authenticate/SAML2" --- > saml2.sp.assertion_consumer_service.url = "https://mySCserver.domain.tld:9443/authenticate/SAML2" 179c179 < # saml2.sp.assertion_consumer_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" --- > saml2.sp.assertion_consumer_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 183c183 < # saml2.sp.single_logout_service.url = "http://MYSP.com:SPPORT/authenticate/SAML2" --- > saml2.sp.single_logout_service.url = "https://mySCserver.domain.tld:9443/authenticate/SAML2" 188c188 < # saml2.sp.single_logout_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" --- > saml2.sp.single_logout_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 193c193 < # saml2.sp.nameidformat = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" --- > saml2.sp.nameidformat = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" 197c197 < # saml2.sp.x509cert = "-----BEGIN CERTIFICATE-----BIGLONGSPPUBLICCERTSTRING-----END CERTIFICATE-----" --- > saml2.sp.x509cert = "-----BEGIN CERTIFICATE----- <insert 1-line concatenated base64-encoded .PEM certificate used for SP here> -----END CERTIFICATE-----" 201c201 < # saml2.sp.privatekey = "-----BEGIN PRIVATE KEY-----BIGLONGSPPRIVATECERTSTRING-----END PRIVATE KEY-----" --- > saml2.sp.privatekey = "-----BEGIN PRIVATE KEY----- <insert 1-line concatenated base64-encoded .PEM private key corresponding to saml2.sp.x509cert here> -----END PRIVATE KEY-----" 204c204 < # saml2.idp.entityid = "http://OURIDP.COM:IDPPORT/SAMLIDP" --- > saml2.idp.entityid = "https://sts.windows.net/3d857c53-2b19..../" 208c208 < # saml2.idp.single_sign_on_service.url = "https://OURIDP.COM:IDPPORT/SSOPATH" --- > saml2.idp.single_sign_on_service.url = "https://login.microsoftonline.com/3d857c53-2b19..../saml2" 210c210 < # saml2.idp.single_sign_on_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" --- > saml2.idp.single_sign_on_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 225c225 < # saml2.idp.x509cert = "-----BEGIN CERTIFICATE-----BIGLONGIDPPUBLICCERTSTRING-----END CERTIFICATE-----" --- > saml2.idp.x509cert = "-----BEGIN CERTIFICATE----- <insert 1-line concatenated base64-encoded .PEM certifcate used by your IdP here> -----END CERTIFICATE-----" 230,235c230,235 < # saml2.social.attribute.key.uid = "uid" < # saml2.social.attribute.key.firstname = "first_name" < # saml2.social.attribute.key.lastname = "last_name" < # saml2.social.attribute.key.fullname = "fullname" < # saml2.social.attribute.key.email = "email" < } --- > saml2.social.attribute.key.uid = "user.userprincipalname" > saml2.social.attribute.key.firstname = "user.givenname" > saml2.social.attribute.key.lastname = "user.surname" > saml2.social.attribute.key.fullname = "fullname" > saml2.social.attribute.key.email = "user.mail" > } \ No newline at end of file
# SAML2 Provider # These settings are intentionally similar to what OneLogin needs for SAML2 # Service Providers and Identity Providers # Compression settings. Note that these are determined by OASIS Standard for SAML2 # false => Base64 encoded, true => Deflated Base64 encoded (which is compressed) # saml2.compress.request = true # saml2.compress.response = true saml2.security.authnrequest_signed = true saml2.security.want_messages_signed = false saml2.security.want_assertions_signed = true saml2.security.want_xml_validation = true saml2.security.signature_algorithm = "sha1" # saml2.security.requested_authncontext = "exact" # CAC/PIV authentications might need something like this, which is IdP-specific # saml2.security.requested_authncontext = "http://idmanagement.gov/ns/assurance/aal/3?hspd12=true" # Identifier of the SP entity (must be a URI) saml2.sp.entityid = "https://mySCserver.domain.tld:9443" # Specifies info about where and how the <AuthnResponse> message MUST be # returned to the requester, in this case our SP. # URL Location where the <Response> from the IdP will be returned saml2.sp.assertion_consumer_service.url = "https://mySCserver.domain.tld:9443/authenticate/SAML2" # SAML protocol binding to be used when returning the <Response> # message. Onelogin Toolkit supports for this endpoint the # HTTP-POST binding only saml2.sp.assertion_consumer_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # Specifies info about where and how the <Logout Response> message MUST be # returned to the requester, in this case our SP. saml2.sp.single_logout_service.url = "https://mySCserver.domain.tld:9443/authenticate/SAML2" # SAML protocol binding to be used when returning the <LogoutResponse> or sending the <LogoutRequest> # message. Onelogin Toolkit supports for this endpoint the # HTTP-Redirect binding only saml2.sp.single_logout_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # Specifies constraints on the name identifier to be used to # represent the requested subject. # Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported saml2.sp.nameidformat = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" # Usually x509cert and privateKey of the SP are provided by files placed at # the certs folder. But we can also provide them with the following parameters saml2.sp.x509cert = "-----BEGIN CERTIFICATE----- <insert 1-line concatenated base64-encoded .PEM certificate used for here> -----END CERTIFICATE-----" # Requires Format PKCS#8 BEGIN PRIVATE KEY # If you have PKCS#1 BEGIN RSA PRIVATE KEY convert it by openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem saml2.sp.privatekey = "-----BEGIN PRIVATE KEY----- <insert 1-line concatenated base64-encoded .PEM private key corresponding to saml2.sp.x509cert here> -----END PRIVATE KEY-----" # Identifier of the IdP entity (must be a URI) saml2.idp.entityid = "https://sts.windows.net/3d857c53-2b19..../" # SSO endpoint info of the IdP. (Authentication Request protocol) # URL Target of the IdP where the SP will send the Authentication Request Message saml2.idp.single_sign_on_service.url = "https://login.microsoftonline.com/3d857c53-2b19..../saml2" saml2.idp.single_sign_on_service.binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # Instead of using the whole x509cert you can use a fingerprint in order to # validate a SAMLResponse (but you still need the x509cert to validate LogoutRequest and LogoutResponse using the HTTP-Redirect binding). # But take in mind that the fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass, # that why we don't recommend it use for production environments. # (openssl x509 -noout -fingerprint -in "idp_crt" to generate it, # or add for example the -sha256 , -sha384 or -sha512 parameter) # If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to # let the toolkit know which Algorithm was used. Possible values: sha1, sha256, sha384 or sha512 # 'sha1' is the default value. #saml2.idp.certfingerprint = "1234" #saml2.idp_certfingerprint_algorithm = "sha1" saml2.idp.x509cert = "-----BEGIN CERTIFICATE----- <insert 1-line concatenated base64-encoded .PEM certifcate used by your IdP here> -----END CERTIFICATE-----" # These are the property keys used to retrieve Social Identity information from the SAML2 Response which an IdP # sends back to an SP. The names of the keys are standardized but are configurable here to support internationalization # and quirks by IdP vendors like Microsoft saml2.social.attribute.key.uid = "user.userprincipalname" saml2.social.attribute.key.firstname = "user.givenname" saml2.social.attribute.key.lastname = "user.surname" saml2.social.attribute.key.fullname = "fullname" saml2.social.attribute.key.email = "user.mail" }

(5) Once all settings are configured, save the file & restart the sc-web-gateway service, ie:

sudo systemctl restart sc-web-gateway

(6) To test, go to the Syndeia Web Dashboard login page and click the Single Sign On (SSO) button

image-20250717-005131.png
Fig. 12: Syndeia Cloud login form

(7) You should be redirected to MS Entra (ID) IdP page to login.

image-20260527-221651.png
Fig. 13: MS Entra (ID) login form

(8) Once you login, you will be redirected back to the Syndeia Web Dashboard :

image-20260527-222916.png
Fig. 14: Syndeia Cloud Web Dashboard