x.crypto.jwt #
x.crypto.jwt
x.crypto.jwt provides JSON Web Token (JWT) signing, verification, and decoding using the compact signed-token format from RFC 7519 and RFC 7515 (JWS), with algorithms from RFC 7518 (JWA) and RFC 8037 (EdDSA).
Supported Algorithms
HS256: HMAC using SHA-256 (symmetric)HS384: HMAC using SHA-384 (symmetric)HS512: HMAC using SHA-512 (symmetric)EdDSA: Ed25519 signature algorithm (asymmetric)
In accordance with security best practices, none and arbitrary unapproved algorithms are rejected by default.
Every verification call requires VerifyOptions.algorithm. Choose this algorithm from trusted application configuration for the verification key. Do not derive it from the token header. For Ed25519 public keys, always select .eddsa; selecting an HMAC algorithm would allow anyone who knows the public key to forge tokens.
Registered timestamp claims (exp, nbf, iat) use signed 64-bit integer Unix seconds. Verification rejects malformed JSON and claims that cannot be decoded as StandardClaims, even when validate_exp or validate_nbf is disabled. Timestamp strings, fractional timestamps, null registered claims, and duplicate top-level members are rejected. Audience claims support a single string; audience arrays are not supported. Headers require an explicit alg. Unsupported crit and b64 extensions, padded or noncanonical Base64url segments, and negative leeway are rejected. Leeway must be a nonnegative number of seconds.
Usage
Signing and Verifying with StandardClaims
import time
import x.crypto.jwt
fn main() {
secret := 'my-secret-key'
claims := jwt.StandardClaims{
sub: 'user-12345'
iss: 'auth.example.com'
aud: 'api.example.com'
exp: time.now().unix() + 3600
}
// Sign token
token := jwt.sign_with_secret(claims, secret, jwt.SignOptions{
algorithm: .hs256
})!
println('Token: ${token}')
// Verify token
tok := jwt.verify_with_secret[jwt.StandardClaims](token, secret, jwt.VerifyOptions{
algorithm: .hs256
expected_issuer: 'auth.example.com'
expected_audience: 'api.example.com'
})!
println('Subject: ${tok.claims.sub or { '' }}')
}
Custom Claims Struct
You can embed StandardClaims into your own custom struct:
import time
import x.crypto.jwt
struct MyClaims {
jwt.StandardClaims
pub mut:
role string
user_id int
}
fn main() {
secret := 'my-secret-key'
claims := MyClaims{
StandardClaims: jwt.StandardClaims{
sub: 'user-1'
exp: time.now().unix() + 1800
}
role: 'admin'
user_id: 101
}
token := jwt.sign_with_secret(claims, secret, jwt.SignOptions{})!
tok := jwt.verify_with_secret[MyClaims](token, secret, jwt.VerifyOptions{
algorithm: .hs256
})!
println('User ID: ${tok.claims.user_id}, Role: ${tok.claims.role}')
}
Asymmetric Signatures (EdDSA / Ed25519)
import crypto.ed25519
import x.crypto.jwt
fn main() {
pubkey, privkey := ed25519.generate_key()!
claims := jwt.StandardClaims{
sub: 'ed25519-user'
}
// Sign using Ed25519 private key
token := jwt.sign(claims, privkey, jwt.SignOptions{
algorithm: .eddsa
kid: 'key-2026'
})!
// Verify using Ed25519 public key
tok := jwt.verify[jwt.StandardClaims](token, pubkey, jwt.VerifyOptions{
algorithm: .eddsa
})!
println('Verified subject: ${tok.claims.sub or { '' }}')
}
Inspecting Header or Claims Without Verifying
import x.crypto.jwt
fn main() {
token := '...'
header := jwt.decode_header(token)!
println('Algorithm: ${header.alg}, Key ID: ${header.kid or { 'none' }}')
tok := jwt.decode[jwt.StandardClaims](token)!
println('Claimed subject: ${tok.claims.sub or { '' }}')
}
fn decode #
fn decode[T](token string) !Token[T]
decode decodes a token into Token[T] without verifying its signature.
fn decode_header #
fn decode_header(token string) !Header
decode_header parses the Header from a token string without verifying its signature.
fn decode_raw #
fn decode_raw(token string) !(Header, string)
decode_raw parses and base64url-decodes the header and payload JSON strings without verifying the signature.
fn parse_algorithm #
fn parse_algorithm(name string) !Algorithm
parse_algorithm parses a string representation of an algorithm into an Algorithm enum.
fn sign #
fn sign[T](claims T, key []u8, options SignOptions) !string
sign serializes claims to JSON, attaches a JOSE header, signs it using key, and returns the compact encoded JWT string (<header>.<payload>.<signature>).
fn sign_raw #
fn sign_raw(header Header, payload_json string, key []u8) !string
sign_raw signs an arbitrary raw JSON payload string using header and key.
fn sign_with_secret #
fn sign_with_secret[T](claims T, secret string, options SignOptions) !string
sign_with_secret is a convenience helper for signing with a string secret key.
fn verify #
fn verify[T](token string, key []u8, options VerifyOptions) !Token[T]
verify validates token signature, header, standard claims, and decodes claims into T. options.algorithm must specify the trusted algorithm associated with key.
fn verify_raw #
fn verify_raw(token string, key []u8, options VerifyOptions) !string
verify_raw verifies token structure, algorithm, signature, and standard claims, returning the decoded payload JSON string. options.algorithm must specify the trusted algorithm associated with key.
fn verify_with_secret #
fn verify_with_secret[T](token string, secret string, options VerifyOptions) !Token[T]
verify_with_secret is a convenience helper for verifying a token with a string secret key. options.algorithm must specify the trusted algorithm associated with secret.
fn Algorithm.from #
fn Algorithm.from[W](input W) !Algorithm
from returns the Algorithm value of an integer or of a field name, or an error if there is none.
enum Algorithm #
enum Algorithm {
hs256
hs384
hs512
eddsa
}
Algorithm represents the cryptographic signing algorithm used in the JWS/JWT.
fn (Algorithm) str #
fn (a Algorithm) str() string
str returns the standard string identifier (e.g. 'HS256', 'EdDSA') for the algorithm.
struct Header #
struct Header {
pub mut:
alg string = 'HS256'
typ string = 'JWT'
kid ?string
}
Header represents the JOSE Header of a JSON Web Token.
struct SignOptions #
struct SignOptions {
pub:
algorithm Algorithm = .hs256
kid ?string
}
SignOptions provides configuration options for signing tokens.
struct StandardClaims #
struct StandardClaims {
pub mut:
iss ?string // Issuer
sub ?string // Subject
aud ?string // Audience
exp ?i64 // Expiration Time (Unix timestamp in seconds)
nbf ?i64 // Not Before (Unix timestamp in seconds)
iat ?i64 // Issued At (Unix timestamp in seconds)
jti ?string // JWT ID
}
StandardClaims contains the standard registered claims defined in RFC 7519 section 4.1.
fn (StandardClaims) is_expired #
fn (c StandardClaims) is_expired(now i64) bool
is_expired returns true if exp is defined and now is at or past exp.
fn (StandardClaims) is_valid_at #
fn (c StandardClaims) is_valid_at(now i64) bool
is_valid_at checks if the claims are currently valid at timestamp now according to exp and nbf (with 0 leeway).
struct Token #
struct Token[T] {
pub:
header Header
claims T
signature []u8
raw string
}
Token represents a parsed or verified JSON Web Token.
struct VerifyOptions #
struct VerifyOptions {
pub:
algorithm Algorithm @[required]
validate_exp bool = true
validate_nbf bool = true
leeway i64
current_time ?i64
expected_issuer ?string
expected_audience ?string
expected_subject ?string
}
VerifyOptions provides configuration options for validating and verifying tokens. algorithm must be explicitly set to the trusted algorithm associated with the verification key.