feat: implement per-tenant API key management with AES-256-GCM encryption
Add encrypted API key storage for AI providers (Anthropic, OpenAI, Ollama) with admin-only CRUD endpoints, tenant isolation, and audit logging. - DB migration: tenant_api_keys table with RLS policy - AES-256-GCM encryption utility (ENCRYPTION_KEY env var) - CRUD API: GET/POST /api/settings/api-keys, PATCH/DELETE /api/settings/api-keys/[id] - Provider integration: getModelForTenant() checks tenant keys before env fallback - Frontend: API key management section in Einstellungen page - Audit logging on all key CRUD operations (DSGVO) Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
31
drizzle/0003_tenant_api_keys.sql
Normal file
31
drizzle/0003_tenant_api_keys.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
-- Migration: Add tenant_api_keys table for per-tenant encrypted API key storage
|
||||
|
||||
CREATE TYPE "api_key_provider" AS ENUM ('anthropic', 'openai', 'ollama');
|
||||
|
||||
CREATE TABLE "tenant_api_keys" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"tenant_id" uuid NOT NULL REFERENCES "tenants"("id") ON DELETE CASCADE,
|
||||
"provider" "api_key_provider" NOT NULL,
|
||||
"encrypted_key" text NOT NULL,
|
||||
"key_hint" varchar(8) NOT NULL,
|
||||
"label" varchar(100),
|
||||
"is_active" boolean NOT NULL DEFAULT true,
|
||||
"created_by_user_id" uuid REFERENCES "users"("id"),
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "tenant_api_keys_tenant_provider_label_idx"
|
||||
ON "tenant_api_keys" ("tenant_id", "provider", "label");
|
||||
|
||||
CREATE INDEX "tenant_api_keys_tenant_idx"
|
||||
ON "tenant_api_keys" ("tenant_id");
|
||||
|
||||
CREATE INDEX "tenant_api_keys_provider_idx"
|
||||
ON "tenant_api_keys" ("tenant_id", "provider", "is_active");
|
||||
|
||||
-- RLS policy: tenants can only see their own API keys
|
||||
ALTER TABLE "tenant_api_keys" ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY "tenant_api_keys_tenant_isolation" ON "tenant_api_keys"
|
||||
USING ("tenant_id" = current_setting('app.tenant_id', true)::uuid);
|
||||
Reference in New Issue
Block a user