- Updated the document title to reflect the focus on IAM Service Architecture. - Expanded the overview section to provide a clearer description of the IAM Service's capabilities. - Enhanced the table of contents for better navigation. - Added detailed architecture diagrams illustrating the layered architecture and key components. - Included comprehensive sections on authentication flows, authorization models, caching strategies, and security architecture. - Improved overall structure and readability to facilitate understanding of the IAM Service's design and functionality. These changes aim to provide developers with a thorough understanding of the IAM Service architecture and its components.
1155 lines
34 KiB
Markdown
1155 lines
34 KiB
Markdown
# IAM Service Data Model
|
|
|
|
> **Complete Database Schema & Entity Relationships**
|
|
>
|
|
> This document describes all database models, relationships, and data architecture patterns used in the IAM Service.
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [Complete Entity Relationship Diagram](#complete-entity-relationship-diagram)
|
|
- [Model Categories](#model-categories)
|
|
- [Core Authentication Models](#core-authentication-models)
|
|
- [Authorization Models](#authorization-models)
|
|
- [Social & OIDC Models](#social--oidc-models)
|
|
- [Identity Management Models](#identity-management-models)
|
|
- [Access Management Models](#access-management-models)
|
|
- [Governance Models](#governance-models)
|
|
- [Relationships & Constraints](#relationships--constraints)
|
|
- [Data Lifecycle](#data-lifecycle)
|
|
- [Indexing Strategy](#indexing-strategy)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The IAM Service uses **PostgreSQL 14+** with **Prisma ORM** for type-safe database access. The data model consists of **30+ interconnected models** organized into 6 logical domains.
|
|
|
|
### Database Statistics
|
|
|
|
| Metric | Value |
|
|
|--------|-------|
|
|
| Total Models | 30+ |
|
|
| Total Relationships | 50+ |
|
|
| Enumerations | 11 |
|
|
| Unique Constraints | 20+ |
|
|
| Indexes | 60+ |
|
|
| Foreign Keys | 35+ |
|
|
|
|
### Model Organization
|
|
|
|
```mermaid
|
|
graph TD
|
|
DataModel[IAM Data Model<br/>30+ Models]
|
|
|
|
DataModel --> CoreAuth[Core Authentication<br/>7 models]
|
|
DataModel --> Authorization[Authorization<br/>6 models]
|
|
DataModel --> SocialOIDC[Social & OIDC<br/>2 models]
|
|
DataModel --> Identity[Identity Management<br/>6 models]
|
|
DataModel --> Access[Access Management<br/>4 models]
|
|
DataModel --> Governance[Governance<br/>3 models]
|
|
|
|
CoreAuth --> User[User]
|
|
CoreAuth --> Session[Session]
|
|
CoreAuth --> RefreshToken[RefreshToken]
|
|
CoreAuth --> AuthEvent[AuthEvent]
|
|
CoreAuth --> SocialAccount[SocialAccount]
|
|
CoreAuth --> MFADevice[MFADevice]
|
|
CoreAuth --> Policy[Policy]
|
|
|
|
Authorization --> Role[Role]
|
|
Authorization --> Permission[Permission]
|
|
Authorization --> UserRole[UserRole]
|
|
Authorization --> RolePermission[RolePermission]
|
|
Authorization --> UserPermission[UserPermission]
|
|
Authorization --> GroupPermission[GroupPermission]
|
|
|
|
Identity --> Organization[Organization]
|
|
Identity --> Group[Group]
|
|
Identity --> GroupMember[GroupMember]
|
|
Identity --> UserProfile[UserProfile]
|
|
Identity --> IdentityVerification[IdentityVerification]
|
|
|
|
Access --> AccessRequest[AccessRequest]
|
|
Access --> AccessRequestApprover[AccessRequestApprover]
|
|
Access --> AccessReview[AccessReview]
|
|
Access --> AccessReviewItem[AccessReviewItem]
|
|
|
|
Governance --> ComplianceReport[ComplianceReport]
|
|
Governance --> PolicyTemplate[PolicyTemplate]
|
|
Governance --> RiskScore[RiskScore]
|
|
|
|
style DataModel fill:#e1f5fe
|
|
style CoreAuth fill:#fff3e0
|
|
style Authorization fill:#f3e5f5
|
|
style SocialOIDC fill:#e8f5e9
|
|
style Identity fill:#fce4ec
|
|
style Access fill:#ffccbc
|
|
style Governance fill:#c8e6c9
|
|
```
|
|
|
|
---
|
|
|
|
## Complete Entity Relationship Diagram
|
|
|
|
This diagram shows all 30+ models and their relationships:
|
|
|
|
```mermaid
|
|
erDiagram
|
|
%% ============================================================================
|
|
%% Core Authentication Domain
|
|
%% ============================================================================
|
|
|
|
User ||--o{ UserRole : "has"
|
|
User ||--o{ UserPermission : "has direct"
|
|
User ||--o{ Session : "has"
|
|
User ||--o{ RefreshToken : "has"
|
|
User ||--o{ SocialAccount : "linked to"
|
|
User ||--o{ MFADevice : "has"
|
|
User ||--o{ AuthEvent : "generates"
|
|
|
|
Role ||--o{ UserRole : "assigned to users"
|
|
Role ||--o{ RolePermission : "has"
|
|
|
|
Permission ||--o{ RolePermission : "granted to roles"
|
|
Permission ||--o{ UserPermission : "granted to users"
|
|
Permission ||--o{ GroupPermission : "granted to groups"
|
|
|
|
%% ============================================================================
|
|
%% Identity Management Domain
|
|
%% ============================================================================
|
|
|
|
Organization ||--o{ User : "contains"
|
|
Organization ||--o{ Group : "contains"
|
|
Organization ||--o{ Policy : "has"
|
|
Organization ||--o{ Organization : "parent/child"
|
|
|
|
Group ||--o{ GroupMember : "has members"
|
|
Group ||--o{ GroupPermission : "has permissions"
|
|
|
|
User ||--o{ GroupMember : "member of"
|
|
User ||--|| UserProfile : "has profile"
|
|
User ||--o{ IdentityVerification : "has verifications"
|
|
|
|
%% ============================================================================
|
|
%% Access Management Domain
|
|
%% ============================================================================
|
|
|
|
User ||--o{ AccessRequest : "creates"
|
|
AccessRequest ||--o{ AccessRequestApprover : "has approvers"
|
|
|
|
AccessReview ||--o{ AccessReviewItem : "contains items"
|
|
|
|
%% ============================================================================
|
|
%% Governance Domain
|
|
%% ============================================================================
|
|
|
|
User ||--o{ RiskScore : "has risk scores"
|
|
|
|
%% ============================================================================
|
|
%% Model Details
|
|
%% ============================================================================
|
|
|
|
User {
|
|
string id PK "cuid primary key"
|
|
string email UK "unique email address"
|
|
string username UK "unique username"
|
|
string passwordHash "bcrypt hashed password"
|
|
boolean isActive "account active status"
|
|
boolean emailVerified "email verified flag"
|
|
boolean mfaEnabled "MFA enabled flag"
|
|
string mfaSecret "TOTP secret (encrypted)"
|
|
datetime lastLoginAt "last login timestamp"
|
|
int loginCount "total login count"
|
|
string organizationId FK "organization reference"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
Role {
|
|
string id PK "cuid primary key"
|
|
string name UK "unique role name"
|
|
string displayName "human-readable name"
|
|
string description "role description"
|
|
boolean isSystem "system role flag"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
Permission {
|
|
string id PK "cuid primary key"
|
|
string resource "resource type"
|
|
string action "action type"
|
|
string scope "access scope"
|
|
string description "permission description"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
UserRole {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string roleId FK "role reference"
|
|
string grantedBy "granter user ID"
|
|
datetime expiresAt "expiration timestamp"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
RolePermission {
|
|
string id PK "cuid primary key"
|
|
string roleId FK "role reference"
|
|
string permissionId FK "permission reference"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
UserPermission {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string permissionId FK "permission reference"
|
|
boolean granted "grant or deny"
|
|
string grantedBy "granter user ID"
|
|
datetime expiresAt "expiration timestamp"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
Session {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string deviceId "device identifier"
|
|
string deviceName "device name"
|
|
string ipAddress "IP address"
|
|
string userAgent "user agent string"
|
|
string fingerprint "device fingerprint"
|
|
boolean isActive "session active flag"
|
|
datetime expiresAt "expiration timestamp"
|
|
datetime createdAt "creation timestamp"
|
|
datetime lastActivityAt "last activity timestamp"
|
|
}
|
|
|
|
RefreshToken {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string token UK "token value"
|
|
string family "token family ID"
|
|
string deviceId "device identifier"
|
|
string ipAddress "IP address"
|
|
string userAgent "user agent string"
|
|
datetime expiresAt "expiration timestamp"
|
|
datetime revokedAt "revocation timestamp"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
SocialAccount {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
enum provider "OAuth provider"
|
|
string providerId "provider user ID"
|
|
string email "provider email"
|
|
string name "provider name"
|
|
string avatar "avatar URL"
|
|
text accessToken "OAuth access token"
|
|
text refreshToken "OAuth refresh token"
|
|
datetime expiresAt "token expiration"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
MFADevice {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
enum type "MFA type (TOTP/WEBAUTHN)"
|
|
string name "device name"
|
|
string secret "TOTP secret"
|
|
string credentialId "WebAuthn credential ID"
|
|
text publicKey "WebAuthn public key"
|
|
int counter "WebAuthn counter"
|
|
boolean isActive "device active flag"
|
|
datetime lastUsedAt "last use timestamp"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
AuthEvent {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string eventType "event type"
|
|
json eventData "event details"
|
|
string ipAddress "IP address"
|
|
string userAgent "user agent string"
|
|
boolean success "success flag"
|
|
text errorMessage "error message"
|
|
datetime timestamp "event timestamp"
|
|
}
|
|
|
|
Policy {
|
|
string id PK "cuid primary key"
|
|
string name UK "unique policy name"
|
|
string description "policy description"
|
|
string resource "target resource"
|
|
json condition "policy conditions"
|
|
string effect "ALLOW or DENY"
|
|
int priority "evaluation priority"
|
|
boolean isActive "policy active flag"
|
|
string organizationId FK "organization reference"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
Organization {
|
|
string id PK "cuid primary key"
|
|
string name "organization name"
|
|
string domain UK "organization domain"
|
|
string parentId FK "parent organization ID"
|
|
json settings "organization settings"
|
|
boolean isActive "active flag"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
Group {
|
|
string id PK "cuid primary key"
|
|
string name "group name"
|
|
string organizationId FK "organization reference"
|
|
string description "group description"
|
|
boolean isActive "active flag"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
GroupMember {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string groupId FK "group reference"
|
|
string role "member role"
|
|
datetime joinedAt "join timestamp"
|
|
datetime expiresAt "expiration timestamp"
|
|
}
|
|
|
|
GroupPermission {
|
|
string id PK "cuid primary key"
|
|
string groupId FK "group reference"
|
|
string permissionId FK "permission reference"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
UserProfile {
|
|
string id PK "cuid primary key"
|
|
string userId UK "user reference"
|
|
string firstName "first name"
|
|
string lastName "last name"
|
|
string phone "phone number"
|
|
boolean phoneVerified "phone verified flag"
|
|
string avatarUrl "avatar URL"
|
|
json customFields "custom attributes"
|
|
json preferences "user preferences"
|
|
json metadata "additional metadata"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
IdentityVerification {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
enum type "verification type"
|
|
enum status "verification status"
|
|
string method "verification method"
|
|
string token UK "verification token"
|
|
datetime verifiedAt "verification timestamp"
|
|
datetime expiresAt "expiration timestamp"
|
|
json metadata "verification details"
|
|
datetime createdAt "creation timestamp"
|
|
}
|
|
|
|
AccessRequest {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
string resource "target resource"
|
|
string action "requested action"
|
|
string reason "request reason"
|
|
enum status "request status"
|
|
datetime requestedAt "request timestamp"
|
|
datetime reviewedAt "review timestamp"
|
|
string reviewedBy "reviewer user ID"
|
|
datetime expiresAt "expiration timestamp"
|
|
json metadata "request metadata"
|
|
}
|
|
|
|
AccessRequestApprover {
|
|
string id PK "cuid primary key"
|
|
string requestId FK "request reference"
|
|
string approverId "approver user ID"
|
|
enum status "approval status"
|
|
string comments "approval comments"
|
|
datetime reviewedAt "review timestamp"
|
|
}
|
|
|
|
AccessReview {
|
|
string id PK "cuid primary key"
|
|
string name "review name"
|
|
string description "review description"
|
|
enum type "review type"
|
|
enum status "review status"
|
|
datetime startDate "start date"
|
|
datetime endDate "end date"
|
|
string createdBy "creator user ID"
|
|
datetime createdAt "creation timestamp"
|
|
datetime completedAt "completion timestamp"
|
|
}
|
|
|
|
AccessReviewItem {
|
|
string id PK "cuid primary key"
|
|
string reviewId FK "review reference"
|
|
string userId "target user ID"
|
|
string resource "target resource"
|
|
json access "current access details"
|
|
enum status "review item status"
|
|
string reviewedBy "reviewer user ID"
|
|
datetime reviewedAt "review timestamp"
|
|
string comments "review comments"
|
|
}
|
|
|
|
ComplianceReport {
|
|
string id PK "cuid primary key"
|
|
enum type "compliance type"
|
|
string name "report name"
|
|
datetime periodStart "period start"
|
|
datetime periodEnd "period end"
|
|
enum status "report status"
|
|
json data "report data"
|
|
datetime generatedAt "generation timestamp"
|
|
string generatedBy "generator user ID"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
PolicyTemplate {
|
|
string id PK "cuid primary key"
|
|
string name "template name"
|
|
enum category "policy category"
|
|
string description "template description"
|
|
json content "template structure"
|
|
string version "template version"
|
|
boolean isActive "active flag"
|
|
datetime createdAt "creation timestamp"
|
|
datetime updatedAt "last update timestamp"
|
|
}
|
|
|
|
RiskScore {
|
|
string id PK "cuid primary key"
|
|
string userId FK "user reference"
|
|
int score "risk score (0-100)"
|
|
enum level "risk level"
|
|
json factors "risk factors"
|
|
datetime calculatedAt "calculation timestamp"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Model Categories
|
|
|
|
### 1. Core Authentication (7 models)
|
|
|
|
**Purpose**: Handle user authentication, sessions, and security events.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **User** | Core user entity | Email/username, password hash, MFA, active status |
|
|
| **Session** | Active user sessions | Device tracking, fingerprinting, expiration |
|
|
| **RefreshToken** | Long-lived tokens | Token rotation, family tracking, revocation |
|
|
| **AuthEvent** | Audit log events | Event sourcing, compliance, troubleshooting |
|
|
| **SocialAccount** | OAuth accounts | Google, Facebook, GitHub integration |
|
|
| **MFADevice** | MFA devices | TOTP, WebAuthn support |
|
|
| **Policy** | ABAC policies | JSON logic, conditions, priority |
|
|
|
|
### 2. Authorization (6 models)
|
|
|
|
**Purpose**: Manage roles, permissions, and access control.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **Role** | Named collections of permissions | ADMIN, MANAGER, USER, custom roles |
|
|
| **Permission** | Granular access rights | resource:action:scope format |
|
|
| **UserRole** | User-role assignments | Expiration, temporary grants |
|
|
| **RolePermission** | Role-permission mappings | Many-to-many relationship |
|
|
| **UserPermission** | Direct user permissions | Override roles, grant/deny |
|
|
| **GroupPermission** | Group permissions | Inherited by group members |
|
|
|
|
### 3. Social & OIDC (2 models)
|
|
|
|
**Purpose**: External authentication integration.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **SocialAccount** | OAuth provider accounts | Access tokens, refresh tokens, profile |
|
|
| **MFADevice** | Multi-factor auth devices | TOTP secrets, WebAuthn credentials |
|
|
|
|
### 4. Identity Management (6 models)
|
|
|
|
**Purpose**: User profiles, organizations, groups, verification.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **Organization** | Multi-tenant organizations | Hierarchy, settings, isolation |
|
|
| **Group** | User groups | Organization-scoped, permissions |
|
|
| **GroupMember** | Group membership | Roles, expiration |
|
|
| **UserProfile** | Extended user info | Name, phone, avatar, custom fields |
|
|
| **IdentityVerification** | Email/phone/document verification | OTP tokens, status tracking |
|
|
|
|
### 5. Access Management (4 models)
|
|
|
|
**Purpose**: Access requests, reviews, analytics.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **AccessRequest** | Access request workflows | Approval chains, expiration |
|
|
| **AccessRequestApprover** | Multi-person approval | Approval status, comments |
|
|
| **AccessReview** | Access certification campaigns | Periodic, adhoc, certification |
|
|
| **AccessReviewItem** | Individual review items | Approve, revoke, no change |
|
|
|
|
### 6. Governance (3 models)
|
|
|
|
**Purpose**: Compliance, policies, risk management.
|
|
|
|
| Model | Purpose | Key Features |
|
|
|-------|---------|--------------|
|
|
| **ComplianceReport** | GDPR, SOC2, ISO27001 reports | Period-based, generation |
|
|
| **PolicyTemplate** | Reusable policy templates | Versioning, categories |
|
|
| **RiskScore** | User risk scoring | Factors, levels, tracking |
|
|
|
|
---
|
|
|
|
## Core Authentication Models
|
|
|
|
### User Model
|
|
|
|
```typescript
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
username String? @unique
|
|
passwordHash String? // Nullable for social-only users
|
|
isActive Boolean @default(true)
|
|
emailVerified Boolean @default(false)
|
|
mfaEnabled Boolean @default(false)
|
|
mfaSecret String?
|
|
lastLoginAt DateTime?
|
|
loginCount Int @default(0)
|
|
organizationId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Primary identifier: `id` (CUID for distributed generation)
|
|
- Unique constraints: `email`, `username`
|
|
- Password hashing: bcrypt (cost factor 12)
|
|
- MFA support: TOTP secret stored
|
|
- Audit fields: `lastLoginAt`, `loginCount`
|
|
- Soft delete: `isActive` flag
|
|
|
|
### Session Model
|
|
|
|
```typescript
|
|
model Session {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
deviceId String
|
|
deviceName String?
|
|
ipAddress String
|
|
userAgent String?
|
|
fingerprint String? // Device fingerprint
|
|
isActive Boolean @default(true)
|
|
expiresAt DateTime
|
|
createdAt DateTime @default(now())
|
|
lastActivityAt DateTime @default(now())
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Device tracking: `deviceId`, `deviceName`, `fingerprint`
|
|
- Security: IP address, user agent tracking
|
|
- Activity monitoring: `lastActivityAt`
|
|
- Expiration: Auto-expire based on `expiresAt`
|
|
|
|
### RefreshToken Model
|
|
|
|
```typescript
|
|
model RefreshToken {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
token String @unique
|
|
family String? // Token family for rotation
|
|
deviceId String?
|
|
ipAddress String?
|
|
userAgent String?
|
|
expiresAt DateTime
|
|
revokedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Token rotation: `family` for tracking token generations
|
|
- Security: Revocation support with `revokedAt`
|
|
- Device binding: Optional `deviceId` tracking
|
|
- Long-lived: 7-day expiration
|
|
|
|
### AuthEvent Model (Audit Log)
|
|
|
|
```typescript
|
|
model AuthEvent {
|
|
id String @id @default(cuid())
|
|
userId String?
|
|
eventType String // LOGIN, LOGOUT, MFA_ENABLED, etc.
|
|
eventData Json
|
|
ipAddress String?
|
|
userAgent String?
|
|
success Boolean @default(true)
|
|
errorMessage String? @db.Text
|
|
timestamp DateTime @default(now())
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Event sourcing: All auth events logged
|
|
- Compliance: GDPR, SOC2 audit trail
|
|
- Troubleshooting: Success/failure tracking
|
|
- Flexible: JSON `eventData` for any event type
|
|
|
|
---
|
|
|
|
## Authorization Models
|
|
|
|
### RBAC Relationship
|
|
|
|
```mermaid
|
|
graph LR
|
|
User[User<br/>alice@example.com] --> UserRole[UserRole<br/>Assignment]
|
|
|
|
UserRole --> Role[Role<br/>ADMIN]
|
|
|
|
Role --> RolePerm1[RolePermission]
|
|
Role --> RolePerm2[RolePermission]
|
|
|
|
RolePerm1 --> Perm1[Permission<br/>users:*:all]
|
|
RolePerm2 --> Perm2[Permission<br/>products:*:all]
|
|
|
|
User --> DirectPerm[UserPermission<br/>Direct Override]
|
|
DirectPerm --> Perm3[Permission<br/>analytics:read:all]
|
|
|
|
style User fill:#e1f5fe
|
|
style Role fill:#f3e5f5
|
|
style Perm1 fill:#fff3e0
|
|
style Perm2 fill:#fff3e0
|
|
style Perm3 fill:#ffccbc
|
|
```
|
|
|
|
### Permission Model
|
|
|
|
**Format**: `resource:action:scope`
|
|
|
|
```typescript
|
|
model Permission {
|
|
id String @id @default(cuid())
|
|
resource String // users, products, orders
|
|
action String // create, read, update, delete
|
|
scope String? // own, team, all
|
|
description String?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([resource, action, scope])
|
|
}
|
|
```
|
|
|
|
**Examples**:
|
|
- `users:read:all` - Read all users
|
|
- `users:update:own` - Update own profile
|
|
- `orders:delete:all` - Delete any order (admin)
|
|
|
|
### UserRole Model (with Expiration)
|
|
|
|
```typescript
|
|
model UserRole {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
roleId String
|
|
grantedBy String? // Who granted this role
|
|
expiresAt DateTime? // Temporary assignment
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([userId, roleId])
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Temporary roles: `expiresAt` for time-limited access
|
|
- Audit trail: `grantedBy` tracks who assigned role
|
|
- Unique constraint: One assignment per user-role pair
|
|
|
|
---
|
|
|
|
## Social & OIDC Models
|
|
|
|
### SocialAccount Model
|
|
|
|
```typescript
|
|
model SocialAccount {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
provider Provider // GOOGLE, FACEBOOK, GITHUB
|
|
providerId String // ID from provider
|
|
email String?
|
|
name String?
|
|
avatar String?
|
|
accessToken String? @db.Text
|
|
refreshToken String? @db.Text
|
|
expiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([provider, providerId])
|
|
}
|
|
|
|
enum Provider {
|
|
GOOGLE
|
|
FACEBOOK
|
|
GITHUB
|
|
APPLE
|
|
MICROSOFT
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Multiple providers per user
|
|
- Token storage for API calls
|
|
- Profile information caching
|
|
- Unique per provider-providerId
|
|
|
|
---
|
|
|
|
## Identity Management Models
|
|
|
|
### Organization Hierarchy
|
|
|
|
```mermaid
|
|
graph TD
|
|
RootOrg[Organization<br/>Acme Corp]
|
|
|
|
RootOrg --> Div1[Organization<br/>Engineering]
|
|
RootOrg --> Div2[Organization<br/>Sales]
|
|
|
|
Div1 --> Team1[Organization<br/>Frontend Team]
|
|
Div1 --> Team2[Organization<br/>Backend Team]
|
|
|
|
Div2 --> Team3[Organization<br/>North America]
|
|
Div2 --> Team4[Organization<br/>Europe]
|
|
|
|
Team1 --> User1[User: Alice]
|
|
Team1 --> User2[User: Bob]
|
|
Team2 --> User3[User: Charlie]
|
|
|
|
style RootOrg fill:#e1f5fe
|
|
style Div1 fill:#fff3e0
|
|
style Div2 fill:#fff3e0
|
|
style Team1 fill:#e8f5e9
|
|
style Team2 fill:#e8f5e9
|
|
```
|
|
|
|
### Organization Model
|
|
|
|
```typescript
|
|
model Organization {
|
|
id String @id @default(cuid())
|
|
name String
|
|
domain String? @unique
|
|
parentId String? // Self-referencing hierarchy
|
|
settings Json?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Self-referencing relationship
|
|
parent Organization? @relation("OrganizationHierarchy", fields: [parentId], references: [id])
|
|
children Organization[] @relation("OrganizationHierarchy")
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Hierarchical structure (parent-child)
|
|
- Domain-based organization
|
|
- Custom settings (JSON)
|
|
- Multi-tenancy support
|
|
|
|
### Group Model
|
|
|
|
```typescript
|
|
model Group {
|
|
id String @id @default(cuid())
|
|
name String
|
|
organizationId String?
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
members GroupMember[]
|
|
permissions GroupPermission[]
|
|
|
|
@@unique([organizationId, name])
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Organization-scoped groups
|
|
- Members and permissions
|
|
- Unique names within organization
|
|
|
|
### UserProfile Model
|
|
|
|
```typescript
|
|
model UserProfile {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
firstName String?
|
|
lastName String?
|
|
phone String?
|
|
phoneVerified Boolean @default(false)
|
|
avatarUrl String?
|
|
customFields Json? // Extended attributes
|
|
preferences Json? // User preferences
|
|
metadata Json? // Additional data
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Extended user information
|
|
- Custom fields (JSON) for flexibility
|
|
- Phone verification support
|
|
- Avatar management
|
|
|
|
---
|
|
|
|
## Access Management Models
|
|
|
|
### Access Request Workflow
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> PENDING: User creates request
|
|
|
|
PENDING --> APPROVED: All approvers approve
|
|
PENDING --> REJECTED: Any approver rejects
|
|
PENDING --> CANCELLED: User cancels
|
|
PENDING --> EXPIRED: Timeout
|
|
|
|
APPROVED --> [*]: Access granted
|
|
REJECTED --> [*]: Access denied
|
|
CANCELLED --> [*]: Request cancelled
|
|
EXPIRED --> [*]: Request expired
|
|
```
|
|
|
|
### AccessRequest Model
|
|
|
|
```typescript
|
|
model AccessRequest {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
resource String
|
|
action String
|
|
reason String?
|
|
status RequestStatus @default(PENDING)
|
|
requestedAt DateTime @default(now())
|
|
reviewedAt DateTime?
|
|
reviewedBy String?
|
|
expiresAt DateTime?
|
|
metadata Json?
|
|
|
|
approvers AccessRequestApprover[]
|
|
}
|
|
|
|
enum RequestStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
EXPIRED
|
|
CANCELLED
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Multi-person approval support
|
|
- Expiration for temporary access
|
|
- Metadata for custom workflows
|
|
- Audit trail (reviewedBy, reviewedAt)
|
|
|
|
---
|
|
|
|
## Governance Models
|
|
|
|
### ComplianceReport Model
|
|
|
|
```typescript
|
|
model ComplianceReport {
|
|
id String @id @default(cuid())
|
|
type ComplianceType
|
|
name String
|
|
periodStart DateTime
|
|
periodEnd DateTime
|
|
status ReportStatus @default(DRAFT)
|
|
data Json?
|
|
generatedAt DateTime?
|
|
generatedBy String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
enum ComplianceType {
|
|
GDPR // General Data Protection Regulation
|
|
SOC2 // Service Organization Control 2
|
|
ISO27001 // Information Security Management
|
|
HIPAA // Health Insurance Portability and Accountability Act
|
|
CUSTOM // Custom compliance framework
|
|
}
|
|
|
|
enum ReportStatus {
|
|
DRAFT
|
|
GENERATED
|
|
PUBLISHED
|
|
ARCHIVED
|
|
}
|
|
```
|
|
|
|
**Key Features**:
|
|
- Multiple compliance frameworks
|
|
- Period-based reporting
|
|
- Status tracking
|
|
- Flexible data structure (JSON)
|
|
|
|
### RiskScore Model
|
|
|
|
```typescript
|
|
model RiskScore {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
score Int // 0-100
|
|
level RiskLevel
|
|
factors Json // Risk factors
|
|
calculatedAt DateTime @default(now())
|
|
}
|
|
|
|
enum RiskLevel {
|
|
LOW
|
|
MEDIUM
|
|
HIGH
|
|
CRITICAL
|
|
}
|
|
```
|
|
|
|
**Risk Factors** (in JSON):
|
|
```json
|
|
{
|
|
"failedLogins": 3,
|
|
"unusualLocation": true,
|
|
"newDevice": true,
|
|
"highPrivilegeAccess": false,
|
|
"inactivityDays": 45,
|
|
"openAccessRequests": 2
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Relationships & Constraints
|
|
|
|
### Primary Relationships
|
|
|
|
```
|
|
User (1) ───< UserRole (many) >─── Role (1)
|
|
User (1) ───< UserPermission (many) >─── Permission (1)
|
|
Role (1) ───< RolePermission (many) >─── Permission (1)
|
|
Group (1) ───< GroupPermission (many) >─── Permission (1)
|
|
Group (1) ───< GroupMember (many) >─── User (1)
|
|
Organization (1) ───< User (many)
|
|
Organization (1) ───< Group (many)
|
|
Organization (1) ───< Organization (many) [self-referencing]
|
|
User (1) ──── UserProfile (1) [one-to-one]
|
|
User (1) ───< Session (many)
|
|
User (1) ───< RefreshToken (many)
|
|
User (1) ───< SocialAccount (many)
|
|
User (1) ───< MFADevice (many)
|
|
User (1) ───< AccessRequest (many)
|
|
AccessRequest (1) ───< AccessRequestApprover (many)
|
|
AccessReview (1) ───< AccessReviewItem (many)
|
|
```
|
|
|
|
### Unique Constraints
|
|
|
|
| Model | Unique Constraint | Purpose |
|
|
|-------|------------------|---------|
|
|
| User | email | One email per user |
|
|
| User | username | One username per user |
|
|
| Role | name | One role name |
|
|
| Permission | [resource, action, scope] | One permission per resource-action-scope |
|
|
| UserRole | [userId, roleId] | One assignment per user-role |
|
|
| Organization | domain | One organization per domain |
|
|
| Group | [organizationId, name] | Unique names within organization |
|
|
| SocialAccount | [provider, providerId] | One account per provider-providerId |
|
|
|
|
### Cascade Deletes
|
|
|
|
**ON DELETE CASCADE**:
|
|
- User deleted → Delete all UserRoles, Sessions, RefreshTokens, etc.
|
|
- Role deleted → Delete all RolePermissions
|
|
- Organization deleted → Set users' organizationId to null
|
|
- Group deleted → Delete all GroupMembers
|
|
|
|
**ON DELETE SET NULL**:
|
|
- Organization deleted → Users remain, organizationId set to null
|
|
- AuthEvent user deleted → Event remains, userId set to null (for audit)
|
|
|
|
---
|
|
|
|
## Data Lifecycle
|
|
|
|
### User Lifecycle
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> Created: register()
|
|
|
|
Created --> Active: Email verified
|
|
Created --> Inactive: Never verified
|
|
|
|
Active --> Deactivated: Deactivate account
|
|
Active --> Locked: Too many failed logins
|
|
Active --> MFAEnabled: Enable MFA
|
|
|
|
Deactivated --> Active: Reactivate
|
|
Locked --> Active: Unlock after timeout
|
|
MFAEnabled --> Active: Disable MFA
|
|
|
|
Active --> Deleted: Delete account (soft)
|
|
Deactivated --> Deleted: Delete account
|
|
|
|
Deleted --> [*]: Hard delete after retention period
|
|
```
|
|
|
|
### Session Lifecycle
|
|
|
|
1. **Created**: User logs in → Session created
|
|
2. **Active**: Session valid, user making requests
|
|
3. **Inactive**: No activity for extended period
|
|
4. **Expired**: Past `expiresAt` timestamp
|
|
5. **Revoked**: User logs out or admin revokes
|
|
6. **Deleted**: Cleanup job removes expired sessions
|
|
|
|
### Permission Lifecycle
|
|
|
|
1. **Created**: Admin creates new permission
|
|
2. **Assigned**: Permission granted to roles/users/groups
|
|
3. **Cached**: Permission cached in Redis (5min TTL)
|
|
4. **Checked**: Permission verified on resource access
|
|
5. **Revoked**: Permission removed from role/user/group
|
|
6. **Invalidated**: Cache cleared on permission change
|
|
|
|
---
|
|
|
|
## Indexing Strategy
|
|
|
|
### Performance Indexes
|
|
|
|
| Model | Index Columns | Purpose |
|
|
|-------|--------------|---------|
|
|
| User | email | Fast login lookup |
|
|
| User | username | Username lookup |
|
|
| User | organizationId | Tenant filtering |
|
|
| Session | userId | User's sessions |
|
|
| Session | deviceId | Device tracking |
|
|
| Session | expiresAt | Cleanup job |
|
|
| RefreshToken | userId | User's tokens |
|
|
| RefreshToken | token | Token lookup |
|
|
| RefreshToken | family | Token rotation |
|
|
| AuthEvent | [userId, timestamp] | User audit trail |
|
|
| AuthEvent | [eventType, timestamp] | Event type queries |
|
|
| UserRole | userId | User's roles |
|
|
| UserRole | roleId | Role members |
|
|
| UserRole | expiresAt | Expiration cleanup |
|
|
| Permission | resource | Resource permissions |
|
|
| AccessRequest | userId | User's requests |
|
|
| AccessRequest | status | Pending requests |
|
|
|
|
### Composite Indexes
|
|
|
|
For efficient querying:
|
|
- `AuthEvent(userId, timestamp)` - User audit logs ordered by time
|
|
- `UserRole(userId, expiresAt)` - Active roles for user
|
|
- `Session(userId, isActive, expiresAt)` - Active sessions for user
|
|
|
|
---
|
|
|
|
## Database Migrations
|
|
|
|
### Migration Strategy
|
|
|
|
1. **Forward-only migrations**: Never rollback, always migrate forward
|
|
2. **Non-destructive changes**: Add columns as nullable, then backfill
|
|
3. **Zero-downtime**: Multi-phase migrations for production
|
|
4. **Versioning**: Prisma migration history in `_prisma_migrations` table
|
|
|
|
### Example Migration Phases
|
|
|
|
**Phase 1 - Add column**:
|
|
```sql
|
|
ALTER TABLE users ADD COLUMN new_field VARCHAR(255);
|
|
```
|
|
|
|
**Phase 2 - Backfill data**:
|
|
```sql
|
|
UPDATE users SET new_field = 'default_value' WHERE new_field IS NULL;
|
|
```
|
|
|
|
**Phase 3 - Make required**:
|
|
```sql
|
|
ALTER TABLE users ALTER COLUMN new_field SET NOT NULL;
|
|
```
|
|
|
|
---
|
|
|
|
## Data Retention
|
|
|
|
| Data Type | Retention Period | Cleanup Strategy |
|
|
|-----------|-----------------|------------------|
|
|
| Active Users | Indefinite | Soft delete |
|
|
| Inactive Users | 2 years | Hard delete |
|
|
| Sessions | 30 days after expiry | Automatic cleanup |
|
|
| Refresh Tokens | 7 days after expiry | Automatic cleanup |
|
|
| AuthEvents | 7 years | Compliance requirement |
|
|
| Access Requests | 3 years | Compliance requirement |
|
|
| Compliance Reports | 7 years | Legal requirement |
|
|
| Risk Scores | 1 year | Rolling window |
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
- **[ARCHITECTURE.md](../ARCHITECTURE.en.md)** - System architecture and flows
|
|
- **[CORE-CONCEPTS.md](./CORE-CONCEPTS.md)** - IAM fundamentals
|
|
- **[SECURITY-MODEL.md](./SECURITY-MODEL.md)** - Security architecture
|
|
- **[API Reference](../API_REFERENCE.md)** - API endpoints
|
|
|
|
---
|
|
|
|
## Reference Files
|
|
|
|
- **Prisma Schema**: [prisma/schema.prisma](../../prisma/schema.prisma)
|
|
- **Repositories**: [src/repositories/](../../src/repositories/)
|
|
- **Migrations**: [prisma/migrations/](../../prisma/migrations/)
|
|
|
|
---
|
|
|
|
**Last Updated**: January 2026
|
|
**Version**: 1.0.0
|
|
**Status**: Production Ready
|