USSO-RS
Universal Single Sign-On (USSO) client for Rust microservices.
Authenticate users, validate JWTs, check authorization scopes, and manage sessions against the USSO identity platform — all with a single crate.
Features
- JWT validation — Decode and verify JWTs signed with RS256/RS384/RS512/PS256/PS384/PS512, ES256/ES384/ES512, or EdDSA (auto-detected from the JWT header). JWKS keys support both RSA and EC key types.
- API key authentication — Verify API keys against the USSO backend.
- Agent (service-to-service) auth — Generate Ed25519-signed agent JWTs and exchange them for access tokens.
- Token refresh — Automatically refresh expired access tokens via the USSO refresh endpoint.
- Scope-based authorization (RBAC) — Built-in hierarchical permission engine with wildcard path/filter matching, owner authorization, scope intersection, and filter scoring.
- Sync + Async — Every API surface is available in both blocking and async variants.
- User management — List, create, and profile users via the USSO REST API.
- Configurable — Customize header names, cookie names, algorithms, and JWKS URLs.
- Axum integration (optional) —
FromRequestPartsextractors for painless auth in axum web apps.
Quick Start
[]
= "0.3"
# Optional: axum integration
= { = "0.3", = ["axum"] }
Validate a JWT (sync)
use Usso;
let usso = new;
match usso.user_data_from_token
Validate a JWT (async)
use init_jwks_async;
use decode_token_with_jwks;
init_jwks_async.await.unwrap;
let user = decode_token_with_jwks.unwrap;
Validate with token-type enforcement
use UssoAuth;
let auth = new;
// Enforce that this must be an "access" token
let user = auth.user_data_from_token?;
API key verification
use HashMap;
let user = auth.user_data_from_api_key?;
Interact with the USSO API
use UssoClient;
let mut client = new;
let users = client.get_users?;
Agent authentication (server-to-server)
let mut client = new;
let token = client.use_agent_token?;
Authorization checks
use check_access;
let scopes = vec!;
let allowed = check_access;
Axum integration (requires axum feature)
use Arc;
use ;
use UssoAuth;
use AuthenticatedUser;
let auth = new;
async
let app: = new
.route
.layer;
Modules
| Module | Description |
|---|---|
core |
JWT decoding (RSA, EC, EdDSA, ES512), Usso and UssoAuth auth orchestrators |
config |
AuthConfig, HeaderConfig, APIHeaderConfig |
jwks |
JWKS fetching (sync/async) with global caching via OnceLock |
authorization |
Scope-based RBAC: check_access, has_subset_scope, is_authorized, owner_authorization, broadest_scope_filter, get_common_scopes |
client |
Full API client (UssoClient / AsyncUssoClient) with session management |
session |
Lightweight session wrapper (UssoSession / AsyncUssoSession) |
schemas |
Data types: UserData, Jwk (RSA + EC), Jwks, UserResponse, UserIdentifierSchema |
exceptions |
Error types: USSOError, JwksError, JwtError |
integrations |
Framework integrations (axum — feature-gated) |
utils |
Agent JWT generation and base64↔UUID conversion |
Configuration
AuthConfig
use ;
let config = AuthConfig ;
Environment
JWKS_URL=https://sso.usso.io/website/jwks.json
Algorithm Support
Token verification auto-detects the signing algorithm from the JWT header:
| Algorithm | Key Type | JWK Fields | Support |
|---|---|---|---|
| RS256 / RS384 / RS512 | RSA | n, e |
✅ |
| PS256 / PS384 / PS512 | RSA-PSS | n, e |
✅ |
| ES256 / ES384 | ECDSA (P-256, P-384) | crv, x, y |
✅ |
| ES512 | ECDSA (P-521) | crv, x, y |
✅ |
| EdDSA (Ed25519) | Edwards | x |
✅ |
Authorization System
Scopes follow the format: <action>:<resource>/<path>?<filters>
Privilege hierarchy: none(0) < read(10) < create(20) < update(30) < delete(40) < manage(50) < admin(60) < owner/*(90) < superadmin(100)
Wildcards (*) are supported in path segments and filter values:
admin:*matches any resourceread:users/*matches any sub-resource of usersread:users?region=*matches any region
Available functions
| Function | Purpose |
|---|---|
check_access |
Check if any of the user's scopes grant access to a resource |
is_authorized |
Check a single user scope against a resource path |
has_subset_scope / is_subset_scope |
Scope containment / delegation checks |
owner_authorization |
Check if a user has owner-level access via user/workspace ID filters |
broadest_scope_filter |
Pick the least restrictive filter from a list (by restriction score) |
get_common_scopes |
Intersect two scope lists, preserving permitted scopes |
get_scope_filters |
Extract filters from scopes matching an action and resource |
parse_scope |
Parse a scope string into (action, path_segments, filters) |
use ;
// Parse a scope
let = parse_scope;
// Check a single scope
let ok = is_authorized;
// Check against multiple scopes
let ok = check_access;
// Check scope containment
let ok = has_subset_scope;
// Owner authorization
let filter = from;
let ok = owner_authorization;
// Broadest (least restrictive) filter
let filters = vec!;
let broadest = broadest_scope_filter;
// Common scopes
let common = get_common_scopes;
Architecture
Your Microservice
│
├── UssoAuth ──► JWT validation (RSA / EC / EdDSA / ES512) ──► USSO Server
│ ► API key verify
│
├── UssoClient ──► User management API
│ ► Token refresh
│ ► Agent auth (Ed25519 JWT exchange)
│ ► Scope resolution
│
├── authorization (RBAC engine — 11 public functions)
├── jwks (global JWKS cache via OnceLock)
├── config (header/cookie extraction)
└── integrations (axum extractors — feature-gated)
Error Handling
| Error | HTTP Status | Description |
|---|---|---|
USSOError::InvalidSignature |
401 | JWT signature mismatch |
USSOError::InvalidToken |
401 | Malformed or unrecognized token |
USSOError::ExpiredToken |
401 | Token has expired |
USSOError::Unauthorized |
401 | Missing or invalid credentials |
USSOError::InvalidTokenType |
401 | Token type mismatch (e.g. expected access but got refresh) |
USSOError::PermissionDenied |
403 | Insufficient scope for the requested action |
Development
# Build
# Build with axum integration
# Test
# Lint
# Format
# All checks
The project uses just as a task runner. See justfile for available commands.
License
MIT — see LICENCE.txt.