Secrets Rotation

Document Engine offers the following options for authentication:

  • Dashboard password — Used to access the PSPDFKit Dashboard.
  • Secret keybase — Used for generating secret keys for the purposes of authentication.
  • Public key for authenticating JWT payloads — Used for client authentication.

Collectively, these options are referred to as secrets.

Secrets Management

You can configure secrets using environmental variables. However, this approach has the following disadvantages:

  • You can’t change secrets during runtime.
  • You can’t use more than one valid secret.
  • You need to restart Document Engine.

Document Engine provides an alternative mechanism for managing secrets: There’s always a “current” version of a secret that never expires and you can only change this current version using secret rotation. Next to the current version, you can have other secrets, but the non-current secrets need to have an expiration date.

By default, secrets are sourced from the following environmental variables:

  • JWT_PUBLIC_KEY
  • SECRET_KEY_BASE
  • DASHBOARD_PASSWORD

To change this behavior, set the REPLACE_SECRETS_FROM_ENV configuration option to false. In this case, current secrets are only sourced from environmental variables if the secrets aren’t yet set via the API. REPLACE_SECRETS_FROM_ENV must be set to false to enable secret rotation. Otherwise, secrets set via the API are replaced on every restart.

Secrets can be managed via the secrets API(opens in a new tab). The secret APIs expects the secret :type, which can be jwt, dashboard_password, or secret_key_base.

Adding a New Secret

To add a new secret, use the following request:

POST /api/secrets/:type
Content-Type: application/json
Authorization: Token token="<secret token>"
{
"secret": "my new secret string",
"expiresAt": "2023-01-01T12:00:00.000000Z"
}

The secret field is the new secret. expiresAt sets the expiration date for the secret. The date and time are in UTC in ISO 8601 format(opens in a new tab).

Listing Secrets

To list the IDs and expiry dates of existing secrets, use the following request:

GET /api/secrets/:type
Authorization: Token token="<secret token>"

An example response is the following:

[
{
"id": 1,
"expiresAt": null
},
{
"id": 2,
"expiresAt": "2023-01-01T12:00:00.000000Z"
},
...
]

Only non-expired secrets are returned. For the current secret, the expiresAt field is null.

Rotating Secrets

Current secrets don’t expire. To change current secrets, rotate them using the request below:

POST /api/secrets/:type/rotate
Content-Type: application/json
Authorization: Token token="<secret token>"
{
"secret": "my new secret string"
}

Expiring Existing Secrets

To change the expiration date of secrets other than the current one, use the request below:

PATCH /api/secrets/:type/:id
Content-Type: application/json
Authorization: Token token="<secret token>"
{
"expiresAt": "2023-01-01T12:00:00.000000Z"
}