JWT Authenticator

The JWT Authenticator is a secure method for applications running on various platforms to authenticate to Conjur using a unique identity token or a third-party machine identity signed by a JWT provider.

A Conjur identity can be established with varying granularity, allowing for a collection of resources to be identified to Conjur as one, or for individual workloads to be uniquely identified.

 

For a use-case scenario with GitLab, see A use-case: Conjur-GitLab Integration with JWT Authentication.

How it works

  1. An application requests an identity token from a JWT provider.

  2. The JWT provider sends a JWT back to the application.

  3. The application sends an authentication request to Conjur using the JWT Authenticator REST API.

  4. Conjur fetches a public key from the JWT provider.

  5. Conjur attempts to authenticate and authorize the request. If successful, Conjur sends a short-lived access token back to the application.

  6. The application can use the Conjur token to retrieve secrets stored in Conjur.

JSON Web Token (JWT)

A JWT is provided by a JWT provider and MUST be signed.

  • The following algorithms are supported by the JWT Authenticator.

    Signing method Algorithm

    RSA

    • RS256 - RSA using SHA-256 hash algorithm

    • RS384 - RSA using SHA-384 hash algorithm

    • RS512 - RSA using SHA-512 hash algorithm

  • The JWT must have a valid expiration date (exp claim). If there is no exp claim, or if it is invalid, the JWT authentication fails.

  • If any of the iat, nbf, or iss claims exists in the JWT, it must be valid, otherwise the JWT authentication fails.

Best practices for JWT authentication configuration

When configuring JWT authentication, you want to define the JWT Authenticator configuration and the application identity in Conjur in such a way that a 1:1 relationship exists between the application that needs to authenticate to Conjur and the application identity in Conjur.

For this purpose we recommend utilizing the JWT Authenticator's token-app-property and identity-path variables, as well as additional annotations in the application identity definition.

Where using these variables is not possible, we recommend creating as unique a combination of annotations as possible/required so that Conjur can properly distinguish between valid and invalid application identities.

Let's explore the various options for defining a relationship between the application and Conjur.

Define relationship in policy

 

We recommend using this option for production environments.

To create a 1:1 relationship between the application and a concrete application identity in Conjur, you define variables in the JWT Authenticator policy that map JWT claims to the application identity.

If you can customize the JWT, we recommend creating a custom claim and configuring the authentication to use this custom claim. This enables a direct 1:1 relationship between the applications using the JWT and Conjur, and no further identification needs to be defined.

If, however, you are not able to customize the JWT, we recommend using as many variables in the JWT Authenticator to control the number of entities that authenticate to Conjur.

Examples

Send host in authentication request

Instead of creating a 1:1 relationship described above, you can send the application path in the URL of the authentication request.

For production environments, make sure the application path is as unique as possible.

For more information about sending a JWT authentication request, see JWT Authenticator.

Authenticate to Conjur with JWT

This section describes how to set up your application to use a JWT to authenticate to Conjur.

Step 1: Before you begin

  • Make sure the time on the Conjur machine and the JWT provider time are synced. For this purpose, you can use the trusted NTP service.

  • The examples in this section assume the following:

    • Application path: host/conjur/authn-jwt/myVendor/myapps

    • Example JWT (Provider: https://vendorHost.example.com):

       
      {
        "ver": "2.0",
        "iss": "https://login.example.com",
        "sub": "AAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ",
        "aud": "6cb02021-a3f5-46a7-b123-940c78f5aef3",
        "exp": 1537361411,
        "iat": 1537274711,
        "nbf": 1537274711,
        "workspace": "production_emp",
        "group_name": "mygroup",
        "group_id": "group21",
        "team_name": "myteam",
        "team_id": "team76",
        "app_name": "myapp",
        "app_id": "app530",
        "oid": "00000000-0000-0000-66f3-3332eca7ea91",
        "tid": "9122040d-6c67-4c5b-b112-36a304b66dad",
        "nonce": "123456",
        "client_id": "s6BhgRkqt3",
        "state": "af0ifjslrkj",
        "aio": "Df2UXL1ix!lv8q5!eGbIDaky5mnOreY"
      }
  • Decide which claims in the JWT you want to use to set up the JWT authentication. As an example, we will use the name, client_id, and state claims to define the authentication.

    • Example JWT (Provider: https://vendorHost.example.com):

       
      {
        "ver": "2.0",
        "iss": "https://login.example.com",
        "sub": "AAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ",
        "aud": "6cb02021-a3f5-46a7-b123-940c78f5aef3",
        "exp": 1537361411,
        "iat": 1537274711,
        "nbf": 1537274711,
        "workspace": "production_emp",
        "group_name": "mygroup",
        "group_id": "group21",
        "team_name": "myteam",
        "team_id": "team76",
        "app_name": "myapp",
        "app_id": "app530",
        "oid": "00000000-0000-0000-66f3-3332eca7ea91",
        "tid": "9122040d-6c67-4c5b-b112-36a304b66dad",
        "nonce": "123456",
        "client_id": "s6BhgRkqt3",
        "state": "af0ifjslrkj",
        "aio": "Df2UXL1ix!lv8q5!eGbIDaky5mnOreY"
      }

Step 2: Configure the JWT Authenticator

This step describes how to configure the JWT Authenticator.

Step 3: Allowlist the JWT Authenticator

In this step, you add the JWT Authenticator to the list of allowed authenticators in Conjur.

Set the CONJUR_AUTHENTICATORS variable as an environment variable: CONJUR_AUTHENTICATORS=<authenticator-name>

 

The value for this variable must be identical to the name given to the JWT Authenticator policy ID above, excluding the conjur/ prefix.

For example:

 
CONJUR_AUTHENTICATORS=authn-jwt/myVendor

Step 4: Send an authentication request to Conjur

Use the following URI to send an authentication request Conjur:

 
POST https://<Conjur-server-hostname>/authn-jwt/<service-id>/<account>/[<host-id>]/authenticate

For example:

  • Request with token-app-property:

     
    curl -k --request POST 'https://myorg.example.com/authn-jwt/myVendor/cucumber/authenticate' --header 'Content-Type: application/x-www-form-urlencoded' --header "Accept-Encoding: base64" --data-urlencode 'jwt=eyJ0e......jjjkl'
  • Request without token-app-property:

     
    curl -k --request POST 'https://myorg.example.com/authn-jwt/myVendor/cucumber/host%2Fjwt-apps%2Fmyapp/authenticate' --header 'Content-Type: application/x-www-form-urlencoded' --header "Accept-Encoding: base64" --data-urlencode 'jwt=eyJ0e......jjjkl'

Limitations

Automatic key revocation is not supported. In case of key revocation, you need to restart the Master and Followers where the JWT Authenticator is enabled.

Troubleshooting