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
jsonwebtokenlibrary - 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
joselibrary (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:
- Consolidate into a single unified auth provider for the entire platform
- 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#
Option 1: Single Unified Auth Provider (Recommended)#
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:
┌─────────────────────────────────────────────────────────────────┐
│ 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-clientSDK 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:
┌───────────────────┐ ┌───────────────────┐
│ 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:
-
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.
-
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.
-
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.
-
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
-
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.
-
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:
-
Phase 1: Foundation Library (Week 1-2)
- Create
@oshun/authpackage inlibs/shared/auth/ - Port Yemaya's JWT service with key rotation (jose library)
- Port Yemaya's Redis session service
- Port hierarchical RBAC system
- Create
-
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
-
Phase 3: OAuth Integration (Week 3)
- Consolidate OAuth providers (Google, GitHub, Discord, Apple, Microsoft)
- Implement unified account linking
- Add OAuth state management
-
Phase 4: Auth Service (Week 3-4)
- Create
apps/oshun/auth-service/ - Implement all auth endpoints
- Add health checks and monitoring
- Deploy to staging
- Create
-
Phase 5: Client SDK (Week 4)
- Create
@oshun/auth-clientpackage - Implement React hooks (useAuth, useUser, useSession)
- Implement Node.js middleware
- Add API client helpers
- Create
-
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:
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:
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:
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:
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:
// 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:
-- 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:
- Revert DNS to point to original auth services
- Restore original session stores
- Mark migrated tokens as invalid
- 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
Related Decisions#
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#
- OAuth 2.0 Security Best Current Practice
- JWT Best Practices
- OWASP Authentication Cheat Sheet
- jose Library Documentation
- WebAuthn Guide
Internal Resources#
- Lilith auth service —
lilith/services/auth/(pre-consolidation source repo) - Yemaya auth package —
yemaya/packages/auth/(pre-consolidation source repo) - ADR-0001: Git Consolidation
- ADR-0002: Package Manager
Revision History#
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2026-01-10 | Development Team | Initial version |