Skip to content
Packages

Identity, Access & Tenant Trust

身份、访问与租户信任

Authentication on Better Auth, tenant context, permission gates, audit, captcha, OAuth, and encrypted vault behavior live in one trust boundary.

8 packages, 98 source files and 37 test files in packages/iam. · Source ↗ · Docs ↗

Trust corridor

Every product action should pass through identity, tenant, permission, audit, and secret boundaries in that order.

  • @nebutra/authBetter Auth on Postgres, session-based
  • @nebutra/tenanttenant context and organization scoping
  • @nebutra/permissionsRBAC and resource-action scopes
  • @nebutra/auditsensitive operation trail
  • @nebutra/vaultlocal and KMS-backed secret storage

What it owns

  • Better Auth session/identity surface, with device-flow login and organization membership
  • Permission gates, tenant context, audit events, and vault storage
  • OAuth server and captcha boundaries for external identity flows

Where it stops

  • UI checks call IAM contracts; they do not reimplement authorization.
  • Secrets and audit behavior do not leak into app-local helpers.

How we know it works

  • auth provider abstraction tests and permission concept docs
  • audit and tenant package boundaries in AGENTS.md contracts

In code

vault.ts
1import { getVault } from "@nebutra/vault";
2
3const vault = await getVault();
4
5// Envelope encryption — AWS KMS unwraps the DEK per-record.
6const encrypted = await vault.encrypt(secretKey, {
7  tenantId: org.id,
8  metadata: { name: "OpenAI API Key", type: "api_key" },
9});
10
11const plaintext = await vault.decrypt(encrypted);

Packages

8 packages in packages/iam.

audit log · 12,847 entries · hash-verified
2sAKadmin.invite_user
14mMRbilling.cancel
1hJTauth.signin
→ hash-chained · SHA-256
audit

Hash-chained, SHA-256 append-only audit log for actor/tenant actions. SOC 2-grade tamper detection, streaming export, and replay-safe queries.

auth

Better Auth on Postgres — organization membership, device-flow login, MFA-enforced, session HMAC-signed. One identity layer, no vendor in the loop.

Select traffic lights
Verify you're human
challenge · 6 tiles
Verified
Cloudflare Turnstile1.2s solve
captcha

Bot challenge with Cloudflare Turnstile / hCaptcha / reCAPTCHA behind one verify() call. Server-side scoring, per-route enable, no third-party tracker on the client.

identity

Shared actor primitive — usr_/svc_/api_ ID space, role/membership lookup, tenant attachment. The single identity object every iam package reads.

third-party app · ‘Acme CI’
Requested scopes:
read:projectswrite:deploymentsadmin:billing
Token JWT · 1h TTL
oauth

Your own OIDC identity provider — "Sign in with Nebutra" for third-party apps. Authorization code + PKCE, refresh-token rotation, consent, clients stored in Postgres.

RBAC / ABACpolicy.matrix
admin
member
viewer
read
write
delete
defineAbility() · CASL
permissions

RBAC + ABAC engine — CASL for in-process checks. defineAbility() server, <Can /> in React.

Acme Robotics
Pro
Globex Corp
Member
Initech Labs
Member
RLS · tenantId scope · AsyncLocalStorage
tenant

Request-scoped tenant context via AsyncLocalStorage, with Prisma RLS bridge. One tenantId resolves through middleware and propagates the whole stack.

vault

Application-layer envelope encryption for customer secrets — AES-256-GCM, per-tenant DEK, KMS-wrapped. Audit-logged read/decrypt, zero plaintext at rest.