jwt
The jwt library provides compact JWT parsing, JWS signing and
verification, JWK/JWKS key selection, and reusable registered-claim
validation predicates.
The current implementation supports native HS256
signing/verification and OpenSSL-backed RS256/ES256
verification. ES256 signatures are converted from JOSE raw
R || S encoding to DER before calling OpenSSL.
This library requires a Prolog backend supporting unbound integer arithmetic.
Requirements
The openssl command must be available on the current PATH.
On macOS, it can be installed using e.g. Homebrew:
$ brew install openssl
Or using MacPorts:
$ sudo port install openssl
On Ubuntu, it can be installed using:
$ sudo apt install openssl
On RedHat distributions (8.x and later):
$ sudo dnf install openssl
For older RedHat distributions:
$ sudo yum install openssl
On Windows, it can be installed using e.g. Chocolatey:
> choco install openssl
Loading
To load the library, load the loader.lgt file:
| ?- logtalk_load(jwt(loader)).
Testing
To test this library, load the tester.lgt file:
| ?- logtalk_load(jwt(tester)).
Basic usage
Decode a compact JWT without verifying its signature:
| ?- jwt::decode(Token, Header, Claims).
Inspect only selected header or claims data:
| ?- jwt::peek_algorithm(Token, Algorithm).
| ?- jwt::claim(Claims, sub, Subject).
Sign and verify a token using native HS256 support:
| ?- Header = {alg-'HS256', typ-'JWT'},
Claims = {sub-'123', exp-4102444800},
jwt::sign(Header, Claims, 'shared-secret', Token, []),
jwt::verify(Token, 'shared-secret', VerifiedClaims, []).
Validate claims independently from signature verification:
| ?- Policy = [
claim(iss, expected('https://issuer.example')),
claim(aud, contains('client-id')),
claim(exp, time(expiration))
],
jwt::validate_claims(Claims, Policy, [now(1700000001)]).
Verify an asymmetric token using a JWK Set. The library selects a key
matching the JWT header alg and optional kid values:
| ?- JWKSet = {keys-[PublicJWK]},
jwt::verify(Token, JWKSet, Claims, [
allow_algorithms(['RS256', 'ES256']),
claim_policy([
claim(iss, expected('https://issuer.example')),
claim(aud, contains('client-id'))
])
]).
Use the openssl_executable/1 option when the OpenSSL command is not
named openssl or is not found in the default command search path:
| ?- jwt::verify(Token, JWKSet, Claims, [
openssl_executable('/opt/local/bin/openssl')
]).