Skip to content

Authenticate Using JSON Web Tokens

Okera can use JSON Web Tokens (JWTs) for authentication. These tokens can either be generated externally and provided to ODAS, or else ODAS can be configured to work with an external service (via REST) to acquire and validate JWTs. If only JWTs are used for authentication, ODAS also requires that a system token be generated for use in authentication with internal services. This is typically a token with okera as the subject.

Okera supports the standard JWT claims including:

  • sub
  • exp
  • nbf

Okera requires that JWTs have a sub claim. For specifying groups in which the token subject is a member, Okera suggests using the claim groups and storing the associated value as a list of strings.

Example JWT payload:

  "sub": "John Doe",
  "iss": "",
  "groups": [
  "exp": 1590510807

Okera can be configured for JWT support using two approaches:

  1. Provide services with the public key used to verify the tokens and the algorithm used (RSA256 or RSA512).
  2. Configure an endpoint for validating tokens.

For either of these approaches, you must also provide:

  1. A system token that Okera uses internally for interservice communication.
  2. A separate private key and public key pair (along with the algorithm for the public key) for Okera to use to create its own tokens when needed.

Configuration Settings

The following configuration settings are used to configure JWT support:

  • ENABLE_JWT: enables the use of JSON web tokens (JWT) for authentication. Valid values are true or false. The default is false.
  • JWT_ALGORITHM: specifies the algorithm used by JWT. Supported algorithms are RSA256 and RSA512. RSA512 is the default. You can specify multiple, comma-separated values, just as with JWT_PUBLIC_KEY. The order of the values must match the order specified for the corresponding JWT_PUBLIC_KEY.
  • JWT_PUBLIC_KEY: specifies the path to the public key used to decode JWTs. You can specify multiple, comma-separated JWT public keys. When used to decode an incoming token, they are attempted in the order specified. See Public and Private Key Validation.
  • JWT_PRIVATE_KEY: specifies the path to the private key used to encode Okera-generated JWTs. Private keys should not be specified as multiple, comma-separated values. See Public and Private Key Validation.
  • SYSTEM_TOKEN: specifies the path to the JWT system token used for interservice communication. The JWT system token has a sub of okera and groups of root. See System Token.
  • JWT_AUTHENTICATION_SERVER_URL: specifies the URL for remote endpoint validation. See Remote Endpoint Validation.

If you want to use the public/private key approach, you must specify ENABLE_JWT, JWT_ALGORITHM, JWT_PUBLIC KEY, JWT_PRIVATE_KEY, and SYSTEM_TOKEN. If you want to use the endpoint validation token approach, you must specify ENABLE_JWT, SYSTEM_TOKEN, and JWT_AUTHENTICATION_SERVER_URL.

Defaults with okctl

If the ENABLE_JWT value is set to true in the configuration file and no other JWT configuration value is used, okctl will generate a private/public key and system token (using the RS512 algorithm) in the current directory:

  • .auth/id_rsa - the JWT private key
  • .auth/ - the JWT public key
  • .auth/system.token - the system token (a JWT with sub of okera and groups of root).

It will then set the following values automatically when updating the cluster configuration:

JWT_PRIVATE_KEY: file://path/to/current/dir/.auth/id_rsa
JWT_PUBLIC_KEY: file:///path/to/current/dir/.auth/
SYSTEM_TOKEN: file:///path/to/current/dir/.auth/system.token

You can disable this behavior by removing the ENABLE_JWT setting or specifying your own values for these settings.

Public and Private Key Validation

To configure the public key approach for validation, the setting JWT_PUBLIC_KEY should specify the full path to the public key used to decode JWTs and the setting JWT_PRIVATE_KEY should specify the full path to the private key used to encode Okera-generated JWTs.

Note: These keys must be in OpenSSL PKCS#8 format.

To configure the algorithm, the setting JWT_ALGORITHM must be set to a string indicating the algorithm used. Currently, supported algorithms are RSA256 and RSA512.

For example, set the following settings in the configuration file:

JWT_PUBLIC_KEY: file:///etc/
JWT_PRIVATE_KEY: file:///etc/id_rsa.512

Okera supports configuring multiple public keys and algorithms for validating JWTs. To do this, specify the public keys and algorithms in comma-delimited lists. When a token is passed, each public key in the list is used to validate it, with the token considered valid as soon as one of the keys matches.

Note: There must be the same number of algorithms specified as public keys and the algorithm order must correspond to the public key order.

For example:

JWT_PUBLIC_KEY: file:///etc/,file:///etc/
JWT_PRIVATE_KEY: file:///etc/id_rsa.512


  1. You want Okera to encode/decode its own JWT tokens, using those for authentication:

    ENABLE_JWT: true
  2. You decide to customize one of the public/private key configuration settings. When you do this, you must specify all of the required public/private key settings:

    ENABLE_JWT: true
    JWT_PUBLIC_KEY: file:///keys/
    JWT_PRIVATE_KEY: file:///keys/my_custom_private_key
    SYSTEM_TOKEN: file:///keys/system.token
  3. You decide you also want to decode tokens created by an external system. You adjust the configuration settings as follows:

    ENABLE_JWT: true
    JWT_PUBLIC_KEY: file:///keys/,file:///keys/
    JWT_PRIVATE_KEY: file:///keys/my_custom_private_key
    SYSTEM_TOKEN: file:///keys/system.token

Remote Endpoint Validation

To configure the remote endpoint approach for validation, configure an endpoint for validating tokens remotely by way of the JWT_AUTHENTICATION_SERVER_URL setting.

For example:


The call from Okera to the REST endpoint is a POST request that passes the JWT to validate as a bearer token and expects JSON as the return value. As a REST call, it looks like this:

curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer <token>' http://<ip>:<port>/<endpoint>

The return value must contain the key "sub" and the value must be a string that contains the username that corresponds to the passed token. Example:

    "sub": ""

Using Both Approaches for JWT Validation

To support both approaches, configure the settings for both, and each is instantiated. The external endpoint is used first. If the JWT is not validated by that service, it is passed to the public-key authenticator for validation.

System Token

To configure Okera to do interservice communication when JWT authentication is enabled, the setting SYSTEM_TOKEN must be set to the full path of the token to use.

For example:

SYSTEM_TOKEN: file:///path/to/system.token

This token should have a sub value of okera.

Use the okctl Utility for Token Management

The okctl utility comes with a few commands to help with token management and creation.

  1. okctl tokens init can be used to create a new public/private key pair and the system token:

    $ okctl tokens init
    2019/09/01 06:15:03 Private Key generated
    2019/09/01 06:15:03 Public key generated
    2019/09/01 06:15:03 Key saved to: .auth/
    2019/09/01 06:15:03 Key saved to: .auth/id_rsa
    2019/09/01 06:15:03 System token saved to: .auth/system.token
  2. okctl tokens create <username> [<groups>...] can be used to create a new token with a particular username and groups, using the public/private key pair in .auth/:

    $ okctl tokens create analyst analyst_group
    2019/09/01 06:17:06 Token saved to: .auth/analyst.token
    2019/09/01 06:17:06 Token: eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbmFseXN0IiwiaXNzIjoiMTkyLjE2OC4xMC44IiwiZ3JvdXBzIjpbImFuYWx5c3RfZ3JvdXAiXSwiZXhwIjoxNTc1OTgzODI2fQ.uvUSihlSfFbs4AbiU8Mldr9THG_QLuha9VJJ6LUTzznLaKNqUbsDIZWIjMPnKFc0vXrlM5VLc0onQLg8ICbquZ-Kq4O9tA91UlaOAdzLaxkUUZKYaHA85ikPBDNw-TeIy9OAQFTsATrIECPIH6EoaJ5VevyMBXXhOJ6cmSUiSIA3ozFF2qxjDr6ZHb4ciazwRyNdTKmumO5iQXU_FwUmGZc0UeaGHkXMvYcQh5p7DI0V8T8DRz8xg1mi4fkbcXEo8EFN9b3vP82xd5HaTlAt-2IZYE7NQU0UFMsSKxeLZswGT_sKkbb1DLYUwGiu28dXEQWrpfhDugHBu5FeVBVNRkBjtwEsAaycBYnEALUvxRWO77Sz-VPn2CucJ6hC_YoMQr54IVtBx7n6B67j03TrUyGwnZJjqndESnNQQ7ig8U_Ah-moNzQEzRjWT26xrj9FyF7nbQH7m3-FQMMIFreHGl99ykxxUj5lCvd4KQOqTxIxn0wxxzz7deCdcK73uH6FQ1xI8xvjrlTUHzGeJcvDPU_jEc48OhNRGpApEY_ee0Kkkt1XzwRc-MQrnW8HKsPUEJgyTWi9AAkzUXpzttvgLWmsenMbj2jmkpo0cD2ym25R7ckjqcPmuqq9Zpn7wbLFwLBYah29aRd9qtUQNr24f48ERfP0OhvpjiuMBGV3piE

    This token will be saved in .auth/<username>.token.

  3. okctl tokens show <username> can be used to show a token created using okctl tokens create:

    $ okctl tokens show analyst
    2019/09/01 06:18:17 Token: eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbmFseXN0IiwiaXNzIjoiMTkyLjE2OC4xMC44IiwiZ3JvdXBzIjpbImFuYWx5c3RfZ3JvdXAiXSwiZXhwIjoxNTc1OTgzODI2fQ.uvUSihlSfFbs4AbiU8Mldr9THG_QLuha9VJJ6LUTzznLaKNqUbsDIZWIjMPnKFc0vXrlM5VLc0onQLg8ICbquZ-Kq4O9tA91UlaOAdzLaxkUUZKYaHA85ikPBDNw-TeIy9OAQFTsATrIECPIH6EoaJ5VevyMBXXhOJ6cmSUiSIA3ozFF2qxjDr6ZHb4ciazwRyNdTKmumO5iQXU_FwUmGZc0UeaGHkXMvYcQh5p7DI0V8T8DRz8xg1mi4fkbcXEo8EFN9b3vP82xd5HaTlAt-2IZYE7NQU0UFMsSKxeLZswGT_sKkbb1DLYUwGiu28dXEQWrpfhDugHBu5FeVBVNRkBjtwEsAaycBYnEALUvxRWO77Sz-VPn2CucJ6hC_YoMQr54IVtBx7n6B67j03TrUyGwnZJjqndESnNQQ7ig8U_Ah-moNzQEzRjWT26xrj9FyF7nbQH7m3-FQMMIFreHGl99ykxxUj5lCvd4KQOqTxIxn0wxxzz7deCdcK73uH6FQ1xI8xvjrlTUHzGeJcvDPU_jEc48OhNRGpApEY_ee0Kkkt1XzwRc-MQrnW8HKsPUEJgyTWi9AAkzUXpzttvgLWmsenMbj2jmkpo0cD2ym25R7ckjqcPmuqq9Zpn7wbLFwLBYah29aRd9qtUQNr24f48ERfP0OhvpjiuMBGV3piE

Note: If you have your own pre-existing public/private key pair and would like to use okctl to create tokens, you can put those in .auth/id_rsa and .auth/ for the private and public keys respectively, and okctl will use them when creating tokens.

Group Resolution Using JWTs

When a request is authenticated with JWTs, the following sequence is used to determine what groups this request will use for the authenticated user:

  1. If the JWT contains a groups field, then the value of this field is used as the set of groups.
  2. If an AD/LDAP group resolver is defined, then the sub field of the JWT is used as the user passed to the resolver.
  3. If an endpoint-based group resolver is defined, then the sub field of the JWT is used as the user passed to the resolver.