feat(#86): implement Authentik OIDC integration for federation
Implements federated authentication infrastructure using OIDC: - Add FederatedIdentity model to Prisma schema for identity mapping - Create OIDCService with identity linking and token validation - Add FederationAuthController with 5 endpoints: * POST /auth/initiate - Start federated auth flow * POST /auth/link - Link identity to remote instance * GET /auth/identities - List user's federated identities * DELETE /auth/identities/:id - Revoke identity * POST /auth/validate - Validate federated token - Create comprehensive type definitions for OIDC flows - Add audit logging for security events - Write 24 passing tests (14 service + 10 controller) - Achieve 79% coverage for OIDCService, 100% for controller Notes: - Token validation and auth URL generation are placeholder implementations - Full JWT validation will be added when federation OIDC is actively used - Identity mappings enforce workspace isolation - All endpoints require authentication except /validate Refs #86 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
205
docs/scratchpads/86-authentik-oidc-integration.md
Normal file
205
docs/scratchpads/86-authentik-oidc-integration.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# 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<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
### 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/callback 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
|
||||
Reference in New Issue
Block a user