Trust portal
Sign in
06Trust portal
Last reviewed 20 July 2026

Technical controls

The cryptographic, access-control, and operational primitives that protect tenant data day-to-day.

Authentication

Authentication
session_tokens
RS256 JWT · 15-min access, 7-day refreshRefresh tokens are stored as an HttpOnly, SameSite=Lax cookie scoped to /api/v1/auth/.
csrf
bearer-token auth + double-submit cookieAccess tokens travel in the Authorization header, not a cookie, so requests are not cross-site forgeable; a double-submit cookie adds defence in depth on state-changing routes.
passwords
bcrypt, cost tuned for production
api_keys
lmn_ prefix · CSPRNG · stored as a bcrypt hashShown once at creation and never displayed again; the UI forces a copy-confirm before the dialog can close.

Authorisation

  • Per-tenant roles: owner, admin, member, viewer. Mutation endpoints check role; sensitive admin actions require the owner role.
  • Cross-tenant platform admin is a separate flag (users.is_platform_admin), distinct from the per-tenant role. Required for the operator console at /admin.
  • API keys carry granular scopes; only the minimum scope set is granted per key.

Multi-tenant isolation

  • PostgreSQL row-level security with FORCE ROW LEVEL SECURITY is enabled on every tenant-scoped table. The limena_app role does not have BYPASSRLS; a query without an explicit app.current_tenant_id returns zero rows.
  • Cross-tenant operator reads (the /admin console) run over a separate maintenance database connection, isolated from tenant request sessions. Operator mutations to a tenant, such as plan, billing, trial, and deletion changes, are recorded in audit_logs.

Encryption

Encryption
in_transit
TLS 1.2+ on every public endpoint; HSTS in production
at_rest
AES-256-GCM, HKDF-derived per-tenant keysIntegration credentials (OAuth refresh tokens, third-party API keys) are encrypted on top of a master key loaded from environment secrets. The plaintext value never persists.

Audit

Every mutation and every security-relevant event (login, logout, password change, API key creation/deletion, integration connect/disconnect, AI quota trip/reset) writes to audit_logs. The log is append-only at the application layer (the limena_app role has no UPDATE or DELETE privilege on the table) and exportable to CSV from Settings → Audit log.

Rate limiting + abuse

Limits
http
IP-keyed rate limits
ai_velocity_cap
500 calls/hour per tenant (default)
ai_token_ceiling
2M / 20M / 50M tokens per month, by plan

Trips fail-soft with an in-app banner explaining the state.