Integrate SSO
important
Before starting the SSO integration, request the IdP metadata (file or URL) from the security team.
SAML 2.0
Security Assertion Markup Language (SAML) is an XML-based, open-standard data format for exchanging authentication and authorization data between parties, in particular, between an identity provider (IdP) and a service provider (SP).
The SAML specification defines three roles:
- the principal (typically a user)
- the identity provider (IdP)
- the service provider (SP)
In the use case addressed by SAML, the principal requests a service from the service provider. The service provider requests and obtains an identity assertion from the identity provider. On the basis of this assertion, the service provider can make an access control decision, that means it can decide, whether or not to perform some service for the connected principal.
Before delivering the identity assertion to the SP, the IdP can request some information from the principal – such as a user name and password – in order to authenticate the principal. SAML specifies the assertions between the three parties: in particular, the messages that assert identity that are passed from the IdP to the SP. In SAML, one identity provider may provide SAML assertions to many service providers. Similarly, one SP may rely on and trust assertions from many independent IdPs.
SAML does not specify the method of authentication at the identity provider; it may use a username and password, or other form of authentication, including multi-factor authentication. A directory service such as LDAP, RADIUS, or Active Directory that allows users to log in with a user name and password is a typical source of authentication tokens at an identity provider. [3] The popular Internet social networking services also provide identity services that in theory could be used to support SAML exchanges.
Java Key Store
A private key that is used for SSO integration is stored in the Java Key Store (jsk). The same jsk is used for storing trusted customers' certificates for IdP.
The location of Java Key Store itself is configured in the following parameters in group_vars/all/vars.yml:
jks_path={{ common_ssl_dir }}/{{ jks_filename }}.common_ssl_dir={{ install_dir }}/ssl.{{ install_dir }}= by default, /opt/workfusion.jks_filename= by default, wf_saml_integration.jks.
note
For high-availability and disaster recovery installation:
If you have to change or update Java Key Store and its content, remember to make these changes in all instances, where Control Tower or Workspace are installed, for example, ct1 and ct2.
Use case
SAML Web Browser SSO (Service Provider initiated authentication):

Request the target resource at the SP.
The principal (via an HTTP user agent) requests a target resource at the service provider:
https://sp.example.com/myresource
The service provider performs a security check on behalf of the target resource. If a valid security context at the service provider already exists, skip steps 2–7.
Redirect to the SSO Service at the IdP.
The service provider determines the user's preferred identity provider (by unspecified means) and redirects the user agent to the SSO Service at the identity provider:
https://idp.example.org/SAML2/SSO/Redirect?SAMLRequest=request
The value of the
SAMLRequestparameter is the Base64 encoding of a deflated<samlp:AuthnRequest>element.Request the SSO Service at the IdP.
The user agent issues a GET request to the SSO service at the identity provider where the value of the
SAMLRequestparameter is taken from the URL query string at step 2. The SSO service processes theAuthnRequestand performs a security check. If the user does not have a valid security context, the identity provider identifies the user (details omitted).Respond with an XHTML form.
The SSO service validates the request and responds with a document containing an XHTML form:
<form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLResponse" value="response" /> ... <input type="submit" value="Submit" /> </form>The value of the
SAMLResponseparameter is the base64 encoding of a<samlp:Response>element.Request the Assertion Consumer Service at the SP.
The user agent issues a POST request to the assertion consumer service at the service provider. The value of the
SAMLResponseparameter is taken from the XHTML form at step 4.Redirect to the target resource.
The assertion consumer service processes the response, creates a security context at the service provider and redirects the user agent to the target resource.
Request the target resource at the SP again
The user agent requests the target resource at the service provider (again):
Respond with requested resource.
Since a security context exists, the service provider returns the resource to the user agent.
Control Tower SAML Integration
Security profiles
The following security profiles for SAML are supported:
- PKIX. The java.security.cert package is utilized for assertion and validation of the certificates. It implements RFC 5280.
- MetaIOP. Trusted certificates are not mandatory. Other mechanisms are used for validation (for example, explicitly supplying the keys to trust).
The desired profile is specified in the SAML metadata file.
Related documentation:
Configuring SAML Extension. Security profiles
Application Properties
<TOMCAT_HOME>/conf/workfusion.properties
| Property Name | Value | Description |
|---|---|---|
wf.sso.saml.enable | true | Enables or disables SSO (SAML 2.0 protocol) authentification for Control Tower. Accepted values: true/false |
wf.sso.saml.entity.base.url | https://workfusion-lb.example.com/workfusion | Base URL of Control Tower (Service Provider). Used in SP metadata. (see Service Provider metadata example) |
wf.sso.saml.response.skew | 60 | Maximum difference between local time and time of the assertion creation which still allows message to be processed. Basically determines maximum difference between clocks of the IDP and SP machines. Defaults to 60 (seconds) |
| wf.sso.saml.keystore.file.path | {{ jks_path }} | The location, where the file Java Key Store (jsk) with the private keys is stored. By default, INSTALL_DIR/ssl/wf_saml_integration.jks. The location and the name are configured in group_vars/all/vars.yml, in parameters common_ssl_dir (here, INSTALL_DIR/ssl) and jks_filename (here, wf_saml_integration.jks) |
workfusion.properties sample
# option to enable/disable SSO authentication
wf.sso.saml.enable=true
# base url used during generation SP metadata
wf.sso.saml.entity.base.url=https://workfusion-lb.example.com/workfusion
# response skew in seconds
wf.sso.saml.response.skew=60
# The location, where the file Java Key Store (jsk) with the private keys is stored. jks_path = {{ common_ssl_dir }}/{{ jks_filename }} , where common_ssl_dir = {{ install_dir }}/ssl, jks_filename = wf_saml_integration.jks. All locations are configured in group_vars/all/vars.yml.
wf.sso.saml.keystore.file.path={{ jks_path }}
Secure Properties
These properties are placed to Secure Storage.
| Property Name | Value | Description |
|---|---|---|
wf.sso.saml.idp.file.metadata | /path/to/local/meta | Local path to a file with IdP metadata parameters. |
wf.sso.saml.idp.metadata | https://SAML_SERVICE_URL/idp/sso | URL that points to a file with IdP metadata parameters. Must be provided by a customer. This parameter is an alternative to |
wf.sso.saml.sp.metadata | workfusion-metadata-id | A unique string. ID of Service Provider. |
wf.sso.saml.username.attribute | uid | Name of attribute that will be used for authentication.
Must be provided by customer. |
wf.sso.saml.metadata.admin.username | workfusion | The username to log in to the https://workfusion-lb.example.com/workfusion/saml/web/metadata/login endpoint. Used for administering metadata. |
wf.sso.saml.metadata.admin.password | 'At#d!at****' | The password to log in to the https://workfusion-lb.example.com/workfusion/saml/web/metadata/login endpoint. Used for administering metadata. |
wf.sso.saml.keystore.password | {{ jks_pass }} | The password to the Java Key Store file is generated during the installation and is recorded to Vault. You can read the password with the command ./loader.sh ansible review. |
wf.sso.saml.keystore.keys.default | {{ jks_alias }} | A human-friendly name for a private key that is stored in Java Key Store. JKS can store several keys with aliases that are assigned to each one. The alias is configured in group_vars/all/vars.yml. |
wf.sso.saml.keystore.keys.map | {"{{ jks_alias }}":"{{ jks_pass }}"} | The property to read the alias of a private key from the JKS file. |
Secure Storage sample properties
# url to IdP metadata, use url or file
#wf.sso.saml.idp.metadata=none
# path to IdP metadata file
wf.sso.saml.idp.file.metadata=/path/to/local/metadata
# some unique name
wf.sso.saml.sp.metadata=wf-sp-hostname
# the name of an attribute taken from IdP response that contains username
wf.sso.saml.username.attribute=uid
# Credentials to log in to https://workfusion-lb.example.com/workfusion/saml/web/metadata endpoint. Used for metadata administration.
wf_sso_saml_metadata_admin_user: workfusion
# Credentials to log in to https://workfusion-lb.example.com/workfusion/saml/web/metadata endpoint. Used for metadata administration.
wf_sso_saml_metadata_admin_pass: '********'
# The password to the Java Key Store file
wf.sso.saml.keystore.password={{ jks_pass }}
# A human-friendly name for a private key that is stored in Java Key Store
wf.sso.saml.keystore.keys.default={{ jks_alias }}
# The property to read the alias of a private key from the JKS file
wf.sso.saml.keystore.keys.map={"{{ jks_alias }}":"{{ jks_pass }}"}
Service Provider metadata example
For example Control Tower is installed and available by URL https://workfusion-lb.example.com/workfusion.
Metadata for this Service Provider can be generated and downloaded by URL https://workfusion-lb.example.com/workfusion/saml/metadata.
SP metadata example
<EntityDescriptor/> has attributes with Service Provider ID and entityID. These attributes are configured through property wf.sso.saml.sp.metadata.
Identity Provider metadata example
Usually IdP metadata is provided by a security team. It can be a file or URL.
The file should be placed on the application server (SP) and be
accessible for Service Provider (Control Tower). It is configured via
the property wf.sso.saml.idp.file.metadata.
If URL provided, it can be configured via wf.sso.saml.idp.metadata.
Both properties wf.sso.saml.idp.file.metadata and
wf.sso.saml.idp.metadata cannot be configured at the same time.
Show IdP metada example
<IDPSSODescriptor/> must contain information about login/logout endpoints: SingleSignOnService, SingleLogoutService, and attributes' description – saml:Attribute.
<saml:Attribute/> is the username attribute name and must be mapped
via wf.sso.saml.username.attribute/ws.sso.saml.username.attribute in
Secure Storage. (for example, wf.sso.saml.username.attribute=ACCOUNT).
The value of this mapped attribute in IdP response will be used for
authorization.
Identity Provider Authentication Response
After a user logs in on the IdP side, the server sends a response to SP
(CT/WS) and this response must include username attributes configured (if not encrypted)
in wf.sso.saml.username.attribute or ws.sso.saml.username.attribute.
How to decrypt SAML Response
To catch SamlResponse from IdP, use a debuger (press F12 to open it) in your browser
and then try to login . Then select the SSO name among all names of the
Network tab and there will be present decoded SamlResponse. Copy this
value and decode it using https://www.samltool.com/decode.php tool.
- Example of the IdP response with not encrypted data:

The Destination attribute in Response must contain an URL that leads
to the <AssertionConsumerService/> tag into SP metadata.
The <saml:Audience/> tag from <saml:AudienceRestriction/> must
contain a value of wf.sso.saml.sp.metadata/ws.sso.saml.sp.metatdata from vault
(depends on component you are configuring SSO for).
<saml:AtributeValue> is "someusername" and will be used for authentication on the SP side (if configuration is wf.sso.saml.username.attribute=uid).
Example
wf.sso.saml.sp.metadata = test.workfusion.com_workspace-sandbox
--------------------------------------------------------------
In this case, Audience will look like:
<saml:AudienceRestriction xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Audience>test.workfusion.com_workspace-sandbox</saml:Audience>
</saml:AudienceRestriction>
Example of the IdP response with the encrypted data:

IdP and SP metadata description
| Tag | Source | Description |
|---|---|---|
| EntityDescriptor | IdP/SP metadata | main metadata's tag with ID/EntityID attributes |
| IDPSSODescriptor | IdP metadata | IdP configuration description |
| SPSSODescriptor | SP metadata | SP configuration description |
| SingleSignOnService | IdP metadata | Endpoint to sign on |
| SingleLogoutService | IdP/SP metadata | Endpoint to sign out |
| AssertionConsumerService | SP metadata | SP endpoint to assert response from IdP side |
| saml:Atribute | IdP metadata/response | Attribute description goes from IdP side |
| saml:AtributeValue | IdP response | Attribute value |
| saml:AudienceRestriction | IdP response | Container for saml:Audience tag |
| saml:Audience | IdP response | SP EntityID for which the response is sent (used in response Assertion) |
| samlp:StatusCode | IdP response | Response status, success example value (urn:oasis:names:tc:SAML:2.0:status:Success) |
Configure SSO
Before enabling SSO, make sure that a user with Administrator role and username that fits your SSO account is created in CT.

Configure application and secure properties to enable SSO:
# workfusion.properties file wf.sso.saml.enable=true wf.sso.saml.entity.base.url=https://workfusion-lb.example.com/workfusion # Secure Storage wf.sso.saml.idp.file.metadata=/path/to/ipd/metadata/provided/by/security/team wf.sso.saml.sp.metadata=unique-service-provider-name wf.sso.saml.username.attribute=ACCOUNT //the name of the attribute into SSO response with username, usually described in IdP metadata file. wf_sso_saml_metadata_admin_user: workfusion // the username to log in to https://workfusion-lb.example.com/workfusion/saml/web/metadata endpoint. Used for metadata administration. wf_sso_saml_metadata_admin_pass: '********' // the password to log in to https://workfusion-lb.example.com/workfusion/saml/web/metadata endpoint. Used for metadata administration.Restart the Application server.
Go to https://workfusion-lb.example.com/workfusion/saml/metadata, and use the
wf_sso_saml_metadata_admin_userandwf_sso_saml_metadata_admin_passcredentials to log in. The metadata file will be downloaded. Send it to the security team to be added into Identity Provider (SSO server).Open any CT page. From now you'll be redirected to your Identity Provider Login Page. Enter your account.
User authentication and authorization
This implementation assumes that the user, who is going to log in via the identity provider (IdP)** already exists in Control Tower
The Admin user who is responsible for creation new users and assigning privileges must be primarily created directly via database.
The Admin user must create new users with usernames that already exists in IdP.
If a deleted, disabled, or non-existing user tries to log in, they will be redirected to the WorkFusion login failed screen with a validation message.

Users are authorized on the WorkFusion side. The admin user can manage user roles.
IdP configuration
Assertion Consumer Service, EntityID and Public Key can be found in the metadata XML file.
Service Provider metadata can be downloaded from https://workfusion-lb.example.com/workfusion/saml/metadata.
LDAP / AD authorization
For information on enabling LDAP and AD auhotization, and mappping user groups, see LDAP and AD integration.
important
In case when Identity provider validates user in LDAP/AD services directly make sure that option ldap.enabled=false in INSTALL_DIR/workfusion/conf/workfusion.properties.
WorkSpace SAML Integration
Application Properties
| Property Name | Value | Description |
|---|---|---|
ws.sso.saml.enable | true | Enables or disables SAML 2.0 protocol for Control Tower. Accepted values: true and false |
ws.sso.saml.entity.base.url | https://workspace-lb.example.com/workspace or https://workspace-lb.example.com/workspace-sandbox | Base url of Workfusion SAML provider |
ws.sso.saml.response.skew | 60 | Maximum difference between the local time and the time of the assertion creation, which still allows a message to be processed. Basically determines maximum difference between clocks of the IDP and SP machines. By default, 60 (seconds) |
| wf.sso.saml.keystore.file.path | {{ jks_path }} | The location, where the file Java Key Store (jsk) with the private keys is stored. By default, INSTALL_DIR/ssl/wf_saml_integration.jks. The location and the name are configured in group_vars/all/vars.yml, in parameters common_ssl_dir (here, INSTALL_DIR/ssl) and jks_filename (here, wf_saml_integration.jks) |
Sample of workspace.properties (workspace-sandbox.properties)
# option to enable/disable SSO authentication
ws.sso.saml.enable=true
# base url used during generation SP metadata
ws.sso.saml.entity.base.url=https://workspace-lb.example.com/workspace
# response skew in seconds
ws.sso.saml.response.skew=60
# The location, where the file Java Key Store (jsk) with the private keys is stored. jks_path = {{ common_ssl_dir }}/{{ jks_filename }} , where common_ssl_dir = {{ install_dir }}/ssl, jks_filename = wf_saml_integration.jks. All locations are configured in group_vars/all/vars.yml.
wf.sso.saml.keystore.file.path={{ jks_path }}
Secure Properties
| Property Name | Value | Description |
|---|---|---|
ws.sso.saml.idp.file.metadata | /path/to/local/meta | Path to a file with IdP metadata parameters. |
ws.sso.saml.idp.metadata | none | A URL that points to a file with IdP metadata parameters. Must be provided by a customer. This parameter is an alternative to wf.sso.saml.idp.file.metadata, which is a recommended option. |
ws.sso.saml.sp.metadata | ws-sp-hostname | A unique string. ID of Service Provider, for example, https://workspace-lb.example.com/workspace/saml/metadata |
ws.sso.saml.username.attribute | A name of the attribute that will be used for authentication | |
wf.sso.saml.metadata.admin.password | 'At#d!at****' | The password to log in to the https://workfusion-lb.example.com/workfusion/saml/web/metadata/login endpoint. Used for administering metadata. |
wf.sso.saml.keystore.password | {{ jks_pass }} | The password to the Java Key Store file is generated during the installation and is recorded to Vault. You can read the password with the command ./loader.sh ansible review. |
wf.sso.saml.keystore.keys.default | {{ jks_alias }} | A human-friendly name for a private key that is stored in Java Key Store. JKS can store several keys with aliases that are assigned to each one. The alias is configured in group_vars/all/vars.yml. |
wf.sso.saml.keystore.keys.map | {"{{ jks_alias }}":"{{ jks_pass }}"} | The property to read the alias of a private key from the JKS file. |
Secure Storage sample properties
# url to IdP metadata, use url or file
#ws.sso.saml.idp.metadata=none
# path to IdP metadata file
ws.sso.saml.idp.file.metadata=/path/to/local/metadata
# some unique name
ws.sso.saml.sp.metadata=ws-sp-hostname
# the name of an attribute taken from IdP response that contains user's email address
ws.sso.saml.username.attribute=mail
# The password to the Java Key Store file
wf.sso.saml.keystore.password={{ jks_pass }}
# A human-friendly name for a private key that is stored in Java Key Store
wf.sso.saml.keystore.keys.default={{ jks_alias }}
# The property to read the alias of a private key from the JKS file
wf.sso.saml.keystore.keys.map={"{{ jks_alias }}":"{{ jks_pass }}"}
note
At least one of the "idp" properties must be set. Otherwise, you'll get the "No IdP was configured" page.
User Authentication and Authorization
- This implementation assumes that the user that is going to log in via the identity provider (IdP) already exists in WorkSpace.
- A requester must be primarily created directly via the database. The user's email in IdP must be the same as the username in WorkSpace.
- A Worker can get registered by itself. The email in IdP must be the same as the username in WorkSpace.
- If a deleted, disabled, or non-existing user tries to log in to Workspace, they will be redirected to the the index page with a validation message.
- A disabled (non-active) user can be activated by email or by a Requester.
IdP Configuration
Assertion Consumer Service, EntityID and Public Key can be found in metadata xml file
Service Provider metadata can be downloaded by the url: https://workspace-lb.example.com/workspace/saml/metadata.
Elastic Stack SAML Integration
Elastic stack is operating as service provider in the SAML terminology. Configuration of SAML in Elastic stack will enable SSO in Kibana.
note
To integrate SAML for the Elastic stack in the HA environment, the changes mentioned below must be applied for all the servers/roles, for example, for two APP and three INT servers.
Configure Elasticsearch
To configure Elasticsearch:
Login to the INT server via SSH.
Create the SAML realm by adding the following lines to elasticsearch.yml configuration file located in the <elasticsearch_home>/config directory.
xpack.security.authc.token.enabled: true xpack.security.authc.realms.saml.<name_of_realm>: # name of saml realm order: <order> # unique order of realm. It's recommended that saml realm has the highest order idp.metadata.path: <path_to_idp_metadata> # path to Identity provider metadata file or URL idp.entity_id: <idp_url> # Id of Identity Provider. It should match the entityID attribute within the metadata file. sp.entity_id: <kibana_url> # Id of Service Provider. Recommended value is the base URL of Kibana instance. sp.acs: <kibana_url>/kibana/api/security/v1/saml # Assertion consumer service URL. Must be in form of <kibana_url>/kibana/api/security/v1/saml sp.logout: <kibana_url>/kibana/logout # Single logout service. Must be in form of <kibana_url>/kibana/logout attributes.principal: <user_attribute_uri> # URI of user attribute returned by Identity Provider attributes.groups: <group_attribute_uri> # URI of group attribute returned by Identity Provider # Example: xpack.security.authc.token.enabled: true xpack.security.authc.realms.saml.shibboleth: order: 2 idp.metadata.path: saml/idp-metadata.xml idp.entity_id: "https://sso.example.com/" sp.entity_id: "https://kibana.example.com/" sp.acs: "https://kibana.example.com/kibana/api/security/v1/saml" sp.logout: "https://kibana.example.com/kibana/logout" attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1" attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1."Generate the Kibana SAML 2.0 Service Provider Metadata file by running the following commands:
$ cd <elasticsearch_home> # the directory where elasticsearch is installed to. $ bin/elasticsearch-saml-metadata --realm <name_of_realm> # the name of the SAML realm configured in elasticsearch.yml file. # Example $ bin/elasticsearch-saml-metadata --realm shibbolethRegister Service Provider at Identity Provider by providing the generated Service Provider Metadata file to Identity Provider.
Configure role mappings of external users and groups by adding the following lines to the role_mapping.yml file located in the <elasticsearch_home>/config directory.
<role>: # role. Description of elastic built-in roles will be provided below. - "<user_attribute_value>" # user attribute value returned by Identity Provider - "<group_attribute_value>" # group attribute value returned by Identity Provider # Example: kibana_user: - "admin" - "admins"As an alternative, map a role via Kibana API: go to Kibana UI as the admin user, open the Dev tool tab, and POST the role mappping in the format below:
POST /_security/role_mapping/<mapping_name> # name of the mapping request { "enabled" : true, "roles" : [ "<kibana role>" # role with permissions the users should be mapped to, for example, superuser, kibana_user ], "rules" : { "all" : [ { "field" : { "realm.name" : "<name_of_realm>" # name of saml realm } }, { "field" : { "groups" : "<group_name>" # group name users belong to from AD/LDAP, for example, Admins } } ] }, "metadata" : { } } # Example POST /_security/role_mapping/saml-superuser { "enabled" : true, "roles" : [ "superuser" ], "rules" : { "all" : [ { "field" : { "realm.name" : "shibboleth" } }, { "field" : { "groups" : "Admins" } } ] }, "metadata" : { } }
For the description of a built-in user, see the guide.
Configure Kibana
Login to the APP server via SSH and add the following lines to kibana.yml located in the <kibana_home>/config directory to use the SAML realm.
# SAML integration
xpack.security.public:
protocol: https
hostname: <kibana_DNS_record> # kibana-lb.example.com
port: 443
xpack.security.authProviders: [saml]
xpack.security.authc.saml.realm: <name_of_realm> # name of saml realm specified in elasticsearch.yml, for example, shibboleth
server.xsrf.whitelist: [/api/security/v1/saml]
The SAML support in Kibana assumes that it will be the primary (or sole) authentication method for users of that Kibana instance. However, it is possible to support both SAML and Basic authentication within a single Kibana instance by setting xpack.security.authProviders as per the example below:
xpack.security.authProviders: [saml, basic]