Disciplines · Decisions (ADRs)

ADR-0003: Unified Authentication and Identity Strategy

The Oshun monorepo consolidation requires a unified authentication and identity strategy.

Accepted · 2026-01-10
11sections9 minread

On this page

Status: Accepted Date: 2026-01-10 Authors: Development Team Reviewers: Security Team, Architecture Team Supersedes: N/A Superseded by: N/A

Context and Problem Statement#

The Oshun monorepo consolidation requires a unified authentication and identity strategy. Currently, both primary codebases implement independent, custom-built authentication systems:

Lilith Auth Service (Current State):

  • JWT-based authentication using jsonwebtoken library
  • In-memory session storage (Map-based)
  • Multi-factor authentication (TOTP, SMS, WebAuthn planned)
  • Basic OAuth callback handling
  • Argon2/bcrypt password hashing
  • Audit logging for compliance
  • Privacy serializers for GDPR

Yemaya Auth Package (Current State):

  • JWT authentication using jose library (more modern)
  • Redis-backed distributed session storage
  • Key rotation support with JWKS endpoint
  • Comprehensive OAuth providers (Google, GitHub, Discord, Apple, Microsoft)
  • Hierarchical RBAC with permission inheritance
  • Token blacklisting via Redis
  • Login history with risk scoring
  • Session analytics and management

Neither codebase uses third-party managed auth providers (Clerk, Auth0, Supabase).

We need to decide whether to:

  1. Consolidate into a single unified auth provider for the entire platform
  2. Maintain per-product auth providers (lilith auth, yemaya auth, etc.)

This decision affects security posture, user experience, operational complexity, and cross-domain integration capabilities.

Decision Drivers#

  • Security: Centralized security controls, consistent policies, single attack surface to monitor
  • User Experience: Single sign-on across products, unified identity, seamless navigation
  • Operational Simplicity: One auth system to maintain, monitor, and scale
  • Cross-Domain Integration: Shared services (isis, sophia, hathor, bellona) need consistent auth
  • Scalability: Must support 100k+ users with distributed session management
  • Compliance: GDPR, SOC2 requirements for identity management
  • Development Velocity: Single auth SDK for all domains vs. multiple integrations
  • Existing Investment: Leverage mature implementations from both codebases

Considered Options#

Description: Consolidate Lilith and Yemaya auth implementations into a single, unified @oshun/auth package and auth service. All domains (lilith, yemaya, isis, sophia, hathor, bellona) authenticate through this central system.

Architecture:

text
┌─────────────────────────────────────────────────────────────────┐
│                     Oshun Auth Service                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │ JWT Service │  │ Session Svc │  │ OAuth Providers         │  │
│  │ (jose)      │  │ (Redis)     │  │ Google/GitHub/Discord/  │  │
│  │ Key rotation│  │ Multi-device│  │ Apple/Microsoft         │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │ RBAC        │  │ MFA Service │  │ Audit & Compliance      │  │
│  │ Hierarchical│  │ TOTP/WebAuthn│ │ GDPR/SOC2              │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
   ┌────▼────┐          ┌─────▼─────┐        ┌─────▼─────┐
   │ Lilith  │          │  Yemaya   │        │ Isis/     │
   │ Product │          │  Studio   │        │ Sophia/   │
   │         │          │           │        │ Hathor    │
   └─────────┘          └───────────┘        └───────────┘

Pros:

  • Single Sign-On: User authenticates once, accesses all products
  • Unified Identity: One user profile, one session, one set of roles
  • Security Consistency: Single place for security policies, monitoring, and incident response
  • Simplified Development: One @oshun/auth-client SDK for all domains
  • Cross-Domain Authorization: Shared services naturally inherit auth context
  • Operational Efficiency: One service to scale, monitor, and maintain
  • Compliance Simplification: Single audit surface for identity management
  • Best-of-Both: Combine Lilith's MFA and Yemaya's distributed sessions

Cons:

  • Single Point of Failure: Auth service outage affects all products
  • Migration Complexity: Both systems need careful migration to unified model
  • Coordination Overhead: Changes affect all products, requires coordination
  • Blast Radius: Security breach in auth affects all products

Cost: Medium - significant development effort for unification Risk: Medium - complexity of migration, mitigated by careful planning Effort: 3-4 weeks for core implementation, 2 weeks for migration

Option 2: Per-Product Auth Providers#

Description: Maintain separate auth systems for Lilith and Yemaya, with each product managing its own identity. Use token exchange or federation for cross-product access when needed.

Architecture:

text
┌───────────────────┐      ┌───────────────────┐
│   Lilith Auth     │      │   Yemaya Auth     │
│   ┌───────────┐   │      │   ┌───────────┐   │
│   │ JWT/TOTP  │   │◄────►│   │ JWT/OAuth │   │
│   │ In-memory │   │      │   │ Redis     │   │
│   └───────────┘   │      │   └───────────┘   │
└───────────────────┘      └───────────────────┘
         │                          │
         ▼                          ▼
    ┌─────────┐               ┌───────────┐
    │ Lilith  │               │  Yemaya   │
    │ Product │               │  Studio   │
    └─────────┘               └───────────┘

Pros:

  • Isolation: Auth issues in one product don't affect others
  • Independent Evolution: Each product can evolve auth independently
  • Simpler Initial Setup: No migration needed, keep existing systems
  • Team Autonomy: Teams own their auth stack

Cons:

  • User Friction: Users need separate accounts or complex linking
  • No SSO: Must re-authenticate when switching products
  • Duplicate Development: Similar features built twice
  • Security Inconsistency: Different policies, different vulnerabilities
  • Operational Overhead: Multiple systems to monitor, scale, and maintain
  • Cross-Domain Complexity: Shared services (isis, sophia) need multiple auth integrations
  • Compliance Burden: Multiple audit surfaces for identity management

Cost: Low initial, High ongoing Risk: High - fragmentation leads to security gaps and poor UX Effort: Minimal initial, significant ongoing maintenance

Option 3: Third-Party Managed Auth (Clerk/Auth0)#

Description: Replace both custom implementations with a managed auth provider like Clerk, Auth0, or Supabase Auth.

Pros:

  • Production-Ready: Battle-tested auth with enterprise features
  • Reduced Maintenance: Provider handles security patches, scaling
  • Rich Features: MFA, social login, passwordless, fraud detection built-in
  • Compliance: SOC2, GDPR, HIPAA certifications
  • Developer Experience: SDKs, UI components, documentation

Cons:

  • Vendor Lock-In: Significant dependency on external provider
  • Cost at Scale: Per-user pricing becomes expensive (100k users = $$$)
  • Migration Effort: Both systems need complete rewrite
  • Customization Limits: May not support specific requirements
  • Data Sovereignty: User data stored externally
  • Discard Investment: Both Lilith and Yemaya have mature implementations

Cost: High - vendor fees + migration effort Risk: Medium - vendor dependency, migration complexity Effort: 6-8 weeks for complete migration

Decision Outcome#

Chosen option: Option 1 - Single Unified Auth Provider

Justification:

A single unified auth provider is the optimal choice for the Oshun platform for the following reasons:

  1. Platform Cohesion: Oshun is fundamentally a unified platform with multiple products. Users should experience seamless access across Lilith (consciousness/meditation), Yemaya (creative studio), and future products. Per-product auth would create friction and fragmentation.

  2. Cross-Domain Architecture: The new domains (isis, sophia, hathor, bellona) are shared services used by multiple products. A unified auth system provides natural authentication propagation without complex token exchange.

  3. Security Posture: A single auth system means one attack surface to monitor, one set of security policies to enforce, and one incident response procedure. This significantly reduces security operational complexity.

  4. Development Efficiency: Rather than maintaining two similar but different auth implementations, consolidation allows combining the best features:

    • From Yemaya: Jose library, Redis sessions, key rotation, OAuth providers, RBAC
    • From Lilith: MFA (TOTP/WebAuthn), audit logging, GDPR privacy serializers
  5. Cost Analysis: While third-party providers offer convenience, at scale (100k+ users), the cost becomes prohibitive (Clerk: $0.02/MAU = $2,000+/month). The existing implementations provide a strong foundation that can be unified.

  6. Existing Investment: Both teams have built sophisticated auth systems. Unifying them preserves this investment while eliminating redundancy.

Trade-offs Accepted:

  • Single point of failure (mitigated by high availability architecture)
  • Migration complexity (mitigated by phased approach)
  • Coordination overhead (offset by reduced long-term maintenance)

Implementation Plan:

  1. Phase 1: Foundation Library (Week 1-2)

    • Create @oshun/auth package in libs/shared/auth/
    • Port Yemaya's JWT service with key rotation (jose library)
    • Port Yemaya's Redis session service
    • Port hierarchical RBAC system
  2. Phase 2: Security Features (Week 2-3)

    • Port Lilith's MFA service (TOTP, WebAuthn)
    • Implement unified token blacklisting
    • Port login history and risk scoring
    • Add audit logging from Lilith
  3. Phase 3: OAuth Integration (Week 3)

    • Consolidate OAuth providers (Google, GitHub, Discord, Apple, Microsoft)
    • Implement unified account linking
    • Add OAuth state management
  4. Phase 4: Auth Service (Week 3-4)

    • Create apps/oshun/auth-service/
    • Implement all auth endpoints
    • Add health checks and monitoring
    • Deploy to staging
  5. Phase 5: Client SDK (Week 4)

    • Create @oshun/auth-client package
    • Implement React hooks (useAuth, useUser, useSession)
    • Implement Node.js middleware
    • Add API client helpers
  6. Phase 6: Migration (Week 5-6)

    • Migrate Lilith to use @oshun/auth-client
    • Migrate Yemaya to use @oshun/auth-client
    • Data migration for existing users
    • Parallel running period for validation

Success Metrics:

  • All products authenticate through unified auth service
  • SSO works across lilith.oshun.dev and yemaya.oshun.dev
  • Zero authentication-related incidents during migration
  • Session management handles 10k concurrent sessions
  • OAuth flow completion rate > 95%
  • MFA enrollment available for all users

Review Schedule: 60 days post-migration

Implementation Details#

Technical Specifications#

Unified JWT Structure:

typescript
interface OshunJWTPayload {
  // Standard claims
  sub: string; // User ID
  iss: string; // "https://auth.oshun.dev"
  aud: string | string[]; // ["lilith", "yemaya", "isis", "sophia"]
  exp: number; // Expiration timestamp
  iat: number; // Issued at
  jti: string; // JWT ID for blacklisting

  // Oshun-specific claims
  email: string;
  emailVerified: boolean;
  name: string;
  roles: string[]; // ["user", "creator", "admin"]
  permissions: string[]; // ["projects:write", "assets:upload"]
  organizationId?: string;

  // Session binding
  sid: string; // Session ID
  version: number; // Token version for rotation

  // Token type
  type: 'access' | 'refresh';

  // OAuth metadata (if applicable)
  provider?: string; // "google", "github", etc.
  scopes?: string[]; // OAuth scopes granted
}

Unified Session Model:

typescript
interface OshunSession {
  id: string;
  userId: string;

  // Authentication state
  refreshTokenHash: string;
  tokenVersion: number;

  // Device information
  client: {
    ip: string;
    userAgent: string;
    deviceType: 'desktop' | 'mobile' | 'tablet';
    browser: string;
    os: string;
    location?: {
      country: string;
      city: string;
    };
  };

  // Lifecycle
  createdAt: Date;
  lastActivityAt: Date;
  expiresAt: Date;
  isActive: boolean;

  // Product access
  products: string[]; // ["lilith", "yemaya"]
  lastProductAccess: Record<string, Date>;

  // Security
  mfaVerified: boolean;
  riskScore: number; // 0-100

  // Extensions
  extensionCount: number;
  lastExtendedAt?: Date;
  rememberMe: boolean;
}

Unified User Model:

typescript
interface OshunUser {
  id: string;
  email: string;
  emailVerified: boolean;

  // Profile
  name: string;
  firstName?: string;
  lastName?: string;
  avatarUrl?: string;

  // Authentication
  passwordHash?: string; // Argon2
  mfaEnabled: boolean;
  mfaMethod?: 'totp' | 'webauthn' | 'sms';
  mfaSecret?: string; // Encrypted
  webauthnCredentials?: WebAuthnCredential[];

  // Authorization
  roles: string[];
  permissions: string[];
  organizationId?: string;

  // OAuth connections
  oauthConnections: {
    provider: string;
    providerId: string;
    email: string;
    connectedAt: Date;
  }[];

  // Security
  forcePasswordReset: boolean;
  passwordChangedAt?: Date;
  lockedUntil?: Date;
  failedLoginAttempts: number;

  // Compliance
  consentGiven: boolean;
  consentTimestamp?: Date;
  dataRetentionOptOut: boolean;

  // Lifecycle
  createdAt: Date;
  updatedAt: Date;
  lastLoginAt?: Date;
  deletedAt?: Date; // Soft delete
}

RBAC Hierarchy:

typescript
const roleHierarchy = {
  viewer: {
    permissions: [
      'projects:read',
      'assets:read',
      'meditations:read', // Lilith
      'workflows:read', // Yemaya
    ],
  },
  creator: {
    permissions: [
      'projects:write',
      'assets:write',
      'assets:upload',
      'meditations:create', // Lilith
      'workflows:create', // Yemaya
    ],
    inherits: ['viewer'],
  },
  editor: {
    permissions: ['projects:publish', 'assets:delete', 'content:moderate'],
    inherits: ['creator'],
  },
  admin: {
    permissions: ['users:manage', 'settings:manage', 'billing:view'],
    inherits: ['editor'],
  },
  owner: {
    permissions: ['organizations:manage', 'billing:manage', 'roles:assign'],
    inherits: ['admin'],
  },
  superadmin: {
    permissions: ['*'], // All permissions
  },
  service: {
    permissions: ['internal:*', 'health:read'],
  },
};

Auth Middleware Interface:

typescript
// libs/shared/auth-primitives/src/middleware.ts

export interface AuthMiddlewareOptions {
  required?: boolean;
  roles?: string[];
  permissions?: string[];
  products?: string[]; // Restrict to specific products
  allowApiKey?: boolean;
  requireMfa?: boolean;
  requireVerifiedEmail?: boolean;
}

export function createAuthMiddleware(options: AuthMiddlewareOptions) {
  return async (ctx: Context, next: Next) => {
    // 1. Extract token from Authorization header
    // 2. Verify JWT signature and expiration
    // 3. Check token blacklist
    // 4. Validate session is active
    // 5. Check roles/permissions if specified
    // 6. Attach user to context
    // 7. Update session activity
    await next();
  };
}

// Usage in Lilith
app.get(
  '/meditations',
  createAuthMiddleware({
    required: true,
    permissions: ['meditations:read'],
  }),
  getMeditations
);

// Usage in Yemaya
app.post(
  '/projects',
  createAuthMiddleware({
    required: true,
    permissions: ['projects:write'],
    requireVerifiedEmail: true,
  }),
  createProject
);

Migration Strategy#

From: Separate Lilith and Yemaya auth systems To: Unified @oshun/auth service

Data Migration Plan:

sql
-- Phase 1: Create unified users table
CREATE TABLE oshun_users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  -- ... other fields

  -- Migration tracking
  lilith_user_id UUID,
  yemaya_user_id UUID,
  migrated_at TIMESTAMP
);

-- Phase 2: Migrate Lilith users
INSERT INTO oshun_users (email, name, password_hash, lilith_user_id, migrated_at)
SELECT email, name, password, id, NOW()
FROM lilith.users
ON CONFLICT (email) DO UPDATE SET lilith_user_id = EXCLUDED.lilith_user_id;

-- Phase 3: Merge Yemaya users
INSERT INTO oshun_users (email, name, password_hash, yemaya_user_id, migrated_at)
SELECT email, name, password_hash, id, NOW()
FROM yemaya.users
ON CONFLICT (email) DO UPDATE SET yemaya_user_id = EXCLUDED.yemaya_user_id;

-- Phase 4: Migrate OAuth connections
INSERT INTO oshun_oauth_connections (user_id, provider, provider_id)
SELECT ou.id, oc.provider, oc.provider_id
FROM yemaya.oauth_connections oc
JOIN oshun_users ou ON ou.yemaya_user_id = oc.user_id;

Rollback Plan: If critical issues discovered:

  1. Revert DNS to point to original auth services
  2. Restore original session stores
  3. Mark migrated tokens as invalid
  4. Investigate and fix issues before retry

Testing Strategy#

Unit Tests:

  • JWT creation and verification
  • Session lifecycle (create, extend, revoke)
  • RBAC permission resolution
  • Password hashing and validation
  • OAuth flow state management

Integration Tests:

  • Full login flow (email/password)
  • OAuth flows for each provider
  • Token refresh flow
  • MFA enrollment and verification
  • Session management across devices
  • Cross-product SSO

Security Tests:

  • Token forgery detection
  • Session hijacking prevention
  • Rate limiting on auth endpoints
  • SQL injection in user lookup
  • CSRF protection on OAuth callbacks
  • Token replay attack prevention

Load Tests:

  • 10,000 concurrent authentication requests
  • 50,000 concurrent active sessions
  • Session lookup latency < 10ms at p99
  • Token verification latency < 5ms at p99

Consequences#

Positive Consequences#

  • Unified User Experience: Single sign-on across all Oshun products
  • Simplified Architecture: One auth system instead of multiple
  • Enhanced Security: Consistent policies, single monitoring surface
  • Developer Productivity: One SDK to learn, one API to integrate
  • Operational Efficiency: Single service to scale and maintain
  • Compliance Simplification: One audit surface for identity
  • Best Features Combined: MFA from Lilith + distributed sessions from Yemaya

Negative Consequences#

  • Migration Effort: Significant initial investment to consolidate
  • Single Point of Failure: Requires robust HA architecture
  • Coordination Required: Auth changes affect all products
  • Learning Curve: Teams need to learn unified auth patterns

Risks and Mitigation#

Risk Probability Impact Mitigation Strategy
Auth service outage affects all products Low Critical Multi-region deployment, circuit breakers, graceful degradation
User data loss during migration Low Critical Comprehensive backups, dry-run migrations, parallel running period
OAuth provider integration breaks Medium High Thorough testing per provider, feature flags for rollback
Performance degradation at scale Medium High Load testing, Redis cluster for sessions, JWT caching
Security vulnerability in unified auth Low Critical Security audit, penetration testing, bug bounty program

Compliance and Security#

Security Implications#

  • Centralized Security: All authentication logic in one auditable codebase
  • Key Management: Centralized key rotation with JWKS distribution
  • Session Security: Redis-backed sessions with encryption at rest
  • MFA Enforcement: Consistent MFA policies across products
  • Audit Logging: Comprehensive auth event logging for compliance

Compliance Requirements#

  • GDPR:
    • Right to erasure (delete user across all products)
    • Data portability (export auth data)
    • Consent management (unified consent tracking)
  • SOC 2:
    • Access controls documented
    • Session management logged
    • Authentication events audited
  • PCI DSS (if applicable):
    • Strong authentication for payment access
    • Session timeout enforcement
    • MFA for sensitive operations

Monitoring and Observability#

Metrics to Track#

  • Authentication: Login success/failure rates, MFA usage, OAuth conversions
  • Sessions: Active sessions, session duration, concurrent sessions per user
  • Performance: Token verification latency, session lookup latency, auth endpoint latency
  • Security: Failed login attempts, blocked IPs, suspicious activity alerts

Alerting Strategy#

  • Critical: Auth service unavailable, >5% login failure rate, security breach detected
  • Warning: >1% login failure rate, session store latency >100ms, approaching rate limits
  • Info: New OAuth provider connected, MFA enrollment spike, unusual login patterns

Dashboards#

  • Auth Operations: Real-time login attempts, OAuth flows, MFA challenges
  • User Security: Risk scores, suspicious activity, account lockouts
  • Performance: Request latency percentiles, throughput, error rates

Upstream Dependencies#

  • ADR-0001: Git Repository Consolidation (single repo enables unified auth)
  • ADR-0002: pnpm Package Manager (auth packages use workspace protocol)

Downstream Impacts#

  • All Product Services: Must integrate with unified auth middleware
  • API Gateway: Routes auth requests to auth service
  • Cross-Domain Services: isis, sophia, hathor inherit auth context
  • Mobile Apps: Use @oshun/auth-client SDK

References#

External Resources#

Internal Resources#


Revision History#

Version Date Author Changes
1.0 2026-01-10 Development Team Initial version