Directory & RBAC

Permissions managed.
Not hard-coded.

Organize users into groups. Assign roles with fine-grained permissions. Sync directories from Entra ID, Okta, or Google Workspace via SCIM.

Available on Free and above. See pricing

The model

Four primitives. One evaluation order.

RBAC is not a feature you build per app — it's a model you assemble once. AuthFI keeps the four standard primitives separate so they compose: users hold no permissions directly, groups collect users (and nest inside other groups), roles name a set of permissions, and permissions are the atomic verbs your code checks. A user's effective permission set is the union of every role reachable through their direct assignments and their group memberships, transitively.

  • Nested groups: membership inherits down the tree, so oncology-dept inside doctors grants both role sets without re-listing users.
  • Union, not override: permissions only add — there's no surprising subtractive precedence to reason about during an audit.
  • The problem it removes: permission logic scattered as if (user.isAdmin) branches across services. Move the policy out of code and into data.
effective-permissions
User: Dr. Alice Chen
  ├─ Direct role: "viewer" → [read:dashboard]
  │
  ├─ Group: "doctors"
  │    └─ Role: "physician" → [read:patients, write:notes]
  │
  └─ Group: "oncology-dept"
       └─ Role: "specialist" → [read:imaging, order:labs]

Effective permissions (union):
  [read:dashboard, read:patients, write:notes,
   read:imaging, order:labs]

The set is computed at evaluation time — change a group and every member's effective access recomputes, no migration.

console.authfi.io/directory/users
UserGroupsRolesSource
Alice Chen
alice@acme.com
EngineeringadminSCIM
Bob Smith
bob@acme.com
DevOpsdeveloperSCIM
Carol Lee
carol@acme.com
FinanceviewerManual

Your identity console

Users, groups, roles — managed from one place.

Every identity carries its provenance. A row sourced from SCIM is owned by the customer's directory — AuthFI mirrors it and never lets a local edit drift from the system of record. A Manual row is one you created directly for a contractor or service account. The same table is the source for the SDK, the eBPF data plane, and the cloud IAM mappings downstream, so what an admin sees is exactly what gets enforced.

Users

People who access your app. Created via signup, SSO, SCIM, or API.

Groups

Collections of users. Synced from Entra ID or managed manually. Groups can nest.

Roles

Named sets of permissions. Assigned to users or groups.

Permissions

Granular actions like read:patients, write:notes.

Lifecycle

Provisioned in seconds. Deprovisioned the moment HR clicks.

SCIM 2.0 is the standard wire format for moving identity between systems — a JSON-over-HTTPS schema (RFC 7643) and protocol (RFC 7644) that the customer's IdP already speaks. When someone is created in Entra ID, the IdP POSTs a User resource to AuthFI; a group change is a PATCH to a Group's members. The event that audits actually care about — offboarding — arrives as PATCH active:false, and AuthFI deactivates the user and revokes sessions in near real time.

  • The problem it removes: orphaned access — accounts that outlive the employee because no nightly CSV job told your app they left.
  • One protocol, every provider: the same SCIM endpoint backs Entra ID, Okta, Google Workspace, and OneLogin — you implement the standard once.
  • The payoff: a clean joiner-mover-leaver trail for SOC 2 and access reviews, with zero manual user admin.
scim/v2 — deprovision
PATCH /scim/v2/Users/2819c2…
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [{
    "op": "replace",
    "path": "active",
    "value": false
  }]
}

→ user disabled · sessions revoked
Protocol
SCIM 2.0 (RFC 7644)
Schema
User + Group (RFC 7643)
Transport
HTTPS · Bearer token
Deprovision
PATCH active:false

Bring your directory in

Two real ways in. Your directory stays the source of truth.

Sync cloud directories over SCIM 2.0 in minutes, or bridge on-prem Active Directory over LDAP. Either way AuthFI mirrors — it never asks you to migrate off the system you already run.

Cloud directories
SCIM 2.0 provisioning

Entra ID (Azure AD), Okta, Google Workspace, and OneLogin push users and groups to AuthFI automatically — no scripts, no nightly jobs. Provisioning happens over the standard SCIM 2.0 protocol.

Entra IDOktaGoogle Workspace
  • Create, update, and deactivate users in real time — deprovision in the IdP and access is gone in seconds.
  • Group membership maps to AuthFI roles, which grant access across app, cloud, server, and agents.
  • One push protocol for every provider — the same SCIM endpoint backs all four.
On-prem Active Directory
LDAP bridge — LDAPS :636

Already running Active Directory in your datacenter? Bind AuthFI to it over LDAP to authenticate and bridge identities without migrating off AD. Your directory of record stays exactly where it is.

  • Point AuthFI at your domain with a baseDN and match users on userPrincipalName.
  • Connections run over LDAPS on port 636 — encrypted bind, no plaintext credentials on the wire.
  • Authenticate against AD today; layer SCIM-synced cloud groups on top whenever you're ready.

One change, every enforcement point

A group is the input. Access everywhere is the output.

The directory is only useful if the membership reaches the place where access is decided. AuthFI resolves a group to its roles, packs the roles into the session's JWT, and the same claim is enforced at three layers — so one group edit in your IdP propagates from your code to the kernel to your cloud account without a deploy.

Group membership
Synced from your IdP or AD
Role + JWT claim
Effective permissions, signed
Enforced everywhere
App, cloud, server, and agents

App layer (SDK)

Permission checks in code. auth.require("read:patients") returns 403 if unauthorized.

auth.require("read:patients")

Infra layer (eBPF)

Kernel-level enforcement. JWT roles checked at the socket layer, before the request reaches your app. ~45us latency.

POST /api/patients/*  roles: [doctor]

Cloud layer (IAM)

Groups map to cloud IAM roles. group:devops -> GCP roles/editor.

group:devops -> roles/editor

Change a group once — the membership flows through the bridge into AuthFI roles and out to every enforcement point.

Why it's policy, not code

Permissions managed as data. Not branches in your codebase.

Hard-coded authorization is the cost that compounds: every new app re-implements roles, every audit re-reads source, every offboarding is a manual hunt. Pulling the model out into a synced directory turns all of that into one place to look and one place to change.

Less code to own

Authorization moves out of scattered if checks into a model your services query. The SDK call — auth.require("read:patients") — is the same line in every service, and it returns 403 when the effective set doesn't include the permission.

Less risk at offboarding

Because identities are mirrored over SCIM, a leaver disabled in the IdP is disabled in AuthFI and revoked across every enforcement layer. No app keeps its own copy of who-still-works-here to forget about.

Audits answer themselves

"Who can order:labs, and why?" resolves to a path through roles and groups, not a code review. The joiner-mover-leaver trail SOC 2 asks for is a byproduct of how provisioning already works.

Get started

Ready to get started?

Free for 5,000 monthly active users. No credit card required.