Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/prisma/rls/crypto-isolation.sql
T
2026-07-08 16:15:37 +02:00

53 lines
2.6 KiB
SQL

-- R-P5 · per-tenant encryption keys — RLS ROLLOUT ARTIFACT (deferred, NOT in the auto-migration)
-- =============================================================================
-- Companion to prisma/rls/tenant-isolation.sql (R-P2b) and the per-module RLS
-- blocks (file/task/hr). The TenantEncryptionKey table ships in the tracked merge
-- migration (created at main-merge per AD-21); the Row-Level-Security block lives
-- HERE, deliberately out of the auto-migration path: enabling RLS before every
-- access sets the GUC would break reads, so activation is a coordinated cutover.
--
-- WHY DEFERRED: with RLS + FORCE on, any query WITHOUT `app.tenant_id` returns
-- ZERO rows. The orchestration in packages/db/src/crypto/tenant-envelope.server.ts
-- always scopes by `where: { tenantId }`, so app-level scoping carries isolation
-- until the P5 cutover (R-P2b switches the runtime role to hivegrid_app,
-- NOSUPERUSER NOBYPASSRLS).
--
-- NOTE: the wrapped DEK is useless without the app master key, so even a full
-- table leak exposes no plaintext. RLS here is defence-in-depth + symmetry with
-- the other tenant tables, not the primary control.
--
-- Forward-only (DoD 28). Inverse SQL as comment. Idempotent, DO-guarded (P3018).
--
-- Inverse:
-- REVOKE SELECT, INSERT, UPDATE, DELETE ON "TenantEncryptionKey" FROM hivegrid_app;
-- DROP POLICY IF EXISTS "TenantEncryptionKey_tenant_isolation" ON "TenantEncryptionKey";
-- ALTER TABLE "TenantEncryptionKey" NO FORCE ROW LEVEL SECURITY;
-- ALTER TABLE "TenantEncryptionKey" DISABLE ROW LEVEL SECURITY;
-- =============================================================================
DO $$
BEGIN
ALTER TABLE "TenantEncryptionKey" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "TenantEncryptionKey" FORCE ROW LEVEL SECURITY;
IF NOT EXISTS (
SELECT 1 FROM pg_policies
WHERE schemaname = current_schema()
AND tablename = 'TenantEncryptionKey'
AND policyname = 'TenantEncryptionKey_tenant_isolation'
) THEN
CREATE POLICY "TenantEncryptionKey_tenant_isolation" ON "TenantEncryptionKey"
USING ("tenantId" = current_setting('app.tenant_id', true))
WITH CHECK ("tenantId" = current_setting('app.tenant_id', true));
END IF;
GRANT SELECT, INSERT, UPDATE, DELETE ON "TenantEncryptionKey" TO hivegrid_app;
END
$$;
-- =============================================================================
-- Verify before the cutover migration (AGENTS.md §Prisma):
-- pnpm prisma validate · pnpm prisma migrate status
-- CI: prisma migrate deploy against an EMPTY DB (reproducible from scratch).
-- =============================================================================