vaultaris /docs

Core Concepts

Understand the building blocks of Vaultaris — tenants, users, roles, groups, applications, sessions, and the security primitives that connect them.

Tenants

A tenant is the top-level isolation unit. Every resource in Vaultaris — users, roles, groups, applications, sessions, audit logs — belongs to exactly one tenant and is never visible to another.

Typical mapping:

  • SaaS product → one tenant per paying customer organization
  • Internal tooling → one tenant per business unit or environment

Tenants are identified by a UUID returned at creation. All resource routes are scoped under /api/v1/tenants/{tenant_id}/.

The master tenant (00000000-0000-0000-0000-000000000001) is reserved for instance-level administration.

Hosted tenants

A tenant whose license includes the hosting capability (granted by the control plane) can act as a host for other tenants on the same instance. Each hosted tenant is fully isolated — the host gets administrative and aggregate-stats access only, never read access to the hosted tenant's data.

Billing shadow tenants

A special tenant variant (is_billing_shadow = true) used by the cloud control plane to hold billing RBAC. Billing shadow tenants have four seeded roles (billing.owner, billing.admin, billing.finance, billing.viewer) and are excluded from OpenAPI docs. They are provisioned automatically when a user signs up via the cloud portal.

Users

A user is a person or service account that can authenticate within a tenant. Users carry:

  • Email address (unique within a tenant)
  • Argon2id-hashed password
  • Profile fields: first name, last name, display name, phone, locale, timezone, avatar URL
  • Email verification status
  • MFA enrollment (TOTP, WebAuthn / passkeys)
  • Lockout state: failed_attempts, locked_until
  • Freeze state: freeze_reason (LicenseDowngrade, Expiry, Suspension, AdminAction)

Roles

A role is a named permission set scoped to a tenant or application. Roles can be:

  • Simple — flat permission list
  • Composite — inherit permissions from other roles (is_composite = true)
  • System — built-in roles protected from modification (is_system = true)

A user's effective permissions are the union of all permissions from direct roles and roles inherited through group membership.

Permissions

A permission is the atomic authorization unit in the resource:action model (e.g. users:read, tenants:write). Permissions support ABAC conditions for attribute-based gating. They are assigned to roles.

Groups

A group is a collection of users that share role assignments. Groups support:

  • Hierarchical nesting via parent_id (path-based)
  • Identity provider allowlists — restrict which IdPs members can use
  • OAuth client allowlists
  • global_session_enabled flag for cross-domain SSO access

Applications

An application represents a logical service within a tenant. Applications can own scoped copies of OAuth clients, IdPs, roles, groups, permissions, and ABAC policies — keeping each service's authorization surface self-contained. Applications are subject to license gating (the applications feature must be enabled for the tier).

OAuth Clients

An OAuth client is the OAuth 2.0 credential set for a specific application or integration:

  • client_id (public)
  • client_secret (hashed — confidential clients only)
  • client_type: public or confidential
  • Allowed redirect URIs, grant types, scopes
  • Token lifetime overrides
  • PKCE requirement flag
  • Consent requirement flag

DPoP (Sender-Constrained Tokens)

DPoP (RFC 9449) binds access and refresh tokens to the client's key pair. The client generates an ed25519 or P-256 key pair, proves possession on every request via a DPoP header JWT, and the server rejects any request that cannot prove ownership of the key the token was issued to.

This prevents token replay: a stolen bearer token is useless without the client's private key.

Sessions

Regular sessions

Short-lived, created on authentication. Stored in PostgreSQL, tied to tenant, user, IP, and user-agent. Instantly revocable.

Global sessions

Long-lived (up to 1 week), issued when a user is in a group with global_session_enabled = true. Enables cross-domain SSO without third-party cookies. Domain transfer tokens (one-time, 60-second lifetime) carry the session across domains.

Device Registry

Every login tracks a device derived from the User-Agent string. Devices can be:

  • Trusted — marked explicitly by the user or admin
  • Revoked — blocked from further sessions
  • New device login — triggers email alert and plugin hook

Each device has a full session history. Device management is at /api/v1/tenants/{tenant_id}/users/{user_id}/devices.

Freeze / Unfreeze System

When a license downgrades or expires, Vaultaris freezes resources to bring the instance within the new limits:

  • LIFO freeze — newest resources frozen first
  • FIFO unfreeze — oldest resources restored first on upgrade
  • Skips — system admin users are never frozen
  • Admin freeze — manual freeze via admin action; never auto-unfrozen on upgrade
  • Scope — Users, OAuthClients, Applications, IdPs, Groups

Frozen resources are listed at GET /api/v1/tenants/{tenant_id}/frozen.

ABAC Policies

Attribute-based access control policies layer on top of RBAC. Each policy has:

  • resource_type + action pattern
  • effect: Allow or Deny (deny-wins)
  • priority ordering
  • conditions: 20+ operators (equals, in, gt, lte, regex, in_cidr, between, …)
  • status: Active, Inactive, or Testing

The ABAC engine evaluates after RBAC. A Deny policy short-circuits all further evaluation.

Audit Log

Every significant action produces an append-only, tamper-evident audit record with: actor, action enum, target resource, timestamp, IP, user-agent, and JSON change metadata.

Plugins

Plugins extend Vaultaris via native Rust dynamic libraries (.so / .dylib). They are compiled against the same ABI using stabby for stability guarantees.

12 plugin categories: auth_provider, identity_provider, storage_backend, notification_channel, encryption_provider, policy_engine, audit_sink, jwt_customizer, rate_limiter, metrics_collector, input_validator, lifecycle_hook.

Plugins are installed globally and activated per-tenant. Each tenant gets its own config chain and plugin instance — two tenants sharing a plugin never share state. See Plugins for the full SDK reference.

Token Types

TokenDefault lifetimePurpose
Access token1 hourBearer credential for API calls
Refresh token24 hoursExchange for new access token
ID token1 hourOIDC identity assertion
Global session token168 hours (1 week)Cross-domain SSO
Authorization code5 minutesIntermediate code in auth code flow
MFA token10 minutesIntermediate credential during MFA challenge
DPoP-bound tokensame as bearerAccess/refresh token bound to client key pair

Lifetimes are configurable per tenant and per application.