Client authentication in Nutrient Instant
Instant uses JSON Web Tokens(opens in a new tab) (JWTs) for authentication at a very granular level: the layer.
You can think of an Instant layer as a scratchpad for annotations on top of a specific PDF file in Document Engine. A PDF file can have any number of them. However, every JWT you issue for Instant references exactly one layer, so each client operates on a single layer at a time.
Security considerations
All JWTs are cryptographically signed. Generating valid JWTs on your users’ devices is possible, but refrain from doing so. It requires a trusted private key on the device, which opens additional attack vectors for little-to-no tangible benefit. Generate JWTs exclusively on your backend server.
Basic information
Any client that’s supposed to have access to a layer needs a JWT signed by your backend. At the very least, the JWT needs to specify the following information:
- The unique identifier for the PDF file in the user-defined
document_idclaim — you obtain this value when you import a PDF in Document Engine - The general permissions granted to the bearer in the user-defined
permissionsclaim — the catchall valueallcovers the simplest case - An expiration date in the standard
exp(opens in a new tab) claim — a UNIX timestamp in seconds. After it, the client must request a new JWT to keep syncing
You can revoke access at any time before the exp date, so pick expiration dates well into the future. That avoids needless roundtrips to fetch a new JWT and reauthenticate the layer.
Extended information
Alongside the claims above, Instant supports the standard nbf(opens in a new tab) and iat(opens in a new tab) claims, plus these user-defined ones:
- A unique identifier for the JWT’s user in the
user_idclaim — when omitted, Nutrient assumes an anonymous user and some functionality may be unavailable - The layer name on the PDF identified by
document_id, in thelayerclaim — when omitted, that PDF’s default layer is implied - The creator name for annotations and comments in the
creator_nameclaim — when omitted, and not set throughDocument.defaultAnnotationUsername, Nutrient prompts for one exactly once - The default group for new annotations and comments in the
groupclaim — when omitted, thenullgroup is implied. This applies only when your license includes the Collaboration Permissions component
To use the Collaboration Permissions component, the user_id claim mentioned above and the collaboration_permissions claim are both mandatory. For details on the latter, refer to the collaboration permissions overview guide.
Customizing general permissions
To limit what a client can do on a layer, replace the catchall all with an array naming each permission to grant. Web clients accept more permissions; iOS clients use these:
download(mandatory)
This permission covers the initial download of the underlying PDF file, without annotations. Instant stores that file locally and shares it across all of its layers. Include the permission anyway in every JWT you issue for Instant on iOS.
read-document(mandatory)
This permission is required to access the annotations on a layer.
write(optional)
The bearer needs this permission to create, update, or delete annotations, or to add comments on the layer. Without it, the client treats the layer as read-only. Such a client still receives changes from other clients, but cannot make changes of its own.
A JWT without the write permission suits read-only scenarios. One is the spectator side of a presenter mode. Another is a final review step before multiple parties digitally sign an agreement or contract. A third is letting users share notes with others in real time, with no risk of a reader accidentally changing something.