Generate a JWT

JSON Web Tokens (JWTs) used for authentication by Document Engine can be generated with one of the many open source libraries that are available and listed on

Token Requirements

  • It has to include the standard claim "exp", which sets the deadline for the validity of the token. This needs to be a non-negative number using the Unix “Seconds Since the Epoch” timestamp format.

  • It has to include the user-defined claims "document_id" and "permissions".

    • "document_id" is the identifier of a document that has been previously uploaded to the server. This field has to be a string value.

    • "permissions" is a list of permission names that define which features will be accessible to the holder of this token. See the Permissions section below for more details.

  • It may include the "user_id" claim, which will be stored on any annotation created, updated, or deleted by the user.

  • It may include the "layer" claim, which defines the Instant layer that all changes will be persisted to.

  • It may include the "collaboration_permissions" claim, which defines fine-grained permissions for actions allowed by individual users when multiple users are working on the same document. See the Collaboration Permissions guide for more details.

  • It may include the "default_group" claim to control the group of created annotations, comments, and form fields.

  • It may include the "password" claim, which defines the password to be used to open password-protected PDFs.

  • It may include the "creator_name" claim, which ensures all annotations and comments are created with the specified creator name.

  • It has to be signed using an asymmetric cryptographic algorithm. Document Engine supports the algorithms RS256, RS512, ES256, and ES512. See RFC 7518 for details about specific algorithms.


Available permissions:

  • "read-document" — Required for viewing a document and its annotations. Without this permission, it won’t be possible for the user to load the document and perform any operations on it.

  • "write" — Required for creating, updating, and deleting annotations in a document. If this permission isn’t present, PSPDFKit for Web will always be in read-only mode.

  • "download" — Required for downloading and printing a document’s PDF file.

  • "cover-image" — Required for accessing the /documents/cover endpoint.

Any combination of the above permissions can be included in the permissions list when generating a JWT. Apart from that, the permissions field of a JWT may have one of the following special values:

  • "all-2017.3" will enable all permissions available in the 2017.3 release, namely "read-document", "write", and "download".

  • "all-2017.9" will enable all permissions available in the 2017.9 release, namely "read-document", "write", "download", and "cover-image".

  • "all" will enable all permissions supported by the running version of the server.

Generating Tokens

The following example shows the creation of a JWT in JavaScript using the jsonwebtoken library.

  1. Create a key via ssh-keygen:

    ssh-keygen -t rsa -b 4096 -f jwtRS256.key
    # Enter your passphrase.
    # Get the public key in PEM format:
    openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256_pub.pem
    # If the above command fails because newer versions of `ssh-keygen` output a different format,
    # convert the key to PEM like this and then repeat the `openssl` command.
    ssh-keygen -p -m PEM -t rsa -b 4096 -f jwtRS256.key
    openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256_pub.pem

The private key (jwtRS256.key) is used to sign the tokens you hand out to the clients.

The public key (jwtRS256_pub.pem) needs to be added as a JWT_PUBLIC_KEY in Document Engine’s configuration so that the server will be able to validate the tokens’ signatures but won’t be able to create valid signatures. This example assumes you chose the RS256 algorithm as the JWT_ALGORITHM in Document Engine’s configuration.


If you want to quickly test PSPDFKit for Web with your application, you can also use the key from our example apps (passphrase: _secret_). Make sure to change to a self-generated key before going into production.

  1. Install the jsonwebtoken dependency:

    npm install --save jsonwebtoken
  2. Read the private key so that it can be used to sign JWTs. In the claims, pass the document ID, the set of permissions you want to have, and the expiration. You can then use the resulting token in your application:

    const fs = require("fs");
    const jwt = require("jsonwebtoken");
    const key = fs.readFileSync("./jwtRS256.key");
    const permissions = ["read-document", "write"];
    const token = jwt.sign({document_id: "abc", permissions: permissions}, key, {
      algorithm: "RS256",
      expiresIn: 60 * 60 // 1 hour — this will set the `exp` claim for us.