Keycloak authentication service

Domino uses Keycloak, an enterprise-grade open source authentication service to manage users and logins. Keycloak runs in a pod in the Domino Platform. There are three modes you can use for identity management in Domino:

  1. Local usernames and passwords
  2. Identity federation to LDAP / AD
  3. Identity brokering to a SAML provider for SSO



Accessing the Keycloak UI

You can access the Keycloak UI on any Domino instance at

https://<domino-domain>/auth/

Note that the trailing / in the URL is required.

To log in as the default keycloak administrator user, you will need kubectl access to the cluster to retrieve the password from a Kubernetes secret called keycloak-http.

Run kubectl -n <domino-platform-namespace> get secret keycloak-http -o yaml to fetch the contents of the secret. The output should look like the following:

apiVersion: v1
data:
  password: <encrypted-password>
kind: Secret
metadata:
  creationTimestamp: 2019-09-09T21:23:15Z
  labels:
    app.kubernetes.io/instance: keycloak
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: keycloak
    helm.sh/chart: keycloak-4.14.1-0.10.2
  name: keycloak-http
  namespace: domino
  resourceVersion: "6746"
  selfLink: /api/v1/namespaces/domino/secrets/keycloak-http
  uid: 09009f96-d348-11e9-9ea1-0aa417381fd6
type: Opaque

Decrypt the password by running echo '<encrypted-password' | base64 --decode. With this password you will be able to log in to the Keycloak UI as the keycloak administrator user in the master realm. Read the official Keycloak documentation on the master realm to learn more.

Keycloak will be configured automatically by Domino with a realm named DominoRealm that will be used for Domino authentication. When reviewing or changing setting for Domino authentication, ensure that you have DominoRealm selected in the upper left.

_images/keycloak-realm.png



Local username and password configuration

The simplest option for authentication to Domino is to use local usernames and passwords. In this case all user information is stored by Keycloak in the Postgres database, and there is no federation or brokering to other identity providers.

Configuration

In this mode the key settings are on the Login tab of the DominoRealm settings page.

_images/keycloak-local-login-config.png

The one setting on this tab that is not supported is Email as username as that would automatically use email as username and Domino currently does not support that as a valid username. Note also that if you want to use the Verify Email option, an SMTP connection must be configured in the Email tab.

User management

You can add, edit, and deactivate local users from the Users menu. Click View all users to load user data.

_images/keycloak-manage-users.png



LDAP / AD federation

Keycloak provides the ability to connect to an LDAP / AD identity provider and cache user information.

Adding a provider

This can be configured in the User Federation menu. Select ldap from the Add provider… dropdown menu.

For details on all available options, read the official Keycloak documentation on User storage federation.

When adding a provider according to those docs, if you are migrating from an older Domino, you can make use of your existing ldap.conf file on the Domino frontend to see exactly what inputs you should use for the provider settings. Some of the key pieces of information are:

ldap.conf name Keycloak user federation setting name
Search principal Bind DN
Search base Users DN
Search filter Additional Filtering

Group and Role synchronization can be configured with steps similar to those listed for SSO, except that user attributes must first be imported to Keycloak via an LDAP mapper. Once that is done, and the users in Keycloak have the appropriate user attributes specifying group membership or role, the remaining setup (to map from Keycloak to Domino) will follow the steps in the SSO group and role synchronization related to Client Mappers.

Note

Updates to a user’s group or role will not fully synchronize to Domino until the user has a login event to Domino.

Configuring mappers

In addition to configuring the LDAP connection you may also need to review the LDAP mappers associated with the LDAP connection you have configured. Some mappers will be configured by based on the LDAP vendor that was chosen, but you may need to modify these based on the specific configuration of your provider. You will need to make sure that there are mappers for the following attributes:

  • username
  • firstName
  • lastName
  • email

For more details, read the official Keycloak documentation on LDAP mappers.




Single Sign-On configuration


Configure Single Sign-On

Domino can integrate with a SAML 2.0 or OIDC identity provider for Single Sign-On (SSO) with the steps outlined below.




Create a new Domino SAML service provider (SP)

  1. Log in to the Keycloak UI as the default keycloak administrator user.
  2. Click Identity Provider from the main menu.
  3. Use the drop-down menu to create a new SAML 2.0 provider
_images/keycloak-identity-providers.png



Configure alias and determine redirect URI

Provide an Alias for the newly created provider. This is a unique name for the provider in Keycloak, and it will also be part of the Redirect URI used by the provider service to route SAML responses and redirect users following authentication.

The Redirect URI (case sensitive) will be:

https://<deployment_domain>/auth/realms/DominoRealm/broker/<alias>/endpoint

In an example deployment with domain domino.acme.org and provider alias domino-credentials the URL will be:

https://domino.acme.org/auth/realms/DominoRealm/broker/domino-credentials/endpoint

_images/keycloak-add-identity-provider.png

Do not save the identity provider entry yet, as you will not be able to import your provider settings once it is saved.




Create a SAML endpoint in your upstream identity provider

To complete the configuration, you need to create a SAML application in the identity provider that will be integrated with Domino. To create the application you will need the Redirect URI from the step above.

The specific procedure for creating the SAML endpoint will depend on your identity provider. Domino can integrate via SAML with Okta, Azure AD, Ping, and any other provider that implements SAML v2.0.

The following are important properties of the SAML endpoint you will create in the provider. After the SAML endpoint has been created and configured, you should export an XML metadata file you can use to complete the configuration of the provider in Keycloak.


NameID policy format

Controls the format of the <saml2:NameID> element in the SAML Response. This will be used to derive the SSO username in Domino.

  • Option 1: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress

    • Users will be uniquely identified by their email and username will be automatically derived from it
    • Example:
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
    john.smith@acme.org
    </saml2:NameID>
    
  • Option 2: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified

    • The SAML endpoint will need to respond with a string that can be used as the username of the user without any modification
    • Example:
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
    jsmith
    </saml2:NameID>
    
  • Option 3: urn:oasis:names:tc:SAML:1.1:nameid-format:persistent

    • Typically the SAML endpoint will return a NameID that is a GUID which is not suitable for a username
    • If the endpoint must use this format, then an additional attribute containing username must be returned

Assertion attributes

Additional SAML attributes are required to automatically populate the Domino profile. Without these, on first login the user will be prompted to complete the required elements of their user profile.

The required attributes are:

  • firstName
  • lastName
  • email
  • username (if NameId is not email or does not represent user name)

No specific attribute names are expected as these can be mapped in Keycloak.


Additional requirements
  • Assertions signed - SAML Responses should contain signed assertions



Import metadata and complete configuration in Keycloak


Import IdP Metadata

You can use the metadata file from the step above to complete configuration of the provider in Keycloak.

You can do this from the bottom of the identity provider configuration page. This is only available before the provider is saved for the first time.

_images/keycloak-import-external-idp-config.png

If you are importing from a file, make sure to click Import after selecting the file. After import, most of the provider settings will be configured automatically. You can now save the configuration.


Additional settings
  • Trust Email - Yes

    Ensures that emails supplied from IdP are trusted even if Email Verification is enabled for DominoRealm.

    _images/keycloak-trust-email-yes.png
  • NameID Policy Format

    This should have been configured on import, but verify that it matches the option configured on the external endpoint.

  • Want Assertions Signed - Yes

  • Validate Signature - Yes

    The corresponding signature field should already be populated based on the metadata you imported in the previous step

_images/keycloak-1_4_2-additional-saml-settings.png

Additional options like Assertion Encryption and Request Singing are supported, but would require additional configuration coordination between Keycloak and the endpoint in your identity provider.

For more detailed documentation of all supported SAML settings, see Keycloak SAML v2 Identity Providers


Exporting metadata from Keycloak

Once the provider in Keycloak is saved, an Export tab will appear that contains XML metadata for the provider that can be used to automatically configure the external endpoint.

The metadata will also be available at:

https://<deployment domain>/auth/realms/DominoRealm/broker/<alias>/endpoint/descriptor




Configure attribute mappers

In order to make the experience of new users signing in for the first time seamless, and not require them to complete their profile on initial login, you need to make sure that several SAML attributes are being passed back in SAML responses and that these are correctly mapped to Domino user attributes.

If the attributes are not properly mapped, upon first login users will be prompted to complete missing fields in their profile.


Mapping first name, last name, and email

To map these values from the SAML assertion attributes to the user profile model, you need to configure an Attribute Importer mapper from the Mappers tab.

_images/keycloak-1_5_1-add-identity-provider-mapper.png
  • First Name mapper

    • Name: First Name
    • Mapper Type: Attribute Importer
    • Attribute Name: Name attribute for the <saml2:Attribute> element containing the value to be mapped to First Name
    • Friendly Name: FriendlyName attribute (optionally available) for the <saml2:Attribute> element containing the value to be mapped to First Name
    • User Attribute Name: Must be firstName
  • Last Name mapper

    • Name: Last Name
    • Mapper Type: Attribute Importer
    • Attribute Name: Name attribute for element containing the value for Last Name
    • Friendly Name: FriendlyName attribute for the <saml2:Attribute> element containing the value for Last Name
    • User Attribute Name: Must be lastName
  • Email mapper

    • Name: Email
    • Mapper Type: Attribute Importer
    • Attribute Name: Name attribute for element containing the value for Email
    • Friendly Name: FriendlyName attribute for the <saml2:Attribute> element containing the value for Email
    • User Attribute Name: Must be email

The following example illustrates how to map First Name from an assertion with the following payload:

<saml2:Attribute Name="customSAMLFirstName" FriendlyName="FriendlyFirstName">
  <saml2:AttributeValue>John</saml2:AttributeValue>
</saml2:Attribute>

Can be mapped using:

_images/keycloak-1_5_1-map-firstname-example.png

Alternatively can be mapped using:

_images/keycloak-1_5_1-map-firstname-example2.png

Mapping username

The mapper configuration for username depends on how the external endpoint is configured with respect to NameID Policy options.

  • Option 1: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress

    • Use Email Prefix as UserName Importer
    • Example:
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
      john.smith@acme.org
    </saml2:NameID>
    

    Map as shown:

    _images/keycloak-1_5_2-email-prefix-as-username.png
  • Option 2: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified

    • No need to do an importer. The username will be mapped automatically to the NameID value
    • Example:
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
      jsmith
    </saml2:NameID>
    
  • Option 3: urn:oasis:names:tc:SAML:1.1:nameid-format:persistent

    • Use Username Template Importer with Template of ${ATTRIBUTE.<attribute Name>} or ${ATTRIBUTE.<attribute FriendlyName>}
    • Example:
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
      jsmith
    </saml2:NameID>
    <saml2:Attribute Name="customUserName">
      <saml2:AttributeValue>jsmith</saml2:AttributeValue>
    </saml2:Attribute>
    

    Map as shown:

    _images/keycloak-1_5_2-nameid-persistent.png

Attribute mapping documentation

For additional information on attribute mapping, please refer to keycloak documentation for Mapping Claims and Assertions


Email Prefix as Username Importer

When using the ‘Email Prefix as Username Importer’ mapper as illustrated above (Option 1), the generated user name will be the email prefix, stripped of all characters except alphanumeric and underscores. Special characters will be converted to underscores, characters with diacritics will be converted to their ascii base.

If an existing username from an external system is present, the same transformation rules will be applied to it.

For example, a username $jöhn.smîth#home$ or an email address $jöhn.smîth#home$@somehost.com would both be mapped to the user name john_smith_home.


Troubleshooting attribute mapping

When troubleshooting SAML attribute mapping, ideally you will want to have a specification for the SAML response that your identity provider endpoint will send back to Keycloak following authentication. A thorough specification will detail the NameID policy format and attributes being sent in the response.

If such a specification is not available, or the attribute mapping does not function as expected, it may be necessary to examine an actual SAML response that is returned after a login attempt. One simple way to do this is to use the SAML-tracer extension available for Chrome and Firefox. It will allow you to examine decoded SAML requests and responses. By examining a SAML response, you will be able to:

  • see the attributes that are being returned
  • verify whether attributes are missing
  • verify whether the names or formats are different from what is expected



Domino First Broker Login authentication flow

To configure the recommended login authentication flow, select the Domino First Broker Login flow (no dashes):

_images/keycloak-first-broker-login-selection.png

See the Keycloak documentation for information on authentication flows.




Restrict access for SSO users to Domino

Typically, when configuring the SAML endpoint that will provide SSO authentication for Domino, the provider administrator restricts the endpoint to a subset of users who should be allowed to authenticate through it. This is the preferred method for restricting access to a subset of users with valid enterprise credentials.

In rare cases, where limitations in the provider software don’t allow you to constrain the set of users who can authenticate against the endpoint, the provider will need to pass an additional SAML attribute which specifies if a user is allowed to access Domino or not. The value of that attribute will depend on a specific rule for each user. Usually, it will be based on membership in a particular group in your identity provider.

The following should be used as a last resort if all identity provider restriction options are exhausted.


Prerequisites

The Domino Keycloak instance must have keycloak.profile.feature.scripts=enabled.


Expected SAML attributes

There must be an attribute that indicates whether a properly authenticated user should be allowed to log in to Domino.

  • AttributeName:

    • Suggested: rolesForDomino
    • Could be anything as this can be mapped
  • Multi-valued: Yes

  • Value:

    • Contains one or more values that could be used for gating access. Typically would be roles or groups.

Attribute mapper

You need to add an additional mapper to your provider configuration in Keycloak.

Use an Attribute Importer mapper type.

  • Name: Allow in Domino
  • Mapper Type: Attribute Importer
  • Attribute Name: Name attribute for element containing the flag
  • Friendly Name: FriendlyName attribute for element containing the groups for the user
  • User Attribute Name: Must be accessforDomino

Example:

<saml2:Attribute Name="rolesForDomino">
  <saml2:AttributeValue>dave-users</saml2:AttributeValue>
  <saml2:AttributeValue>it-users</saml2:AttributeValue>
</saml2:Attribute>

Create the Post Login authentication flow

Domino doesn’t provide a post login flow by default, so you should add one by clicking Authentication -> Flows, and then the “New” button:

_images/keycloak-new-post-login.png

Then create a generic flow named “Post Login Flow”:

_images/keycloak-new-post-login-2.png

In the new flow, add an execution of type Script.

_images/keycloak-new-post-login-4.png _images/keycloak-new-post-login-3.png

Click on Actions, then Config:

_images/keycloak-new-post-login-5.png

Use the following script and modify the attribute value as needed.

/*
* Template for JavaScript based authenticator's.
* See org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticatorFactory
*/

// import enum for error lookup
AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");


/**
* An example authenticate function.
*
* The following variables are available for convenience:
* user - current user {@see org.keycloak.models.UserModel}
* realm - current realm {@see org.keycloak.models.RealmModel}
* session - current KeycloakSession {@see org.keycloak.models.KeycloakSession}
* httpRequest - current HttpRequest {@see org.jboss.resteasy.spi.HttpRequest}
* script - current script {@see org.keycloak.models.ScriptModel}
* authenticationSession - current authentication session {@see org.keycloak.sessions.AuthenticationSessionModel}
* LOG - current logger {@see org.jboss.logging.Logger}
*
* You one can extract current http request headers via:
* httpRequest.getHttpHeaders().getHeaderString("Forwarded")
*
* @param context {@see org.keycloak.authentication.AuthenticationFlowContext}
*/
function authenticate(context) {
    //name of the attribute that needs to be 'true' to allow a user to authenticate in Domino
    var requiredAttrName = "accessForDomino";
    var requiredAttrMustContain = "dave-users";
    var errorMessageId = "userNotAssignedToDominoInIdp";
    var errorPageTemplate = "error.ftl";

    if (user === null) {
        context.success();
        return;
    }

    LOG.info(script.name +
            " trace script auth for: " +
            user.username);

    var requiredAttrValues = user.getAttribute(requiredAttrName)

    LOG.info("User gated on attribute: " + requiredAttrName);
    LOG.info("Attribute values from SSO: " + requiredAttrValues)
    LOG.info("Attribute must contain: " + requiredAttrMustContain);

    if (requiredAttrValues === null ||
        requiredAttrValues.size() === 0 ||
        requiredAttrValues.contains(requiredAttrMustContain)) {
            //user is explicitly allowed in Domino
            LOG.info("User is allowed in Domino.");
            context.success();
            return;
    }

    //user is not authorized to access Domino
    LOG.info("User is not allowed in Domino.");
    context.failure(AuthenticationFlowError.IDENTITY_PROVIDER_DISABLED, context.form().setError(errorMessageId, null).createForm(errorPageTemplate));

    //actually remove the user that was provisionally created
    session.userLocalStorage().removeUser(realm, user);
}

Make the execution required.



Customizing the SSO button

When using the default domino-theme in Keycloak, each identity provider has a display text field that can be edited. This display text will show up on the SSO button for that identity provider. If Display text is blank or equal to the alias value, the button will display the default text Continue with Single Sign On. If any text other than the value of the Alias field is used, that value becomes the text on the button.




Testing and troubleshooting

If you encounter errors from the Keycloak service while attempting an SSO login, you can view the Keycloak request logs via kubectl by running kubectl -n <domino-platform-namespace> logs keycloak-0.




Session and token timeouts

Domino interacts with Keycloak via the OpenID Connect protocol <https://openid.net/connect/>, which uses two JWT tokens. Access token gives its bearer access to the secured resource (can be used to authenticate requests). The other token, refresh token, is not recognized by the secured resources, but it is used to request a fresh valid access token from the identity provider (Keycloak).

When the user authenticates with Keycloak and gets redirected to Domino, both tokens are saved in the Domino server-side session. Every time a request from the user’s browser is made to Domino, the server-side session is checked. If the access token is about to expire or has expired, Domino will attempt a background call to Keycloak to request another access token. If this call is successful, the user’s request is served, otherwise the user is logged out. If the refresh token is expired, the user is logged out.

Keycloak has several timeouts that affect the behavior described above.

  1. Access Token Lifespan. This defines how long an access token is valid. Domino will not re-check the validity of the user’s authentication with Keycloak until this token expires. Default value is 5 minutes.
  2. SSO Session Max. This setting has no effect on the lifespan of any tokens, but it limits the maximum length of the user’s session with Keycloak. Even if the user keeps refreshing their tokens and actively using Domino, they will be logged out at the end of this period. Default value is 60 days.
  3. SSO Session Idle. This defines the maximum period of time within which the user’s session on Keycloak must be refreshed, otherwise it will be terminated. It defines the lifespan of the refresh token. This period should be longer than Access Token Lifespan, and not longer than SSO Session Max. Important: If the user leaves their browser window with Domino open, the background requests will keep the session alive. Only if the user closes the window or navigates away from the Domino UI, the idle countdown will start.

See the Keycloak documentation for more information on timeouts.




AWS credential propagation




Overview

If you have enabled SSO for Domino, you can optionally configure AWS credential propagation, which allows for Domino to automatically assume temporary credentials for AWS roles that are based on roles assigned to users in the upstream identity provider. Below is a reference for the overall workflow from user login to credential usage.

_images/keycloak-upstream-idp-trust.png

Validations within the AssumeRoleWithSAML workflow
  1. The Identity Provider Relying Party/Application validates that the Issuer element in the AuthnRequest (SAML request) sent by Domino
  2. Domino validates the Audience (Entity ID of the SP) in the SAML Response sent by the Identity Provider Relying Party/Application
  3. AWS AssumeRole validates that the Issuer of the SAML Response passed on from Domino matches the Issuer of the Identity Provider Relying Party/Application. You can set up additional validations also (e.g. validating the Audience)

Launching a Workspace or Run
_images/keycloak-launching-workspace-run.png

Enable credential propagation in Domino

The following central configuration settings need to be set as shown to enable credential propagation. These can be found or added by a Domino administrator by clicking Advanced > Central Config from the administration UI.

  • Key: com.cerebro.domino.auth.aws.sts.enabled

    Value: true

  • Key: com.cerebro.domino.auth.aws.sts.region

    Value: Short AWS region name where your Domino is deployed, such as us-west-2

  • Key: com.cerebro.domino.auth.aws.sts.defaultSessionDuration

    Value: Default session duration, such as 1h for 1 hour

Example of a valid configuration:

_images/keycloak-2_1-enable-cred-prop.png _images/keycloak-2_1-enable-cred-prop2.png

Remember to restart the services with the link at the top of the central configuration page for these settings to take effect.


SAML provider configuration prerequisites

You need to have federation between your AWS account and your identity provider configured independent of Domino. As an example see AWS Federated Authentication with Active Directory Federation Services (AD FS)

The SAML provider application connected to Domino needs include the appropriate AWS federation attributes based on the roles that each user will be allowed to assume.

Since Domino will refresh the user’s credentials during an active session, you must ensure that any IAM role that you propagate to a user has assume-self policy.

For example:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "<ARN for the role>"
    }
}

Expected SAML attributes

  • Attribute with Name https://aws.amazon.com/SAML/Attributes/Role
    • Multi-valued: Yes
    • Value format:
      • Comma-separated key-value pair of provider and role
      • <provider arn>,<role arn>
      • arn:aws:iam::<acct #>:saml-provider/<provider name>,arn:aws:iam::<acct #>:role/<role name>
  • Attribute with Name https://aws.amazon.com/SAML/Attributes/RoleSessionName
    • Multi-valued: No
    • Value:
      • String to be used as identifier for the temporary credentials assumed
      • Usually set to the email of the user
  • Attribute with Name https://aws.amazon.com/SAML/Attributes/SessionDuration
    • Multi-valued: No
    • Value:
      • Duration (in seconds) of how long the initial set of credentials for each of the roles is valid before the user will need to login again
      • The duration must be smaller than the maximum allowable duration for each of the roles made available for a given user

Before proceeding, it’s useful to check that your SAML attributes appeared in your SAML response when logging into Domino. This will help validated that you’ve correctly established trust between AWS and your IDP. One simple way to do this is to use the SAML-tracer extension available for Chrome and Firefox. It will allow you to examine decoded SAML requests and responses to see that the appropriate attributes appear.

Example:

<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/Role">
      <saml2:AttributeValue xsi:type="xs:string">
          arn:aws:iam::123456789012:saml-provider/acme-saml,arn:aws:iam::123456789012:role/role1
      </saml2:AttributeValue>
      <saml2:AttributeValue xsi:type="xs:string">
          arn:aws:iam::123456789012:saml-provider/acme-saml,arn:aws:iam::123456789012:role/role2
      </saml2:AttributeValue>
  </saml2:Attribute>
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName">
      <saml2:AttributeValue xsi:type="xs:string">
          john.smith@acme.org
      </saml2:AttributeValue>
  </saml2:Attribute>
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/SessionDuration">
      <saml2:AttributeValue xsi:type="xs:string">
          900
      </saml2:AttributeValue>
  </saml2:Attribute>
</saml2:AttributeStatement>

Mapping AWS federation attributes

To map the appropriate values from the SAML assertion, you need to configure an Attribute Importer mapper from the Mappers tab for the following attributes.

_images/keycloak-2_2_3-attribute-mapper.png
  • AWS Roles

    • Name: AWS Roles
    • Mapper Type: Attribute Importer
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/Role
    • Friendly Name: <blank>
    • User Attribute Name: Must be aws-roles
  • AWS Role Session Name

    • Name: AWS Role Session Name
    • Mapper Type: Attribute Importer
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/RoleSessionName
    • Friendly Name: <blank>
    • User Attribute Name: Must be aws-role-session-name
  • AWS Session Duration

    • Name: AWS Session Duration
    • Mapper Type: Attribute Importer
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/SessionDuration
    • Friendly Name: <blank>
    • User Attribute Name: Must be aws-session-duration

Additional provider configuration

In order to give Domino access to users SAML assertions, you need to enable the following settings from the identity provider:

  • Store Tokens: On
  • Store Tokens Readable: On
_images/keycloak-2_2_4-tokens.png

Domino-client configuration

The domino-play OIDC client is pre-populated on installation with client mappers, so that IdP mapped SAML information will flow into Domino.

  1. Go to the Clients tab in the DominoRealm and select the domino-play client
_images/keycloak-2_3_1-domnio-play.png
  1. Select the Mappers tab for the domino-play client
_images/keycloak-2_3_1-mappers.png
  1. Below are the default domino-play client mappers:
_images/keycloak-default-client-mappers.png
  1. Create a new mapper with type User Session Note and the following settings:

    • Name: identity-provider-mapper
    • Mapper Type: User Session Note
    • User Session Note: identity_provider
    • Token Claim Name: idpbroker
    • Claim JSON Type: string
    • Add to ID token: On
    • Add to access token: On
    _images/keycloak-2_3_1-mappers2.png

Usage

Once configured properly the first time, you will need to log out and log back into Domino.

To confirm that credentials are propagating correctly to users, start a workspace and check the environment variable AWS_SHARED_CREDENTIALS_FILE and that your credential file appears at /var/lib/domino/home/.aws/credentials.

This should be sufficient for a user to connect to AWS resources without further configuration. Click here to see an example of connecting to s3.

Learn more about using a credential file with AWS SDK.

Confirming the configuration

To test your configuration outside of Domino, perform an AssumeRoleWithSAML call successfully using the SAML token provided to Domino by your IdP.

Example:

aws sts assume-role-with-saml \
--role-arn arn:aws:iam::521624712688:role/DataScientist-dev \
--principal-arn arn:aws:iam::521624712688:saml-provider/ADFS-DOMINO \
--saml-assertion "PHNhb.......VzcG9uc2U+"



SSO group and role synchronization

Domino supports synchronizing Domino administrative user roles and organization membership with attributes in your SAML identity provider. This allows management of these roles and memberhsips to be externalized to the identity provider.




SAML Group to Organization synchronization


Prerequisite

Your SAML provider application connected to Domino must include group membership as a multi-valued attribute.


Central configuration options

Enabling this feature requires that the following Domino central configuration setting is set as follows:

  • Key: authentication.oidc.externalOrgsEnabled

    Value: true

Remember that Domino services need to be restarted for this setting to take effect.


Attribute mapper

You need to add an additional mapper to the provider configuration in Keycloak.

Use an Attribute Importer mapper type.

  • Name: Domino Groups
  • Mapper Type: Attribute Importer
  • Attribute Name: Name attribute for element containing the groups for the user
  • Friendly Name: FriendlyName attribute for element containing the groups for the user
  • User Attribute Name: Must be domino-groups

Example:

<saml2:Attribute Name="UserGroups">
  <saml2:AttributeValue>nyc-data-scientists</saml2:AttributeValue>
  <saml2:AttributeValue>all-data-scientists</saml2:AttributeValue>
  <saml2:AttributeValue>sensitive-claims-users</saml2:AttributeValue>
</saml2:Attribute>
_images/keycloak-3_1_3-mapper.png

Domino client Mapper

By default, the domino-group-mapper client mapper is created upon installation. To review it, go to the Clients tab in the DominoRealm in Keycloak, and select the domino-play client:

_images/keycloak-3_1_4-domino-play.png

Select the Mappers tab for the domino-play client

_images/keycloak-3_1_4-mappers.png

The domino-group-mapper mapper will be present in the default client mappers listed:

_images/keycloak-default-client-mappers.png



Role synchronization

In addition to automatically configuring group membership, it is also possible to automatically assign Domino administrative and/or user roles to users based on attributes from your SAML identity provider.


Prerequisite

The SAML identity provider application connected to Domino must include attributes that can be mapped to specific Domino roles.


Central configuration

Enabling this feature requires that the following Domino central configuration setting is set as follows:

  • Key: authentication.oidc.externalRolesEnabled

    Value: true

Remember that Domino services need to be restarted for this setting to take effect.


Attribute mapper

You need to add an additional mapper to the provider configuration in Keycloak.

Use an Attribute Importer mapper.

  • Name: Domino System Roles
  • Mapper Type: Attribute Importer
  • Attribute Name: Name attribute for element containing the Domino system roles for the user
  • Friendly Name: FriendlyName attribute for element containing the groups for the user
  • User Attribute Name: Must be domino-system-roles

Domino client mapper

By default, the domino-system-roles client mapper is created upon installation. To review it, go to the Clients tab in the DominoRealm in Keycloak and select the domino-play client.

_images/keycloak-3_2_4-client-mapper.png

Select the Mappers tab for the domino-play client

_images/keycloak-3_2_4-mappers.png

The domino-system-roles mapper will be present in the default client mappers listed:

_images/keycloak-default-client-mappers.png



Summary of Domino SAML attribute requirements

This section covers the SAML attributes expected by Domino to enable different pieces of functionality.




SSO attributes

The following are required to establish single sign-on between Domino and your identity provider:

  • Username
    • NameID (In Subject element)
    • Preferred format: urn:oasis:names:tc:SAML:1.1:nameid-format:email
  • First Name
    • Attribute name: Can be any name since Domino allows attribute mapping
  • Last Name
    • Attribute name: Can be any name since Domino allows attribute mapping
  • Email
    • Attribute name: Can be any name since Domino allows attribute mapping

Example:

<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:email">
    john.smith@acme.org
  </saml2:NameID>
...
</saml2:Subject>
  <saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml2:Attribute Name="DominoEmail">
      <saml2:AttributeValue xsi:type="xs:string">
        john.smith@acme.org
      </saml2:AttributeValue>
    </saml2:Attribute>
    <saml2:Attribute Name="DominoFirstName">
      <saml2:AttributeValue xsi:type="xs:string">
        John
      </saml2:AttributeValue>
    </saml2:Attribute>
    <saml2:Attribute Name="DominoLastName">
      <saml2:AttributeValue xsi:type="xs:string">
        Smith
      </saml2:AttributeValue>
    </saml2:Attribute>
  </saml2:AttributeStatement>



Credential propagation attributes

The following attributes are optional but required if you are using the credential propagation functionality of Domino.

In this case, the following additional attributes are required.

  • AWS Roles
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/Role
    • Multi-valued: Yes
    • Value format:
      • Comma-separated key-value pair of provider and role
      • <provider arn>,<role arn>
      • arn:aws:iam::<acct #>:saml-provider/<provider name>,arn:aws:iam::<acct #>:role/<role name>
  • AWS Role Session Name
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/RoleSessionName
    • Multi-valued: No
    • Value:
      • String to be used as identifier for the temporary credentials assumed
      • Usually set to the email of the user
  • AWS Session Duration
    • Attribute Name: https://aws.amazon.com/SAML/Attributes/SessionDuration
    • Multi-valued: No
    • Value:
      • Duration (in seconds) of how long the initial set of credentials for each of the roles is valid before the user will need to login again
      • The duration must be smaller than the maximum allowable duration for each of the roles made available for a given user

Example:

<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/Role">
    <saml2:AttributeValue xsi:type="xs:string">
      arn:aws:iam::123456789012:saml-provider/acme-saml,arn:aws:iam::123456789012:role/role1
    </saml2:AttributeValue>
    <saml2:AttributeValue xsi:type="xs:string">
      arn:aws:iam::123456789012:saml-provider/acme-saml,arn:aws:iam::123456789012:role/role2
    </saml2:AttributeValue>
  </saml2:Attribute>
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName">
    <saml2:AttributeValue xsi:type="xs:string">
      john.smith@acme.org
    </saml2:AttributeValue>
  </saml2:Attribute>
  <saml2:Attribute Name="https://aws.amazon.com/SAML/Attributes/SessionDuration">
    <saml2:AttributeValue xsi:type="xs:string">
      900
    </saml2:AttributeValue>
  </saml2:Attribute>
</saml2:AttributeStatement>



Group synchronization attributes

The following attributes are required if you are using group synchronization functionality in Domino.

In this case, the following additional attributes are required:

  • Domino Organizations
    • Name: Can be any name since Domino can do attribute mapping
    • Multi-valued: Yes
    • Values:
      • One or more of the groups of which the user is a member in your centralized identity provider. For any groups specified here, the user will be automatically enrolled in a Domino organization with the same name

Example:

<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:Attribute Name="DominoOrganizations">
    <saml2:AttributeValue>nyc-data-scientists</saml2:AttributeValue>
    <saml2:AttributeValue>all-data-scientists</saml2:AttributeValue>
    <saml2:AttributeValue>sensitive-claims-users</saml2:AttributeValue>
  </saml2:Attribute>
</saml2:AttributeStatement>



Administrative role synchronization attributes

The following attributes are required if you are using administrative role synchronization functionality in Domino.

In this case, the following additional attributes are required:

  • Domino System Roles
    • Name: Can be any name since Domino can do attribute mapping
    • Multi-valued: Yes
    • Values:
      • One or more values that is an exact, case-sensitive match to one of the Domino administrative roles
        • Practitioner
        • SysAdmin
        • Librarian
        • ReadOnlySupportStaff
        • SupportStaff
        • ProjectManager

Example:

<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:Attribute Name="DominoSystemRoles">
    <saml2:AttributeValue xsi:type="xs:string">
      SysAdmin
    </saml2:AttributeValue>
    <saml2:AttributeValue xsi:type="xs:string">
      Librarian
    </saml2:AttributeValue>
  </saml2:Attribute>
</saml2:AttributeStatement>



Limiting concurrent user sessions

It is possible to limit the number of concurrent user sessions either on a per user basis or globally for an entire realm. The configuration is different depending on whether Keycloak manages users itself or is tied to an SSO system.

Using Keycloak’s user management

Each Keycloak authentication flow in use needs to be configured separately. Usually, this will be the Browser flow (for browser login) and the Domino First Broker Login Flow for API access. The browser flow is internal to Keycloak and can’t be modified, so you will have to make a copy of it first.

In either of these flows, add a new execution step to the subflow that establishes user credentials. In case of Domino First Broker Login, that’s “Domino - User Creation Or Linking”, in your copied Browser flow, it’s “<Flow Name> Forms”. In the row corresponding to the subflow, select “Add Execution” from the “Actions” pull down menu. On the next page, select “User Session Count Limiter” or “Realm Session Count Limiter”, depending on whether the limit should be user-specific or realm-specific, respectively.

Back on the flow page, set the requirement of the new execution step to “REQUIRED”, then select “Config” from the Actions menu in the same line. Provide a meaningful alias, configure the desired threshold, and the action taken. For User specific limits, the choice is between denying new sessions and deleting the oldest session. For realm specific limits, the choice is to deny sessions, or to mainly log which sessions would have been dropped.

Finally, in case you copied the Browser flow above, select “Clients” from the left navigation, then “domino-play”. In Authentication Flow Overrides, select your copied Browser Flow from the Browser Flow menu and click save. Note, you need to do this for every client that should take advantage of the session limit.

Note

Deleting the oldest session refers to Keycloak sessions, not Domino sessions. The corresponding Domino session remains active until its refresh token expires.

SSO version

When using SSO, Keycloak uses a Client flow, which cannot be extended. Instead, there is the option to add a “post-login” flow that will be executed after successful login. The steps are as follows:

  1. Use the left navigation to select “Authentication”, which opens the flow definition screen.
  2. Click “New” to create a new Flow, name it “Post-Login” or similar, leave the flow type at “generic”, and save the Flow.
  3. Add an Execution Step and select either “User Session Count Limiter” or “Realm Session Count Limiter”.
  4. Configure this execution as described above.
  5. Use the left navigation to select “Identity Providers” and click your SSO Provider.
  6. In the following screen, open the “Post Login Flow” menu and select the post-login flow you created above.
  7. Save the configuration.