jwt

JSON Web Token (JWT) encoding and decoding for Kit

Files

FileDescription
kit.tomlPackage manifest with metadata and dependencies
src/jwt.kitJWT encode/decode with HS256 and RS256/384/512
tests/test-hs256.kitTests for HS256 encode, decode, and verification
examples/basic.kitCreate, verify, and decode JWT tokens
LICENSEMIT license file

Dependencies

  • base64
  • crypto
  • rsa

Installation

kit add gitlab.com/kit-lang/packages/kit-jwt.git

Usage

import Kit.Jwt

License

MIT License - see LICENSE for details.

Exported Functions & Types

JWTError

JWT error type with specific variants for different failure modes.

Variants

JWTEncodeError {message}
JWTDecodeError {message}

encode

Create a JWT token from claims using HS256 algorithm

Encodes the provided claims as a JWT token signed with HMAC-SHA256. The header is automatically set to {"alg":"HS256","typ":"JWT"}.

Parameters:

  • - claims-json - String - The claims/payload as a JSON string
  • - secret - String - The secret key used for signing (should be strong and random)

Returns: JwtResult String - Either:- Ok token: The complete JWT token (header.payload.signature)- Err msg: Should not occur for encoding, but included for consistency

String -> String -> Result String JWTError

  claims = "{\"sub\":\"user123\",\"name\":\"Alice\",\"exp\":1735689600}"
  result = encode claims "my-secret-key"
  match result
    | Ok token -> IO.println "JWT: ${token}"
    | Err msg -> IO.println "Error: ${msg}"

Security Notes:
  - Use a strong secret (minimum 256 bits for HS256)
  - Include standard claims like "exp" (expiration) and "iat" (issued at)
  - Never expose the secret in client-side code or version control

encode-with-header

Create a JWT token with custom header fields

Similar to encode, but allows specifying custom header fields instead of using the default HS256 header. Useful for adding additional header claims like "kid" (key ID) or other metadata.

Parameters:

  • - header-json - String - The header as a JSON string (must include "alg" and "typ")
  • - claims-json - String - The claims/payload as a JSON string
  • - secret - String - The secret key used for signing

Returns: JwtResult String - Either:- Ok token: The complete JWT token with custom header- Err msg: Should not occur for encoding, but included for consistency

String -> String -> String -> Result String JWTError

  header = "{\"alg\":\"HS256\",\"typ\":\"JWT\",\"kid\":\"key-2025-01\"}"
  claims = "{\"sub\":\"user123\",\"role\":\"admin\"}"
  result = encode-with-header header claims "my-secret-key"

Note:
  - The algorithm specified in the header must be HS256 (only supported algorithm)
  - Ensure the header is valid JSON and includes required fields

decode

Decode and verify a JWT token

Returns:

String -> String -> Result {header: String, payload: String} JWTError

decode-unsafe

Decode a JWT without verifying the signature (UNSAFE - for debugging only)

String -> Result {header: String, payload: String} JWTError

verify?

Verify a JWT token is valid (returns Bool)

String -> String -> Bool

get-claims-unsafe

Get the payload (claims) as JSON string without verification

String -> Option String

get-header-unsafe

Get the header as JSON string without verification

String -> Option String

get-claims

Get claims after verification

String -> String -> Option String

get-header

Get header after verification

String -> String -> Option String

encode-rs256

Create a JWT token from claims using RS256 algorithm (RSA-SHA256)

Encodes the provided claims as a JWT token signed with RSA-SHA256. The header is automatically set to {"alg":"RS256","typ":"JWT"}.

This is the standard algorithm used for service account authentication with Google Cloud Platform and other cloud providers.

Parameters:

  • - claims-json - String - The claims/payload as a JSON string
  • - private-key-pem - String - RSA private key in PEM format

Returns: Result String JWTError:- Ok token: The complete JWT token (header.payload.signature)- Err JWTError: Error with details about what went wrong

String -> String -> Result String JWTError

  claims = "{\"iss\":\"sa@project.iam.gserviceaccount.com\",\"aud\":\"https://oauth2.googleapis.com/token\",\"exp\":1735689600}"
  pem-key = File.read "service-account-key.pem"
  match encode-rs256 claims pem-key
    | Ok token -> print "JWT: ${token}"
    | Err e -> print "Error: ${Show.show e}"

Security Notes:
  - Never expose the private key in client-side code or version control
  - Use appropriate key sizes (2048 bits minimum, 4096 recommended)
  - Include standard claims like "exp" (expiration) and "iat" (issued at)

encode-rs384

Create a JWT token from claims using RS384 algorithm (RSA-SHA384)

Similar to encode-rs256 but uses SHA-384 for the hash function, providing a higher security margin.

Parameters:

  • - claims-json - String - The claims/payload as a JSON string
  • - private-key-pem - String - RSA private key in PEM format

Returns: Result String JWTError:- Ok token: The complete JWT token (header.payload.signature)- Err JWTError: Error with details about what went wrong

String -> String -> Result String JWTError

encode-rs512

Create a JWT token from claims using RS512 algorithm (RSA-SHA512)

Similar to encode-rs256 but uses SHA-512 for the hash function, providing the highest security margin among RS* algorithms.

Parameters:

  • - claims-json - String - The claims/payload as a JSON string
  • - private-key-pem - String - RSA private key in PEM format

Returns: Result String JWTError:- Ok token: The complete JWT token (header.payload.signature)- Err JWTError: Error with details about what went wrong

String -> String -> Result String JWTError

decode-rs256

Decode and verify a JWT token signed with RS256 (RSA-SHA256)

Verifies the signature using the provided RSA public key and returns the decoded header and payload if valid.

Parameters:

  • - token - String - The JWT token to decode
  • - public-key-pem - String - RSA public key in PEM format

Returns: Result {header: String, payload: String} JWTError:- Ok {header, payload}: Decoded header and payload as JSON strings- Err JWTError: Invalid token format or signature verification failed

String -> String -> Result {header: String, payload: String} JWTError

public-key = File.read "public-key.pem"
match decode-rs256 token public-key
  | Ok result -> print "Claims: ${result.payload}"
  | Err e -> print "Error: ${Show.show e}"

decode-rs384

Decode and verify a JWT token signed with RS384 (RSA-SHA384)

Parameters:

  • - token - String - The JWT token to decode
  • - public-key-pem - String - RSA public key in PEM format

Returns: Result {header: String, payload: String} JWTError

String -> String -> Result {header: String, payload: String} JWTError

decode-rs512

Decode and verify a JWT token signed with RS512 (RSA-SHA512)

Parameters:

  • - token - String - The JWT token to decode
  • - public-key-pem - String - RSA public key in PEM format

Returns: Result {header: String, payload: String} JWTError

String -> String -> Result {header: String, payload: String} JWTError

verify-rs256?

Verify a JWT token signed with RS256 is valid (returns Bool)

Parameters:

  • - token - String - The JWT token to verify
  • - public-key-pem - String - RSA public key in PEM format

Returns: Bool - true if the token is valid, false otherwise

String -> String -> Bool

verify-rs384?

Verify a JWT token signed with RS384 is valid (returns Bool)

String -> String -> Bool

verify-rs512?

Verify a JWT token signed with RS512 is valid (returns Bool)

String -> String -> Bool

get-claims-rs256

Get claims from an RS256-signed token after verification

Parameters:

  • - token - String - The JWT token
  • - public-key-pem - String - RSA public key in PEM format

Returns: Option String - Some claims JSON if valid, None otherwise

String -> String -> Option String

get-claims-rs384

Get claims from an RS384-signed token after verification

String -> String -> Option String

get-claims-rs512

Get claims from an RS512-signed token after verification

String -> String -> Option String