JSON Web Tokens¶
Okera can use JSON Web Tokens (JWT) 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 that the token subject is a member of, 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
}
ODAS can be configured for JWT support via two approaches:
- Providing services with both the public key used to verify the tokens and the algorithm that was used (RSA256, RSA512, etc.).
- Configuring an endpoint for validating tokens.
For either of these approaches, if you are using JWT, you will need to provide a system token that ODAS uses internally for inter-service communication.
Configuration Settings¶
The following configuration settings are used to configure JWT support:
ENABLE_JWT
JWT_ALGORITHM
JWT_PUBLIC_KEY
SYSTEM_TOKEN
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 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_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 Key Validation¶
To configure the public key approach for validation, the setting JWT_PUBLIC_KEY
, should be a full path to the public key.
Note: This key 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_ALGORITHM: RSA512
ODAS supports configuring multiple keys to use for validating JWTs passed in by users. This is accomplished by specifying the keys in a comma-delimited list. When a token is passed in, each key will be used to attempt to validate the token, with the token considered valid as soon as one of the specified keys matches.
Note: There must be the same number of algorithms specified as keys and the algorithm order must correspond to the key order
For example:
JWT_PUBLIC_KEY: file:///etc/id_rsa.512.pub,file:///etc/external_vendor.256.pub
JWT_ALGORITHM: RSA512,RSA256
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¶
If you have the requirement 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 ODAS to be able to do inter-service 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
.
Using okctl
¶
okctl
comes with a few utility 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, and okctl
will use them when creating tokens.
Group Resolution when 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 will be used as the set of groups. - If an AD/LDAP group resolver is defined, then the
sub
field of the JWT will be used as the user passed to the resolver. - If an endpoint-based group resolver is defined, then the
sub
field of the JWT will be used as the user passed to the resolver.