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": "okera.com",
"groups": [
"web_user",
"philatelist",
"cat_person"
],
"exp": 1590510807
}
Okera can be configured for JWT support using two approaches:
- Provide services with the public key used to verify the tokens and the algorithm used (RSA256 or RSA512).
- Configure an endpoint for validating tokens.
For either of these approaches, you must also provide:
- A system token that Okera uses internally for interservice communication.
- 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 aretrue
orfalse
. The default isfalse
.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 withJWT_PUBLIC_KEY
. The order of the values must match the order specified for the correspondingJWT_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 ofokera
and groups ofroot
. 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/id_rsa.pub
- the JWT public key.auth/system.token
- the system token (a JWT with sub ofokera
and groups ofroot
).
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/id_rsa.pub
JWT_ALGORITHM: "RSA512"
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/id_rsa.512.pub
JWT_PRIVATE_KEY: file:///etc/id_rsa.512
JWT_ALGORITHM: RSA512
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/id_rsa.512.pub,file:///etc/external_vendor.256.pub
JWT_PRIVATE_KEY: file:///etc/id_rsa.512
JWT_ALGORITHM: RSA512,RSA256
Scenarios¶
-
You want Okera to encode/decode its own JWT tokens, using those for authentication:
ENABLE_JWT: true
-
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/my_custom_public_key.pub JWT_ALGORITHM: RSA512 JWT_PRIVATE_KEY: file:///keys/my_custom_private_key SYSTEM_TOKEN: file:///keys/system.token
-
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/my_custom_public_key.pub,file:///keys/external_public_key.pub JWT_ALGORITHM: RSA512,RSA256 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:
JWT_AUTHENTICATION_SERVER_URL: http://10.1.10.1:8000/idp/userinfo.openid
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": "santa@okera.com"
}
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.
-
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/id_rsa.pub 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
-
okctl tokens create <username> [<groups>...]
can be used to create a new token with a particularusername
andgroups
, 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
. -
okctl tokens show <username>
can be used to show a token created usingokctl 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/id_rsa.pub
for the private and public keys respectively, andokctl
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:
- If the JWT contains a
groups
field, then the value of this field is used as the set of groups. - If an AD/LDAP group resolver is defined, then the
sub
field of the JWT is used as the user passed to the resolver. - If an endpoint-based group resolver is defined, then the
sub
field of the JWT is used as the user passed to the resolver.