⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

84codes/jwt.cr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

JWT

A Crystal library for JWT verification with RS256 and automatic JWKS fetching from OIDC providers.

Features

  • RS256 signature verification
  • Automatic JWKS fetching and caching with OIDC discovery
  • Standard claims validation (exp, iat, nbf, iss, aud)
  • Thread-safe public key caching
  • Automatic JWKS refresh with configurable TTL

Installation

Add this to your application's shard.yml:

dependencies:
  jwt:
    github: 84codes/jwt.cr

Then run:

shards install

Usage

Basic JWT Verification with JWKS

require "jwt"

# Create JWKS fetcher and start background refresh
fetcher = JWT::JWKSFetcher.new(
  issuer_url: "https://auth.example.com",
  default_cache_ttl: 1.hour
)
spawn { fetcher.refresh_loop }

# Configure and create verifier
config = JWT::VerifierConfig.new(
  expected_issuer: "https://auth.example.com",
  expected_audience: "my-api",
  verify_audience: true
)
verifier = JWT::Verifier.new(config, fetcher.public_keys)

# Verify tokens
token = verifier.verify(jwt_string)
puts token.payload["sub"]

The JWKS fetcher automatically:

  1. Fetches {issuer_url}/.well-known/openid-configuration
  2. Fetches public keys from the jwks_uri
  3. Refreshes keys based on Cache-Control headers or default_cache_ttl

Manual Decoding with Public Key

require "jwt"

# With verification
token = JWT::RS256Parser.decode(jwt_string, public_key_pem)

# Without verification (testing only)
token = JWT::RS256Parser.decode(jwt_string, "", verify: false)

Configuration

# VerifierConfig
config = JWT::VerifierConfig.new(
  expected_issuer: "https://auth.example.com",
  expected_audience: "my-api",
  verify_audience: true,
  time_tolerance: 200.milliseconds  # Clock skew tolerance for iat validation
)

# JWKSFetcher
fetcher = JWT::JWKSFetcher.new(
  issuer_url: "https://auth.example.com",
  default_cache_ttl: 1.hour  # Used if no Cache-Control header
)

# Stop the refresh loop gracefully
fetcher.stop

# Manually trigger a refresh
fetcher.trigger_refresh

Security

  • Only RS256 algorithm accepted (prevents algorithm confusion attacks)
  • Validates exp, iat, nbf time claims
  • Optional iss and aud claim validation
  • Supports multiple keys with kid (Key ID) lookup
  • Thread-safe key caching

Testing

crystal spec

License

Apache License 2.0

About

A crystal shard for handling JWT and JWKS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published