session
Version, currently 1.0.2431 versions
- 1.0.31latestMar 8, 2026
- 1.0.30not indexedMar 8, 2026
- 1.0.29not indexedMar 8, 2026
- 1.0.28not indexedMar 8, 2026
- 1.0.27not indexedMar 8, 2026
- 1.0.26not indexedMar 8, 2026
- 1.0.25not indexedMar 8, 2026
- 1.0.24not indexedMar 8, 2026
- 1.0.23not indexedMar 8, 2026
- 1.0.22not indexedMar 8, 2026
- 1.0.21not indexedMar 8, 2026
- 1.0.20not indexedMar 8, 2026
- 1.0.19not indexedMar 8, 2026
- 1.0.18not indexedMar 8, 2026
- 1.0.17not indexedMar 8, 2026
- 1.0.16not indexedMar 8, 2026
- 1.0.15not indexedMar 8, 2026
- 1.0.14not indexedMar 8, 2026
- 1.0.13not indexedMar 8, 2026
- 1.0.12not indexedMar 8, 2026
- 1.0.11not indexedMar 8, 2026
- 1.0.10not indexedMar 8, 2026
- 1.0.9not indexedMar 8, 2026
- 1.0.8not indexedMar 8, 2026
- 1.0.7not indexedMar 8, 2026
- 1.0.6not indexedMar 8, 2026
- 1.0.5not indexedMar 8, 2026
- 1.0.4not indexedMar 8, 2026
- 1.0.3not indexedMar 8, 2026
- 1.0.2not indexedMar 8, 2026
- 1not indexedMar 8, 2026
github.com/azutoolkit/session
Type-safe, production-ready session management for Crystal.
Nothing has been indexed for 1.0.24 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.
Installation
# Add this to your shard.yml
dependencies:
session:
github: azutoolkit/session
version: ~> 1.0.24Then run:
shards installshard.yml
No shard.yml has been indexed for 1.0.24. You can read it on the repository.
Dependencies
Unknown: the shard.yml for this version has not been read yet.
README
This README is the one indexed from the repository at its latest ref, not from the tag for this version.
Session
Type-safe, production-ready session management for Crystal.
Why Session?
| Type-Safe | Define sessions as Crystal classes with compile-time guarantees |
| Multiple Backends | Cookie, Memory, Redis, or Clustered Redis—pick what fits |
| Battle-Tested Security | AES-256 encryption, HMAC-SHA256, PBKDF2, client binding |
| Production Resilience | Circuit breakers, retry logic, graceful degradation |
| 346 Tests | Comprehensive coverage you can rely on |
Quick Start
Install (add to shard.yml):
dependencies:
session:
github: azutoolkit/session
Use (< 30 seconds to your first session):
require "session"
# Define your session data
class UserSession < Session::Base
property? authenticated : Bool = false
property username : String? = nil
end
# Configure once
Session.configure do |config|
config.secret = ENV["SESSION_SECRET"]
config.store = Session::MemoryStore(UserSession).new
end
# Create and use sessions
store = Session.config.store.not_nil!
session = store.create
session.username = "alice"
That's it. You're ready to build.
Key Features
Storage Backends
| Backend | Best For | Persistence | Multi-Node |
|---|---|---|---|
| CookieStore | Stateless apps, serverless | Client-side | Yes |
| MemoryStore | Development, single-server | None | No |
| RedisStore | Production deployments | Redis | Yes |
| ClusteredRedisStore | High-scale, multi-node | Redis + local cache | Yes |
# Cookie (stateless, client-side)
config.store = Session::CookieStore(UserSession).new
# Memory (development)
config.store = Session::MemoryStore(UserSession).new
# Redis (production)
config.store = Session::RedisStore(UserSession).new(client: Redis.new)
# Clustered Redis (high-scale production)
config.cluster.enabled = true
config.store = Session::ClusteredRedisStore(UserSession).new(client: Redis.new)
Security
- Encryption — AES-256-CBC with random IV per operation
- Signing — HMAC-SHA256 to detect tampering
- Key Derivation — Optional PBKDF2 with configurable iterations
- Client Binding — Lock sessions to IP and/or User-Agent
- Size Protection — Automatic cookie size validation (4KB limit)
Session.configure do |config|
config.secret = ENV["SESSION_SECRET"] # 32+ chars recommended
config.use_kdf = true # Enable PBKDF2
config.kdf_iterations = 100_000 # OWASP recommended
config.bind_to_ip = true # Prevent session hijacking
config.bind_to_user_agent = true
end
Resilience
- Circuit Breaker — Fail fast when backends are down
- Retry Logic — Exponential backoff with jitter
- Compression — Gzip for large session payloads
Session.configure do |config|
config.circuit_breaker_enabled = true
config.circuit_breaker_config = Session::CircuitBreakerConfig.new(
failure_threshold: 5,
reset_timeout: 30.seconds
)
config.enable_retry = true
config.retry_config = Session::RetryConfig.new(
max_attempts: 3,
base_delay: 100.milliseconds,
backoff_multiplier: 2.0
)
end
Clustering
Multi-node session management with Redis Pub/Sub invalidation and local caching.
flowchart LR
subgraph Node_A["Node A"]
A_Cache["Local Cache"]
end
subgraph Node_B["Node B"]
B_Cache["Local Cache"]
end
Redis[("Redis")]
PubSub{{"Pub/Sub"}}
A_Cache <--> Redis
B_Cache <--> Redis
A_Cache -.->|invalidate| PubSub -.->|evict| B_Cache
Session.configure do |config|
config.cluster.enabled = true
config.cluster.node_id = ENV["POD_NAME"]? || UUID.random.to_s
config.cluster.local_cache_ttl = 30.seconds
config.cluster.local_cache_max_size = 10_000
config.store = Session::ClusteredRedisStore(UserSession).new(
client: Redis.new(url: ENV["REDIS_URL"])
)
end
API Essentials
Store Operations
store = Session.config.store.not_nil!
store.create # New session
store.delete # Destroy session
store.regenerate_id # New ID, keep data (post-login security)
store.valid? # Check validity
store.current_session # Access your typed session data
store.flash # One-request flash messages
Session Object
session = store.current_session
session.session_id # Unique ID
session.username # Your session properties directly
session.valid? # Not expired?
session.expired? # Past expiration?
session.time_until_expiry # Remaining lifetime
session.touch # Extend expiration
Flash Messages
# Set (available next request)
store.flash["notice"] = "Saved successfully"
store.flash["error"] = "Something went wrong"
# Read (clears after access)
store.flash.now["notice"] # => "Saved successfully"
Query & Bulk Operations
store = Session::MemoryStore(UserSession).new
# Iterate sessions
store.each_session { |s| puts s.username }
# Find by criteria
admins = store.find_by { |s| s.roles.includes?("admin") }
# Bulk delete (e.g., revoke compromised user)
store.bulk_delete { |s| s.user_id == compromised_id }
HTTP Integration
require "http/server"
Session.configure do |config|
config.secret = ENV["SESSION_SECRET"]
config.store = Session::MemoryStore(UserSession).new
end
store = Session.config.store.not_nil!
server = HTTP::Server.new([
Session::SessionHandler.new(store),
YourAppHandler.new,
])
server.listen(8080)
The handler automatically loads sessions from cookies, validates bindings, handles corruption gracefully, and sets response cookies.
Configuration Reference
Session.configure do |config|
# Core
config.secret = ENV["SESSION_SECRET"] # Required
config.timeout = 1.hour # Session lifetime
config.session_key = "_session" # Cookie name
config.sliding_expiration = true # Extend on access
# Security
config.use_kdf = true # PBKDF2 key derivation
config.kdf_iterations = 100_000
config.bind_to_ip = true
config.bind_to_user_agent = true
config.encrypt_redis_data = true
# Performance
config.compress_data = true
config.compression_threshold = 256
# Resilience
config.enable_retry = true
config.circuit_breaker_enabled = true
# Clustering
config.cluster.enabled = true
config.cluster.local_cache_ttl = 30.seconds
config.cluster.local_cache_max_size = 10_000
# Callbacks
config.on_started = ->(id : String, session : Session::Base) { Log.info { "Session #{id} created" } }
config.on_deleted = ->(id : String, session : Session::Base) { Log.info { "Session #{id} destroyed" } }
# Metrics
config.metrics_backend = Session::Metrics::LogBackend.new
end
Documentation
Full documentation available at GitBook (or see the docs/ directory).
- Getting Started
- Configuration Guide
- Storage Backends
- Clustering Guide
- Security Best Practices
- AZU Framework Integration
- HTTP::Server Integration
- Upgrade Guide
Contributing
- Fork it
- Create your branch (
git checkout -b feature/awesome) - Write tests
- Make sure
crystal specpasses - Commit and push
- Open a PR
License
MIT — see LICENSE
Built with Crystal. Maintained by @eliasjpr.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
1.0.24- Tagged
- Mar 8, 2026
- Commit
d33b439854b9- Indexed
- not yet
Dependents
Repository
github.com/azutoolkit/session
Metadata
- Created
- Aug 16, 2026
- Updated
- Sep 19, 2026
- Synced
- Sep 19, 2026
- Versions
- 31