# Issue #86: [FED-003] Authentik OIDC Integration ## Objective Integrate Authentik OIDC authentication with the federation system to enable: - Federated authentication flows using Authentik as the identity provider - User identity mapping across federated instances - Token validation and verification for federated requests - Secure API endpoints for federated authentication This builds on issues #84 (Instance Identity Model) and #85 (CONNECT/DISCONNECT Protocol). ## Context ### Existing Infrastructure From issue #84: - Instance model with keypair for signing - FederationConnection model for managing connections - FederationService for instance identity management - CryptoService for encryption/decryption From issue #85: - SignatureService for request signing/verification - ConnectionService for connection lifecycle management - Connection handshake protocol with status management ### Current Authentication Setup The project uses BetterAuth with Authentik OIDC provider: - `/apps/api/src/auth/auth.config.ts` - BetterAuth configuration with genericOAuth plugin - `/apps/api/src/auth/auth.service.ts` - Auth service with session verification - Environment variables: OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_REDIRECT_URI ## Requirements Based on federation architecture and existing code patterns: 1. **Federation-Specific OIDC Provider**: Create a dedicated OIDC provider configuration for federation that's separate from regular user authentication 2. **Cross-Instance Identity Linking**: Map users authenticated via OIDC to their identity on federated instances 3. **Token Validation for Federation**: Verify OIDC tokens in federated API requests 4. **Federated Authentication Endpoints**: API endpoints for initiating and completing federated authentication flows 5. **Security**: Ensure proper token validation, signature verification, and workspace isolation ## Approach ### 1. Create Federation OIDC Types Create `/apps/api/src/federation/types/oidc.types.ts`: ```typescript interface FederatedOIDCConfig { issuer: string; clientId: string; clientSecret: string; redirectUri: string; scopes: string[]; } interface FederatedTokenValidation { valid: boolean; userId?: string; instanceId?: string; workspaceId?: string; error?: string; } interface FederatedIdentity { localUserId: string; remoteUserId: string; remoteInstanceId: string; oidcSubject: string; email: string; metadata: Record; } ``` ### 2. Create OIDC Service for Federation Create `/apps/api/src/federation/oidc.service.ts`: - `configureFederatedProvider(instanceId, config)` - Configure OIDC for remote instance - `validateFederatedToken(token)` - Validate OIDC token from federated request - `linkFederatedIdentity(localUserId, remoteData)` - Link local user to remote identity - `getFederatedIdentity(localUserId, remoteInstanceId)` - Retrieve identity mapping - `revokeFederatedIdentity(localUserId, remoteInstanceId)` - Remove identity link ### 3. Extend Prisma Schema Add model for federated identity mapping: ```prisma model FederatedIdentity { id String @id @default(uuid()) @db.Uuid localUserId String @map("local_user_id") @db.Uuid remoteUserId String @map("remote_user_id") remoteInstanceId String @map("remote_instance_id") oidcSubject String @map("oidc_subject") email String metadata Json @default("{}") createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz user User @relation(fields: [localUserId], references: [id], onDelete: Cascade) @@unique([localUserId, remoteInstanceId]) @@index([localUserId]) @@index([remoteInstanceId]) @@index([oidcSubject]) @@map("federated_identities") } ``` ### 4. Add Federation Auth Endpoints Extend `FederationController` with: - `POST /api/v1/federation/auth/initiate` - Start federated auth flow - `GET /api/v1/federation/auth/callback` - Handle OIDC callback - `POST /api/v1/federation/auth/validate` - Validate federated token - `GET /api/v1/federation/auth/identities` - List user's federated identities - `POST /api/v1/federation/auth/link` - Link identity to remote instance - `DELETE /api/v1/federation/auth/identities/:id` - Revoke federated identity ### 5. Update Connection Service Enhance `ConnectionService` to handle OIDC-based authentication: - Store OIDC configuration in connection metadata - Validate OIDC setup when accepting connections - Provide OIDC discovery endpoints to remote instances ### 6. Security Considerations - OIDC tokens must be validated using the issuer's public keys - Federated requests must include both OIDC token AND instance signature - Identity mapping must enforce workspace isolation - Token expiration must be respected - PKCE flow should be used for public clients - Refresh tokens should be stored securely (encrypted) ### 7. Testing Strategy **Unit Tests** (TDD approach): - OIDCService.validateFederatedToken() validates tokens correctly - OIDCService.validateFederatedToken() rejects invalid tokens - OIDCService.linkFederatedIdentity() creates identity mapping - OIDCService.getFederatedIdentity() retrieves correct mapping - OIDCService.revokeFederatedIdentity() removes mapping - Workspace isolation for identity mappings **Integration Tests**: - POST /auth/initiate starts OIDC flow with correct params - GET /auth/oauth2/callback/:providerId handles OIDC response and creates identity - POST /auth/validate validates tokens from federated instances - GET /auth/identities returns user's federated identities - Federated requests with valid tokens are authenticated - Invalid or expired tokens are rejected ## Progress - [x] Create scratchpad - [x] Add FederatedIdentity model to Prisma schema - [x] Generate migration - [x] Create OIDC types - [x] Write tests for OIDCService (14 tests) - [x] Implement OIDCService - [x] Write tests for federation auth endpoints (10 tests) - [x] Implement auth endpoints in FederationAuthController - [x] Update FederationModule - [x] Update audit service with new logging methods - [x] Verify all tests pass (24 OIDC tests, 94 total federation tests) - [x] Verify type checking passes (no errors) - [x] Verify test coverage (OIDCService: 79%, Controller: 100%) - [x] Commit changes ## Design Decisions 1. **Separate OIDC Configuration**: Federation OIDC is separate from regular user auth to allow different IdPs per federated instance 2. **Identity Mapping Table**: Explicit FederatedIdentity table rather than storing in connection metadata for better querying and RLS 3. **Dual Authentication**: Federated requests require both OIDC token (user identity) AND instance signature (instance identity) 4. **Workspace Scoping**: Identity mappings are user-scoped but authenticated within workspace context 5. **Token Storage**: Store minimal token data; rely on OIDC provider for validation ## Notes - Need to handle OIDC discovery for dynamic configuration - Should support multiple OIDC providers per instance (one per federated connection) - Consider token caching to reduce validation overhead - May need webhook for token revocation notifications - Future: Support for custom claims mapping