0.0
The project is in a healthy, maintained state
Backend SDK for torii. Verify end-user JWTs without a per-request round-trip, call /api/server/v1/** with a secret key, and react to events from torii. Ships with Rack middleware that works with Rails, Sinatra, Roda, and anything else Rack-compatible.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 3.1
~> 13.0
~> 3.13
~> 1.8

Runtime

~> 2.8
~> 1.4
 Project Readme

torii-backend (Ruby)

Backend SDK for torii — verify end-user JWTs without a per-request round trip and manage users from your Ruby server.

v0.x — API may still change.

Setup

  1. Sign in to app.torii.so and from your dashboard copy:

    • your issuer URL (e.g. https://acme.torii.so)
    • a secret key (sk_test_… for development, sk_live_… for production)
  2. Install the gem:

    gem install torii-backend

    or in your Gemfile:

    gem 'torii-backend'

    Requires Ruby 3.1+.

  3. Verify an end-user JWT:

    require 'torii/backend'
    
    auth = Torii::Backend.verify_token(token, issuer: 'https://acme.torii.so')
    auth.user_id          # => "user_abc"
    auth.environment_id   # => "env_xyz"
    auth.email_verified   # => true

    The first call fetches the issuer's JWKS at {issuer}/_torii/.well-known/jwks.json; subsequent calls reuse a process-wide cache (5-minute TTL, automatic refresh on kid miss). ES256 only.

  4. Call the backend REST API:

    torii = Torii::Backend::Client.new(secret_key: ENV.fetch('TORII_SECRET_KEY'))
    user = torii.users.get(user_id)

Rack middleware (Rails / Sinatra / Roda)

# config/application.rb (Rails)
config.middleware.use Torii::Backend::Rack::RequireAuth,
  issuer: 'https://acme.torii.so'
# config.ru (Sinatra / plain Rack)
use Torii::Backend::Rack::RequireAuth, issuer: 'https://acme.torii.so'
run MyApp

On success the verified Torii::Backend::Auth is placed at env['torii.auth']. On failure the middleware short-circuits with a 401 JSON body:

{ "error": { "code": "authentication_failed", "message": "..." } }

For ad-hoc verification outside Rack:

auth = Torii::Backend.authenticate_request(
  request.env,
  issuer: 'https://acme.torii.so',
)

authenticate_request accepts a Rack env, a plain Hash of headers (string or symbol keys), or anything that responds to #each with [name, value] pairs.

Backend API (REST client)

page = torii.users.list(limit: 50)
page[:items]        # => [{ id: "...", ... }, ...]
page[:next_cursor]  # => "cursor_..." or nil
page[:has_more]     # => true / false

user = torii.users.create(email: 'x@y.com')
torii.users.update(user[:id], name: Torii::Backend::Patch.set('New name'))
torii.users.ban(user[:id])

sessions = torii.sessions.list_for_user(user[:id])
torii.sessions.revoke_all_for_user(user[:id])

The REST client is generated from the OpenAPI spec at spec/server-v1.json via openapi-generator-cli (target: ruby); hand-written wrappers in lib/torii/backend/client.rb give it the Ruby-idiomatic surface above.

Partial updates

PATCH fields are tri-state: set to a value, clear (JSON null on the wire), or leave alone. Ruby keyword args can't express that on their own (a literal nil can't be told apart from "absent"), so every kwarg accepted by update must be wrapped in Torii::Backend::Patch:

torii.users.update(user_id,
  name: Torii::Backend::Patch.set('New name'),  # update the name
  phone: Torii::Backend::Patch.set(nil),        # null on the wire
  # locale, address, date_of_birth omitted -> untouched
)

Patch.set(value) updates the field; Patch.set(nil) clears it; omitted kwargs are left untouched on the server.

Errors

  • Torii::Backend::Error — base.
  • Torii::Backend::AuthError — raised by verify_token / authenticate_request.
  • Torii::Backend::ApiError — raised by REST calls on non-2xx. Inspect status, code, support_id, body.

License

MIT