JwtSign()
Creates a signed JSON Web Token (JWT) — a compact, URL-safe token commonly used for API authentication and authorization.
Sign with a shared secret (HMAC) or a private key (RSA, EC, Ed25519).
Requires Extension: Crypto Extension
JwtSign( claims=struct, key=any, algorithm=string, expiresIn=numeric, issuer=string, audience=string, kid=string );
Returns: String
| Argument | Description |
|---|---|
|
claims
struct,
required
|
edit
JWT payload claims. Standard claims: sub, iss, aud, exp, nbf, iat, jti. Custom claims allowed. |
|
key
any,
required
|
edit
Signing key. For HMAC: string or byte array. For RSA/EC: PEM string or Java PrivateKey object. |
|
algorithm
string,
optional
|
edit
JWS algorithm: HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512. Auto-detected if omitted. |
|
expiresIn
numeric,
optional
|
edit
Token expiration in seconds from now. Sets the 'exp' claim. |
|
issuer
string,
optional
|
edit
Token issuer. Sets the 'iss' claim (overrides claims struct). |
|
audience
string,
optional
|
edit
Token audience. Sets the 'aud' claim (overrides claims struct). |
|
kid
string,
optional
|
edit
Key ID to include in the JWT header. |
Usage Notes
editAlgorithm selection: If you omit the algorithm parameter, it's auto-detected from the key type:
- RSA key → RS256
- P-256 → ES256, P-384 → ES384, P-521 → ES512
- Ed25519 → EdDSA
For HMAC (HS256/HS384/HS512), the algorithm must be specified explicitly since the key is just a string.
Claims: The iat (issued-at) claim is set automatically. If you set exp explicitly in your claims struct, it takes precedence over the expiresIn parameter.
Key security: For HMAC, your secret must be at least as long as the hash output (32 bytes for HS256, 48 for HS384, 64 for HS512). Short secrets are technically accepted but cryptographically weak.
For asymmetric algorithms (RS256, ES256, etc.), sign with the private key and verify with the public key using JwtVerify().
Examples
edit// Sign a JWT with a shared HMAC secret (simplest approach)
secret = "my-super-secret-key-that-is-at-least-256-bits-long";
token = JwtSign(
claims = { sub: "user123", role: "admin" },
key = secret,
algorithm = "HS256"
);
// token is a string like: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOi...
// Set expiration and issuer
token = JwtSign(
claims = { sub: "user123", role: "admin" },
key = secret,
algorithm = "HS256",
expiresIn = 3600, // expires in 1 hour (seconds)
issuer = "https://myapp.com",
audience = "api"
);
// The iat (issued-at) claim is set automatically
// If you set exp explicitly in claims, it takes precedence over expiresIn
// Sign with RSA keys (asymmetric - sign with private, verify with public)
keyPair = GenerateKeyPair( "RSA-2048" );
token = JwtSign(
claims = { sub: "user123", admin: true },
key = keyPair.private,
algorithm = "RS256"
);
// Sign with EC keys
keyPair = GenerateKeyPair( "P-256" );
token = JwtSign(
claims = { sub: "user123" },
key = keyPair.private,
algorithm = "ES256"
);
// Algorithm auto-detection: if you omit algorithm, it's inferred from the key type
// RSA key -> RS256, P-256 -> ES256, P-384 -> ES384, P-521 -> ES512, Ed25519 -> EdDSA
keyPair = GenerateKeyPair( "Ed25519" );
token = JwtSign( claims = { sub: "user123" }, key = keyPair.private );
// Algorithm is automatically set to EdDSA
// Positional arguments are also supported: claims, key, algorithm
token = JwtSign( { sub: "user123" }, secret, "HS256" );
See also
- Cryptography
- GenerateKeyPair()
- JwtDecode()
- JwtVerify()
- Search Issue Tracker open_in_new
- Search Lucee Test Cases open_in_new (good for further, detailed examples)