Siren Platform User Guide

JWT authentication support

This section offers an overview of how to integrate Siren Investigate with the Search Guard JWT authenticator when Siren Investigate is embedded into an iframe by another application.

Before enabling JWT support you should setup Siren Investigate and Search Guard as described in Search Guard integration, and ensure that it works as expected.3.7.1. Search Guard Integration and Siren Investigate access control

Prerequisites

Search Guard add-on

JWT authentication support require the installation of the commercial Search Guard Kerberos JWT HTTP Authentication add-on; to install it, download the correct jar for your Search Guard version from this page and copy it to the plugins/search-guard-<version> folder on each node, then perform a rolling restart of the cluster.

Siren Investigate proxy

It is required that Siren Investigate and the container application are published on the same domain to enable cross frame communication; this can be achieved by implementing a proxy to Siren Investigate in the container application routes or configuring a reverse proxy on a path in the application server configuration.

JWT token issuance

The application that embeds Siren Investigate is responsible for generating JWT tokens; jwt.io provides a good overview of the technology, a browser based debugging tool and a list of libraries for several platforms.

The Search Guard documentation provides an overview of all the claims supported by the add-on and a list of all the configuration options.

Note that the application must specify an expiration date claim (exp) to avoid creating tokens with unlimited duration.

Configuration

After the add-on has been installed in the cluster, you must modify sg_config.yml file and upload it to the cluster using sgadmin. If you are using the Search Guard management API ensure you include only the sg_config.yml in the sgadmin configuration folder or you will overwrite internal users, actiongroups, roles and mappings defined through the API

To enable JWT authentication over HTTP, you need to add a JWT authenticator stanza to searchguard.authc; an example sg_config.yml follows:

searchguard:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
    authc:
      jwt_auth_domain:
        enabled: true
        order: 1
        http_authenticator:
          type: jwt
          challenge: false
          config:
            signing_key: "cGFzc3dvcmQ="
            jwt_header: "Authorization"
        authentication_backend:
          type: noop
      basic_internal_auth_domain:
        enabled: true
        order: 2
        http_authenticator:
          type: basic
          challenge: true
        authentication_backend:
          type: internal

With this configuration, Search Guard will check if the Authorization header contains a JWT token signed with the signing key specified in http_authenticator.signing_key.

The signing key must be encoded using the base64 algorithm; in the example the decoded key is password; when using RSA public keys, it is also possible to write them on multiple lines as follows:

searchguard:
    ...
    authc:
      jwt_auth_domain:
        ...
        http_authenticator:
          ...
          config:
            signing_key: |-
              -----BEGIN PUBLIC KEY-----
              123123abcbc
              -----END PUBLIC KEY-----

If the token is decoded successfully, Search Guard will validate the following claims:

  • iat: Issued At: the date when the token was issued (optional).
  • exp: Expiration Time: the date after which the token should expired; this claim is optional but you should set it, otherwise tokens will have unlimited duration.
  • nbf: Not Before: the date before which the token should be rejected (optional).

Note

All dates are expressed as seconds since the Epoch in UTC.

If time claims are validated, Search Guard will get the username from the Subject claim (sub), assign role mappings and evaluate role permissions.

If an HTTP request to the cluster contains an HTTP Basic authorization header it will be authenticated by the HTTP authenticator defined in basic_internal_auth_domain; it is necessary to leave this enabled as the Siren Investigate backend uses this method to authenticate with the cluster.

It is possible to customize the claim used to retrieve the username through the parameter subject_key, for example:

searchguard:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
    authc:
      jwt_auth_domain:
        enabled: true
        order: 1
        http_authenticator:
          type: jwt
          challenge: false
          config:
            signing_key: |-
              -----BEGIN PUBLIC KEY-----
              123123abcbc
              -----END PUBLIC KEY-----
            subject_key: "service:username"
            jwt_header: "Authorization"
        authentication_backend:
          type: noop
User cache

When using the JWT authentication mechanism it is recommended to switch off the Search Guard user cache as each token contains the complete description of the user; this can be done by adding the following setting to elasticsearch.yml:

searchguard.cache.ttl_minutes: 0

Each node must be restarted after writing the setting.

Roles

It is possible to specify user roles in a token claim by setting the roles_key attribute in the authenticator configuration to the desired claim name, for example:

#...
      jwt_auth_domain:
        enabled: true
        order: 1
        http_authenticator:
          type: jwt
          challenge: false
          config:
            roles_key: "roles"
            signing_key: "cGFzc3dvcmQ="
            jwt_header: "Authorization"
#...

After the attribute is set and the configuration is updated, it is possible to assign backend roles to the user by setting the claim defined in http_authenticator.config.roles_key in the token payload, for example :

{
  "sub": "sirenuser",
  "exp": 1495711765,
  "roles": "sales,marketing"
}

Note that to map roles set in the JWT token to Search Guard roles you must define a role mapping such as the following:

Figure 10. JWT role mapping
JWT role mapping


Verification

To verify that Search Guard JWT authentication is working correctly you can generate a JWT token from your application and pass it to Elasticsearch using curl’s -H option, for example:

curl -k -H "Content-Type: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJraWJpdXNlciJ9.tqCYxJsORvro59Q01J9HUeFpQtauc81CcTlS5bVl93Y" https://localhost:9200/_searchguard/authinfo

To test if it is working correctly before the application is ready, you can use the jwt.io debugger to generate tokens using the signing key defined in sg_config.yml.

Siren Investigate JWT configuration

To enable JWT support in Siren Investigate, set the investigate_access_control.backends.searchguard.authenticator option to http-jwt, in investigate.yml, for example:

investigate_access_control:
  #... existing options
  backends:
    searchguard:
      #... existing options
      authenticator: 'http-jwt'

Then restart Siren Investigate and open it in a browser; you should get a blank page and the URL should end with login.

To test JWT authentication, open your browser console (Ctrl+Shift+I on Chrome and Firefox) and call setJWTToken of the sireninvestigate object, for example:

.sireninvestigate
.setJWTToken(yourtoken)
.then(function() {
  console.log('JWT token set.');
})
.catch(function(error) {
  console.log('An error occurred setting the token.');
});

After the token is set, Siren Investigate will store it in an encrypted cookie and send it in every request to the backend; the backend will then forward the JWT token to Search Guard to authenticate the user.

After the token is set, you can switch to the desired Siren Investigate URL by changing location.href.

When the user is logged out from the main application, sessionStorage and localStorage should be cleared.

For more information on how to call setJWTToken from the parent frame, see 3.12. Legacy REST datasources.3.12. Legacy REST datasources