PSPDFKit Server Secrets Rotation

Information

PSPDFKit Server has been deprecated and replaced by PSPDFKit Document Engine. All PSPDFKit Server and PSPDFKit for Web Server-Backed licenses will work as before and be supported until 15 May 2024 (we will contact you about license migration). To start using Document Engine, refer to the migration guide. With Document Engine, you’ll have access to robust new capabilities (read the blog for more information).

PSPDFKit Server 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.

Change in Behavior

Previously, you could configure secrets using environmental variables. However, this approach had the following disadvantages:

  • You couldn’t change secrets during runtime.

  • You couldn’t use more than one valid secret.

  • You needed to restart PSPDFKit Server.

PSPDFKit Server 2023.1.0 introduced a new mechanism for managing secrets. There’s always a “current” version of a secret that never expires. 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, current secrets are sourced from the following environmental variables to retain old behavior:

  • JWT_PUBLIC_KEY

  • SECRET_KEY_BASE

  • DASHBOARD_PASSWORD

To change this behavior, set REPLACE_SECRETS_FROM_ENV 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 PSPDFKit Server API. The secret APIs expect 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.

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"
}