Harden authentication, tenant isolation and security boundaries

This commit is contained in:
t.indorf
2026-10-09 22:49:55 +02:00
parent ec3f4f933d
commit 656ada80bd
71 changed files with 3107 additions and 1200 deletions
+34
View File
@@ -0,0 +1,34 @@
import { PrismaClient } from '@prisma/client';
const password = process.env.APP_DATABASE_PASSWORD;
if (!password || password.length < 24 || password.length > 256) {
throw new Error('Set APP_DATABASE_PASSWORD to a dedicated password of 24–256 characters.');
}
const prisma = new PrismaClient();
async function main() {
const existing = await prisma.$queryRaw`SELECT 1 FROM pg_roles WHERE rolname = 'kita_runtime'`;
if (!existing.length) await prisma.$executeRawUnsafe('CREATE ROLE kita_runtime LOGIN');
const owned = await prisma.$queryRaw`SELECT 1 FROM pg_class c JOIN pg_roles r ON c.relowner = r.oid WHERE r.rolname = 'kita_runtime'
UNION ALL SELECT 1 FROM pg_namespace n JOIN pg_roles r ON n.nspowner = r.oid WHERE r.rolname = 'kita_runtime'`;
if (owned.length) throw new Error('Runtime role must not own tables or schemas.');
const memberships = await prisma.$queryRaw`SELECT quote_ident(r.rolname) AS role FROM pg_auth_members m JOIN pg_roles r ON m.roleid = r.oid
JOIN pg_roles member ON m.member = member.oid WHERE member.rolname = 'kita_runtime'`;
for (const membership of memberships) await prisma.$executeRawUnsafe(`REVOKE ${membership.role} FROM kita_runtime`);
// PostgreSQL quotes the secret. Only this server-produced SQL is executed.
const [quoted] = await prisma.$queryRaw`SELECT format('ALTER ROLE kita_runtime PASSWORD %L LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS NOREPLICATION', ${password}) AS statement`;
await prisma.$executeRawUnsafe(quoted.statement);
for (const statement of [
'REVOKE CREATE ON SCHEMA public FROM PUBLIC',
'GRANT USAGE ON SCHEMA public TO kita_runtime',
'GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO kita_runtime',
'GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO kita_runtime',
'REVOKE ALL ON TABLE _prisma_migrations FROM kita_runtime',
'REVOKE UPDATE, DELETE, TRUNCATE ON TABLE audit_logs FROM kita_runtime',
]) await prisma.$executeRawUnsafe(statement);
console.log('Runtime database grants configured. Re-run after future migrations.');
}
main().finally(() => prisma.$disconnect()).catch(error => {
// Avoid putting a statement containing credentials into deployment logs.
console.error('Runtime role provisioning failed:', error?.code ?? error?.name ?? 'unknown');
process.exitCode = 1;
});