feat(#359): Encrypt LLM provider API keys in database
Implemented transparent encryption/decryption of LLM provider API keys stored in llm_provider_instances.config JSON field using OpenBao Transit encryption. Implementation: - Created llm-encryption.middleware.ts with encryption/decryption logic - Auto-detects format (vault:v1: vs plaintext) for backward compatibility - Idempotent encryption prevents double-encryption - Registered middleware in PrismaService - Created data migration script for active encryption - Added migrate:encrypt-llm-keys command to package.json Tests: - 14 comprehensive unit tests - 90.76% code coverage (exceeds 85% requirement) - Tests create, read, update, upsert operations - Tests error handling and backward compatibility Migration: - Lazy migration: New keys encrypted, old keys work until re-saved - Active migration: pnpm --filter @mosaic/api migrate:encrypt-llm-keys - No schema changes required - Zero downtime Security: - Uses TransitKey.LLM_CONFIG from OpenBao Transit - Keys never touch disk in plaintext (in-memory only) - Transparent to LlmManagerService and providers - Follows proven pattern from account-encryption.middleware.ts Files: - apps/api/src/prisma/llm-encryption.middleware.ts (new) - apps/api/src/prisma/llm-encryption.middleware.spec.ts (new) - apps/api/scripts/encrypt-llm-keys.ts (new) - apps/api/prisma/migrations/20260207_encrypt_llm_api_keys/ (new) - apps/api/src/prisma/prisma.service.ts (modified) - apps/api/package.json (modified) Note: The migration script (encrypt-llm-keys.ts) is not included in tsconfig.json to avoid rootDir conflicts. It's executed via tsx which handles TypeScript directly. Refs #359 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
-- Encrypt LLM Provider API Keys Migration
|
||||
--
|
||||
-- This migration enables transparent encryption/decryption of LLM provider API keys
|
||||
-- stored in the llm_provider_instances.config JSON field.
|
||||
--
|
||||
-- IMPORTANT: This is a data migration with no schema changes.
|
||||
--
|
||||
-- Strategy:
|
||||
-- 1. Prisma middleware (llm-encryption.middleware.ts) handles encryption/decryption
|
||||
-- 2. Middleware auto-detects encryption format:
|
||||
-- - vault:v1:... = OpenBao Transit encrypted
|
||||
-- - Otherwise = Legacy plaintext (backward compatible)
|
||||
-- 3. New API keys are always encrypted on write
|
||||
-- 4. Existing plaintext keys work until re-saved (lazy migration)
|
||||
--
|
||||
-- To actively encrypt all existing API keys NOW:
|
||||
-- pnpm --filter @mosaic/api migrate:encrypt-llm-keys
|
||||
--
|
||||
-- This approach ensures:
|
||||
-- - Zero downtime migration
|
||||
-- - No schema changes required
|
||||
-- - Backward compatible with plaintext keys
|
||||
-- - Progressive encryption as keys are accessed/updated
|
||||
-- - Easy rollback (middleware is idempotent)
|
||||
--
|
||||
-- Note: No SQL changes needed. This file exists for migration tracking only.
|
||||
Reference in New Issue
Block a user