Identity & Access

Purpose

Identity is the security kernel. It is small, strictly bounded, and auditable — the module every other module trusts. Its responsibilities are:

All other modules receive a pre-verified {tenant_id, user_id, scopes} context and call Identity only for explicit authz checks; they never handle raw credentials.

Data owned

Table Purpose
tenants Tenant registry, plan, status
users User accounts, password hashes, MFA state
memberships User ↔ tenant ↔ role mapping
roles Role definitions (owner, admin, member, viewer)
api_tokens Hashed API tokens with scope + expiry
sessions Active session state (refresh token hashes)

Internal API

Identity exposes Identity.* gRPC methods:

Method Description
Identity.IntrospectToken Verify a bearer token; return claims
Identity.CheckPermission RBAC decision: allow / deny for principal + action + resource
Identity.RegisterUser Create user + initial membership
Identity.IssueToken Exchange credentials or refresh token for access token
Identity.RevokeToken Invalidate a session or API token

Authentication model

BitVault implements OAuth 2.1 + OIDC (ADR-0010):

API tokens

RBAC model

Roles are tenant-scoped; a user may have different roles in different tenants.

Role Capabilities
owner Full control including billing and tenant deletion
admin User management, share management, all file ops
member File read/write within granted paths
viewer Read-only access to explicitly granted nodes

Default policy is deny. Access is granted only by an explicit role assignment or a Sharing grant.

Resource-level grants (e.g., “user X can edit folder Y”) are resolved by Sharing and composed with the RBAC role check in Identity.

Hot path optimization

Token introspection and authz decisions are the single hottest path in the system — called on every request. Results are cached in Redis with a short TTL (typically 30 s).

:::warning Token introspection must be called on every request. Do not rely on in-process memory caches across request boundaries — the Redis TTL is the cache; in-process caches can serve a revoked token. A revoked session must be respected within the Redis TTL window. :::

Events emitted

Event Trigger
UserCreated New user registered
TenantSuspended Tenant status set to suspended
TokenRevoked Session or API token explicitly revoked