Introduction
Better IAM is an embeddable TypeScript platform for authentication, identity provisioning, and access management that runs inside your application, on your database.
Better IAM gives an application the identity layer that is usually bought as a hosted service: multi-tenant organizations, sign-in with every modern method, fine-grained authorization, governance, and enterprise federation. It is a library, not a SaaS. It runs in your process, stores its data in your PostgreSQL, SQLite, or libSQL database, and exposes a typed API to your server and browser code.
You create one instance with betterIam(), giving it a database, a deployment secret, and the URL it is served
from, and import that instance wherever your server code needs identity or authorization:
import { } from 'better-iam';
import { } from 'better-iam/adapter-sqlite';
export const = ({
: ({ : './iam.db' }),
: ..!,
: 'https://identity.example.com',
});Why it exists
Most business software eventually needs the same identity features: customers are organizations rather than individuals, each organization wants its own roles and its own single sign-on, security teams ask who can do what and who changed it, and enterprise buyers expect SCIM provisioning, MFA policies, and an audit trail. Teams usually assemble this from several services: a hosted sign-in provider, a separate authorization service, and later a governance or provisioning tool. That works, but it has costs:
- Your identity data lives somewhere else. People, sessions, and roles sit in a vendor's database, so every permission check is a network call, and keeping that data consistent with your own records is your problem.
- Authorization is disconnected from your data. Deciding "may Alice approve this invoice?" needs the invoice's owner and amount, which the external service does not have.
- Each service has its own model. Tenants, roles, and audit logs are defined three times and reconciled by hand.
Better IAM takes the other approach: it is a library that runs inside your application and stores everything in your database, in the same transactions as your own writes. One model, one authorization engine, and one tamper-evident cover sign-in, access decisions, governance, and federation, all behind a single typed API.
When you may not need it
If your application has individual users and no organizations, roles, or enterprise customers, a simpler authentication library is enough. Better IAM earns its place when access control, multi-tenancy, and auditability are part of the product.
What it covers
Tenants and organizations
Tenant trees with isolated identity directories, invitations, sign-in aliases, and platform root administration.
Authentication
Passwords, passkeys, magic links, email and SMS codes, TOTP, trusted devices, and per-tenant sign-in policies.
Authorization
Roles, versioned JSON policies with conditions and variables, relationships (ReBAC), boundaries, and reverse queries.
Privileged access
Just-in-time elevation with approvals, access packages, temporary bindings, and configuration as code.
Governance
Access reviews, certification campaigns, separation of duties, role mining, invariants, and change previews.
Federation
OAuth/OIDC sign-in and provider, SAML SSO, SCIM in and out, and Shared Signals (CAEP/RISC).
Audit and events
A tamper-evident, hash-chained audit log with webhooks, subscribers, metrics, and spans.
Every framework
A typed client plus Next.js, React, Vue, Nuxt, SvelteKit, React Router, NestJS, Express, Hono, and Fastify integrations.
How it fits together
Every operation, whether it comes from a browser, a server action, the CLI, or a SCIM connector, runs through the same pipeline:
- Resolve the . A session cookie, bearer token, API key, or assumed role becomes a : who is calling, how they signed in, and whether they used MFA.
- Authorize. The principal's , , and in that tenant decide whether the action is allowed.
- Apply the change in one transaction in your database, so a failure leaves nothing half done.
- Record it. A hash-chained audit event is appended in the same transaction and then fans out to , in-process subscribers, and metrics.
Because there is only one path, nothing can bypass authorization or the audit log, and an administrator using the console is held to the same rules as your own API calls.
Where to go next
Quickstart
Create an instance, bootstrap a tenant, and make your first authorization check in minutes.
Installation
Packages, subpath imports, databases, and runtime requirements.
Policy playground
Evaluate policy documents in your browser with the real policy engine.
API reference
Every server API method with HTTP routes and TypeScript signatures.
Was this page helpful?
Last updated on