# 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
30+ Models] DataModel --> CoreAuth[Core Authentication
7 models] DataModel --> Authorization[Authorization
6 models] DataModel --> SocialOIDC[Social & OIDC
2 models] DataModel --> Identity[Identity Management
6 models] DataModel --> Access[Access Management
4 models] DataModel --> Governance[Governance
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
alice@example.com] --> UserRole[UserRole
Assignment] UserRole --> Role[Role
ADMIN] Role --> RolePerm1[RolePermission] Role --> RolePerm2[RolePermission] RolePerm1 --> Perm1[Permission
users:*:all] RolePerm2 --> Perm2[Permission
products:*:all] User --> DirectPerm[UserPermission
Direct Override] DirectPerm --> Perm3[Permission
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
Acme Corp] RootOrg --> Div1[Organization
Engineering] RootOrg --> Div2[Organization
Sales] Div1 --> Team1[Organization
Frontend Team] Div1 --> Team2[Organization
Backend Team] Div2 --> Team3[Organization
North America] Div2 --> Team4[Organization
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