Project

crudjt

0.0
No release in over 3 years
Fast B-tree–backed token store for stateful user sessions Provides authentication and authorization across multiple processes Optimized for vertical scaling on a single server
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 1.17
~> 1.78.0
~> 1.1
~> 1.8
 Project Readme

Shows a dark logo
Ruby SDK for the fast, file-backed, scalable JSON token engine

Buy Me a Coffee

⚠️ Version 1.0.0-beta — production testing phase
API is stable. Feedback is welcome before the final 1.0.0 release

Fast B-tree–backed token store for stateful user sessions
Provides authentication and authorization across multiple processes
Optimized for vertical scaling on a single server

Installation

With Bundler:

bundle add crudjt --pre

Or via RubyGems:

gem install crudjt --pre

How to use

  • One process starts the master
  • All other processes connect to it

Start CRUDJT master (once)

Start the CRUDJT master when your application boots

Only one process can do this for a single token storage

The master process manages sessions and coordination
All functions can also be used directly from it

For containerized deployments, see: Start CRUDJT master in Docker

Generate a new secret key (terminal)

export CRUDJT_SECRET_KEY=$(openssl rand -base64 48)

Start master (ruby)

require 'crudjt'

CRUDJT::Config.start_master(
  secret_key: ENV.fetch('CRUDJT_SECRET_KEY'),
  store_jt_path: 'path/to/local/storage', # optional
  grpc_host: '127.0.0.1', # default
  grpc_port: 50051 # default
)

Important: Use the same secret_key across all sessions. If the key changes, previously stored tokens cannot be decrypted and will return nil or false

Start CRUDJT master in Docker

Create a docker-compose.yml file:

services:
  crudjt-server:
    image: coffeemainer/crudjt-server:beta
    restart: unless-stopped

    ports:
      - "${CRUDJT_CLIENT_PORT:-50051}:50051"

    volumes:
      - "${STORE_JT:-./store_jt}:/app/store_jt"
      - "${CRUDJT_SECRETS:-./crudjt_secrets}:/app/secrets"

    environment:
      CRUDJT_DOCKER_HOST: 0.0.0.0
      CRUDJT_DOCKER_PORT: 50051

Start the server:

docker-compose up -d

Ensure the secrets directory contains your secret key file at ./crudjt_secrets/secret_key.txt

For configuration details and image versions, see the CRUDJT Server on Docker Hub

Connect to an existing CRUDJT master

Use this in all other processes

Typical examples:

  • multiple local processes
  • background jobs
  • forked processes
require 'crudjt'

CRUDJT::Config.connect_to_master(
  grpc_host: '127.0.0.1', # default
  grpc_port: 50051 # default
)

Process layout

App boot
├─ Process A → start_master
├─ Process B → connect_to_master
└─ Process C → connect_to_master

C

data = { user_id: 42, role: 11 } # required
ttl = 3600 * 24 * 30 # optional: token lifetime (seconds)

# Optional: read limit
# Each read decrements the counter
# When it reaches zero — the token is deleted
silence_read = 10

token = CRUDJT.create(data, ttl: ttl, silence_read: silence_read)
# token == 'HBmKFXoXgJ46mCqer1WXyQ'
# To disable token expiration or read limits, pass `nil`
CRUDJT.create({ user_id: 42, role: 11 }, ttl: nil, silence_read: nil)

R

result = CRUDJT.read('HBmKFXoXgJ46mCqer1WXyQ')
# result == {'metadata' => {'ttl' => 101001, 'silence_read' => 9}, 'data' => {'user_id' => 42, 'role' => 11}}
# When expired or not found token
result = CRUDJT.read('HBmKFXoXgJ46mCqer1WXyQ')
# result == nil

U

data = { user_id: 42, role: 8 }
# `nil` disables limits
ttl = 600
silence_read = 100

result = CRUDJT.update('HBmKFXoXgJ46mCqer1WXyQ', data, ttl: ttl, silence_read: silence_read)
# result == true
# When expired or not found token
CRUDJT.update('HBmKFXoXgJ46mCqer1WXyQ', { user_id: 42, role: 8 })
# result == false

D

result = CRUDJT.delete('HBmKFXoXgJ46mCqer1WXyQ')
# result == true
# When expired or not found token
result = CRUDJT.delete('HBmKFXoXgJ46mCqer1WXyQ')
# result == false

Performance

Metrics will be published after 1.0.0-beta GitHub Actions builds

Storage (File-backed)

Disk footprint

Metrics will be published after 1.0.0-beta GitHub Actions builds

Path Lookup Order

Stored tokens are placed in the file system according to the following order

  1. Explicitly set via CRUDJT::Config.start_master(store_jt_path: 'custom/path/to/file_system_db')
  2. Default system location
    • Linux: /var/lib/store_jt
    • macOS: /usr/local/var/store_jt
    • Windows: C:\Program Files\store_jt
  3. Project root directory (fallback)

Storage Characteristics

  • CRUDJT automatically removing expired tokens after start and every 24 hours without blocking the main thread
  • Storage automatically fsyncs every 500ms, meanwhile tokens ​​are available from cache

Multi-process Coordination

For multi-process scenarios, CRUDJT uses gRPC over an insecure local port for same-host communication only. It is not intended for inter-machine or internet-facing usage

Limits

The library has the following limits and requirements

  • Ruby version: tested with 2.7
  • Supported platforms: Linux, macOS (x86_64 / arm64). Windows (experimental, x86_64 / arm64)
  • Maximum json size per token: 256 bytes
  • secret_key format: must be Base64
  • secret_key size: must be 32, 48, or 64 bytes

Contact & Support

Shows a dark favicon in light color mode and a white one in dark color mode

Lincense

CRUDJT is released under the MIT License

💘 Shoot your g . ? Love me out via Patreon Sponsors!