ywt/verify_key
Types
Values
pub fn decoder() -> decode.Decoder(VerifyKey)
Decodes a JSON Web Key (JWK) containing a public key into a verification key.
Use this when receiving public keys from external sources, key management services, or when implementing key rotation with public key distribution.
This function only supports RSA or Elliptic Curve keys.
Security Considerations
- Only accept keys from trusted sources
- Only accepts asymmetric public keys (EC, RSA) - never processes private key material
- Does not implement key pinning or certificate validation
Example
import gleam/json
// Receive a public key from your identity provider
let jwk_json = "{
\"kty\": \"EC\",
\"crv\": \"P-256\",
\"alg\": \"ES256\",
\"x\": \"...\",
\"y\": \"...\"
}"
case json.parse(jwk_json, verify_key.decoder()) {
Ok(verify_key) -> {
// Use this key to verify tokens from the identity provider
ywt.parse(token, using: decoder, claims: [], keys: [verify_key])
}
Error(_) -> // Handle invalid key format
}
๐ Note: Always validate that keys come from trusted sources and consider implementing key rotation mechanisms.
pub fn derived(sign_key: sign_key.SignKey) -> VerifyKey
Construct a verification key for token validation from a signing key.
Security Considerations
- For asymmetric keys (RSA/ECDSA), this extracts only the public key
- For symmetric keys (HMAC), this returns the same secret (use with caution)
- Distribute verify keys to services that only need to check token validity
- Never give signing keys to services that only need verification
Example
import gleam/crypto
let secret = crypto.strong_random_bytes(32)
// Create a signing key
let sign_key = sign_key.hs256(secret)
// Extract verification key for a service
let verify_key = verify_key.derived(sign_key)
// This token can be used to verify but not create tokens
ywt.decode(jwt_token, using: payload_decoder, claims: [], keys: [verify_key])
๐ก Best Practice: Only your auth service should have signing keys. All other services should only have verification keys.
pub fn id(key: VerifyKey) -> Result(String, Nil)
Extracts the key identifier from a verification key, if present.
This function retrieves the optional key identifier that was assigned to a key. Key identifiers are used for key selection during JWT verification.
pub fn set_decoder() -> decode.Decoder(List(VerifyKey))
Decodes a JSON Web Key Set (JWKS) into a list of verification keys.
Use this when receiving public keys from external sources, key management services, or when implementing key rotation with public key distribution.
Security Considerations
- Only accept keys from trusted sources
- Only accepts asymmetric public keys (EC, RSA) - never processes private key material
- Does not implement key pinning or certificate validation
Example
import gleam/json
// Receive a public key from your identity provider
let jwk_json = "{\"keys\": [{\"kty\": \"EC\", ...}]}"
case json.parse(jwk_json, verify_key.set_decoder()) {
Ok(verify_keys) -> {
ywt.parse(token, using: decoder, claims: [], keys: verify_keys)
}
Error(_) -> // Handle invalid key format
}
๐ Note: Always validate that keys come from trusted sources and consider implementing key rotation mechanisms.
pub fn to_jwk(key: VerifyKey) -> json.Json
Encodes a verification key into a JSON Web Key (JWK).
This function serializes a VerifyKey into the standard JWK format defined in RFC 7517,
making it suitable for key distribution, storage, or exchange with other JWT libraries
and services.
Security Considerations
- Only converts verification keys (public keys and HMAC secrets for verification)
- HMAC keys will include the secret in the JWK - distribute carefully
- For asymmetric keys, only public information is included (safe to distribute)
- Include key IDs (
kid) to enable proper key rotation and selection - Consider key expiration and rotation policies when distributing JWKs
Example
// Convert an ECDSA public key to JWK
let verify_key = verify_key.derived(ecdsa_sign_key)
let jwk = verify_key.to_jwk(verify_key)
// Serve this JWK for other services to verify your tokens
json.to_string(jwk)
// Returns: {"kty":"EC","crv":"P-256","x":"...","y":"...","alg":"ES256","kid":"key1"}
โ ๏ธ Warning: For HMAC keys, the resulting JWK contains the shared secret. Only distribute HMAC JWKs to trusted services that need to verify tokens.
pub fn to_jwks(keys: List(VerifyKey)) -> json.Json
Converts a list of verification keys to a JSON Web Key Set (JWKS) format.
This creates a standard JWKS structure containing multiple keys, which is the standard way to publish multiple verification keys for key rotation, different algorithms, or multi-tenant scenarios.
Usage
Use this to:
- Implement a JWKS endpoint (
/.well-known/jwks.json) - Support key rotation with multiple active keys
- Provide keys for different algorithms or use cases
- Enable external services to verify your JWTs
Security Considerations
- JWKS endpoints are typically public - ensure only verification keys are included
- Implement proper caching headers for JWKS endpoints (but allow for key rotation)
- For HMAC keys, be extremely careful about distribution
- Consider rate limiting your JWKS endpoint to prevent abuse
- Include appropriate CORS headers if serving to web applications
Example
// Create a JWKS with multiple keys for rotation
let current_key = verify_key.derived(current_signing_key)
let previous_key = verify_key.derived(previous_signing_key)
let backup_key = verify_key.derived(backup_signing_key)
let jwks = verify_key.to_jwks([current_key, previous_key, backup_key])
// Serve this at /.well-known/jwks.json
json.to_string(jwks)
// Returns: {"keys":[{"kty":"EC",...},{"kty":"RSA",...},{"kty":"EC",...}]}
๐ก Best Practice: Include multiple keys during rotation periods to ensure tokens signed with old keys remain valid during the transition period.