Sapling Logo

Signing a JWT in Haskell


Haskell is a popular programming language in industry and academia. It is purely functional, declarative, and statically typed.

JWT Tokens

JSON Web Tokens (JWT) are a small, secure URL-based representation of claims that may be shared between two parties. They are frequently used in online applications for functions like information sharing and authentication. Three components make up a JWT: a signature, a payload, and a header, which are separated by dots (.).

Header: The header usually consists of two elements: the signing technique (e.g., RSA, SHA256, or HMAC) and the type of token (e.g., JWT).

Payload:The claims are contained in the payload. Claims are assertions and supplementary information about an entity, usually the user. Claims can be classified as registered, public, or private. In order to provide a set of practical, interoperable claims, registered claims are a collection of preconfigured claims that are suggested but not required. Those who use JWTs are free to define public claims as they see fit. Private claims are neither registered nor public claims; rather, they are used to exchange information between persons who consent to utilizing them.

Signature: The encoded payload, the encoded header, a secret, and the header-specified procedure must all be signed in order to construct the signature portion. The purpose of the signature is to confirm that the JWT's sender is who they claim to be and to make sure the message hasn't been altered in transit.

Setup Steps

Using third-party open-source cryptography libraries instead of creating your own for several reasons. Firstly, cryptography is extremely complex and prone to subtle errors that can compromise security. Established libraries have been rigorously tested, peer-reviewed, and battle-hardened in real-world scenarios, ensuring robustness and reliability. Developers of these libraries are typically experts in the field, and the libraries are regularly updated to address new vulnerabilities and adhere to evolving security standards. Moreover, using well-known libraries saves time and resources, as implementing and maintaining a secure cryptographic solution from scratch is resource-intensive.

Sapling only checks the 'sub' (subject) and 'exp' (expiry) values on a JWT Payload, but below is a list of standard fields that can be included:

  • iss (Issuer): This claim identifies the principal that issued the JWT.
  • sub (Subject): The subject claim identifies the principal that is the subject of the JWT.
  • aud (Audience): This claim identifies the recipients that the JWT is intended for. It's a case-sensitive string or an array of strings
  • exp (Expiration Time): This claim identifies the expiration time on or after which the JWT must not be accepted for processing. It's a number representing seconds after Epoch.
  • nbf (Not Before): Identifies the time before which the JWT must not be accepted for processing, represented as a number of seconds after Epoch.
  • iat (Issued At): This claim identifies the time at which the JWT was issued. Represented as a number of seconds after Epoch.
  • jti (JWT ID): A unique identifier for the JWT, used to prevent the token from being replayed or reused. It's a case-sensitive string.

Creating a JWT Token in Haskell

Replace the private_key string with your API Private Key and the public_key string with your API Public Key. The Public Key is used to identify you and the Private Key is used to sign the claim.

In Haskell, you'd use a library like jose-jwt.

{-# LANGUAGE OverloadedStrings #-}

import Jose.Jwt
import Data.Time.Clock.POSIX (getPOSIXTime)
import Control.Monad (liftM)

main :: IO ()
main = do
    currentTime <- liftM round getPOSIXTime
    let expirationTime = currentTime + 864000 -- ten days
    let claims = mempty { unregisteredClaims = [("sub", String "public_key"), ("exp", Number $ fromIntegral expirationTime)] }
    let key = Secret "private_key"
    let token = encode [HS256] key claims
    print token

Returned result (note this will depend on when the script is run):


The Sapling SDK can be initialized with the JWT token without exposing the private/secret key. The key will stop working at the set expiration time.

    key: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwdWJsaWNfa2V5IiwiZXhwIjoxNzg2MzQwMDE4fQ.PFQSoCUQ9rcwF6ipgCmLQgxRdweulQsqZM6slAziN6U',


Addtional documentation on how to use Sapling's SDK can be accessed here: