Using personal API tokens

November 14, 2023

With the personal API tokens module, you can use tokens instead of your credentials to make calls to Jahia APIs, such as GraphQL API and others.

Personal API tokens provide many benefits, including isolation of security credentials between various usages and platforms. While a username and password is unique for a specific user, many security tokens can be attached to an individual user. If a token is considered compromised, that single token can easily be disabled or deleted to prevent its future use without impacting any platforms using other tokens generated for that user. Alternatively, dealing with compromised username and password credentials involves modifying those credentials on all multiple platforms.

As a best practice, Jahia recommends that you create a separate token for each external service that needs to interact with the system APIs. This makes it easier for you to manage tokens that are compromised or lost.

When created, a token is attached to its “creator” user and benefits from the same level of authorization as its creator. For this reason, treat tokens with the same level of precaution as traditional credentials.

Installing the module

The personal API tokens module (module ID: personal-api-tokens) is compatible with Jahia 8.0.1.0 and above and can be easily installed by adding the module in Jahia Administration>Modules and Extensions>Modules. For information on adding the module, see the Installing a module tutorial.

Existing tokens are stored in the JCR and persist across Jahia upgrades as well as module upgrades.

Compatibility

The Personal API tokens module is compatible with Jahia 8.0.1.0 with some limitations, and supports the entire feature set from Jahia 8.0.2.0. With Jahia 8.0.1.0, automatically deleting Groovy scripts when creating and managing tokens through the filesystem is not available. All other functionality, such as creating and using tokens through the UI or API, is supported.

Creating a token

Tokens are active by default and can easily be disabled from the tokens list.

Access to the "My API tokens" page is restricted to users with permission "Personal api tokens"

To create a token:

  1. In Jahia, navigate to Dashboard>My API tokens.
  2. Click Create Token.
  3. In the Create a personal API token dialog, provide the following information:
    • Name
      The name of the token is unique for each user. It is used only for token management purposes to identify the token’s purpose by the user.
    • Expiration date
      The expiry date is the date after which any calls to the API are deemed invalid. Once the expiry date is reached, tokens are not deleted and are not usable unless you update the expiration date to a later date.
      create-personal-api-token-01.png
  4. Click Create. The token displays on the page. This is the only time the token is visible to you. This token string is a sensitive piece of information. Make sure to keep it safe.
    create-personal-api-token-02.png
  5. To copy the token, click Copy. Then copy the token value to a safe location.
  6. Click Close.

The token displays in the list of tokens on the My API tokens page.

Token format

Tokens are generated using standard mechanisms and contain an access key and secret key. The access key is stored as part of the token and you can derived it using our CLI tool:

java -jar personal-api-tokens-1.0.0-cli.jar --get-key YOUR_TOKEN

The implementation for getKey is available here on GitHub which shows how the key is derived from the token. A custom implementation may be necessary.

Using tokens

You can simply pass a token in the authorization header in any API call by prefixing it with APIToken.

For example, the Apollo client would be instantiated like this in Typescript:


export const apolloClient = (token: string): ApolloClient => {
    return new ApolloClient({
        link: new HttpLink({
            uri: `JAHIA_URL/modules/graphql`,
            headers: {
              authorization: `APIToken ${token}`
            }
        }),
        cache: new InMemoryCache(),
        defaultOptions: {
            query: {
                fetchPolicy: 'no-cache',
            },
        },
    })
}

Or, to retrieve the result of the healthcheck, it would be like that:

curl -H "Authorization: APIToken XXXXXXXXXX" JAHIA_URL/modules/healthcheck

Managing tokens

Access to the "My API tokens" page is restricted to users with permission "Personal api tokens"

Tokens that you create display on the My API tokens page. The list shows information such as the name of the token, its access key, and expiration date. You can delete, activate and disable tokens from this page.

managing-tokens-01.png

Note: Tokens are only visible to users once when they are created. None of the information provided here is sufficient to perform an API call.

To delete a token:

  1. Click Delete under Actions beside the token that you want to delete.
  2. In the Confirmation dialog, click Delete Forever.

Once deleted, a token is gone forever and subsequent API calls using that token are denied.

To activate or disable a token:

Click the More actions button under Actions and select Activate or Disable.

The status changes to Active or Disabled for the token. Any API call using a disable token is denied.

Managing tokens for other users

Although you cannot create tokens for other users, you can delete, activate, and disable tokens that you have permissions to view.

To manage another user’s token:

  1. Navigate to Administration>Users and Roles>User API tokens.
    create-personal-api-token-03.png
  2. In the search box, enter a user name to filter the list of users.
  3. Delete, activate, and disable the tokens that you want to update.

Managing tokens through the API

Tokens can also be managed through our GraphQL API. The entry point for such operations are located under admin.personalAPITokens.

In addition to features provided in the UI, the GraphQL API also provides features to:

  • Check if a token is valid for authentication (verifyToken)
  • Update a token’s name or expiry date

Managing tokens through the filesystem

Tokens can also be created through the filesystem. This is useful for situations where tokens must be created automatically during Jahia’s first startup. This makes use of an existing Jahia feature which executes Groovy scripts placed in the digital-factory-data/patches/groovy/ folder.

When creating tokens from the filesystem, the token is supplied to the system by the developer and the supplied token must have a valid format.

Our CLI tool can be used to generate valid tokens.

java -jar personal-api-tokens-1.0.0-SNAPSHOT-cli.jar

returns


{"token": "b765L5rYQO+vuQW+tWZZ4nYIp3/Qv2wk2Z27fNtmgOY=", "key": "6fbeb92f-9ad8-40ef-afb9-05beb56659e2"}

Creating a token through the filesystem

You can use the following script to create a token through the filesystem, where setResult(“remove”) indicates that the Groovy script is deleted after processing.


setResult("remove");
org.jahia.services.content.JCRTemplate.getInstance().doExecuteWithSystemSession({ session ->
    org.jahia.osgi.BundleUtils.getOsgiService("org.jahia.modules.apitokens.TokenService")
        .tokenBuilder("/users/root", "test-token12345", session)
        .setToken("kgHNm05iQV61I+GY3X5HVr13i866HAAsyou8G+eGubk=")
        .setActive(true)
        .setExpirationDate(new org.joda.time.DateTime('2021-12-31').toCalendar(Locale.getDefault()))
        .create()
    session.save();
})

Deleting a token through the filesystem

The following script deletes a token through the filesystem.


setResult("remove");
org.jahia.services.content.JCRTemplate.getInstance().doExecuteWithSystemSession({ session ->
    org.jahia.osgi.BundleUtils.getOsgiService("org.jahia.modules.apitokens.TokenService").deleteToken("9201cd9b-4e62-415e-b523-e198dd7e4756", session)
    session.save();
})

Updating a token through the filesystem

The following script updates a token through the filesystem.


setResult("remove");
org.jahia.services.content.JCRTemplate.getInstance().doExecuteWithSystemSession({ session ->
    def service = org.jahia.osgi.BundleUtils.getOsgiService("org.jahia.modules.apitokens.TokenService")
    def tokenDetails = service.getTokenDetails("9201cd9b-4e62-415e-b523-e198dd7e4756", session)
    tokenDetails.setActive(false)
    service.updateToken(tokenDetails, session)
    session.save();
})