fix(security): disable RLS on roles/permissions — blocks login (0109)
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"""Disable RLS on login-related tables (roles, permissions).
|
||||
|
||||
⚠️ KI / AGENT HINWEIS — BITTE VOR ÄNDERUNGEN LESEN ⚠️
|
||||
|
||||
Migration 0108 hat RLS auf alle Tabellen mit tenant_id aktiviert, darunter auch
|
||||
`roles` und `permissions`. Diese Tabellen werden vom Login-Flow gelesen um die
|
||||
Benutzerrolle zu bestimmen. Mit RLS auf diesen Tabellen und keinem tenant_id
|
||||
Kontext beim Login → Query gibt nichts zurück → Login schlägt fehl mit 401.
|
||||
|
||||
Diese Tabellen MÜSSEN ohne RLS bleiben, genau wie users, sessions, tenants,
|
||||
user_tenants, password_reset_tokens (siehe 0108 LOGIN_TABLES).
|
||||
|
||||
Lektion: RLS darf NICHT auf Tabellen aktiviert werden die vom Login-Flow
|
||||
gelesen werden, wenn der Login-Flow noch keinen tenant_id Kontext hat.
|
||||
|
||||
Revision ID: 0109
|
||||
Revises: 0108
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from alembic import op
|
||||
|
||||
revision = "0109"
|
||||
down_revision = "0108"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
# ⚠️ LOGIN-RELATED TABLES — KEIN RLS! Diese Tabellen werden vom Login-Flow
|
||||
# gelesen bevor ein tenant_id Kontext existiert. RLS blockiert den Login.
|
||||
# Siehe auch 0108 LOGIN_TABLES und 0085 AUTH_TABLES.
|
||||
LOGIN_RELATED_TABLES = [
|
||||
"roles",
|
||||
"permissions",
|
||||
]
|
||||
|
||||
|
||||
def _exec(sql: str) -> None:
|
||||
op.execute(sql)
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Disable RLS on login-related tables
|
||||
for table in LOGIN_RELATED_TABLES:
|
||||
_exec(
|
||||
f"DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables "
|
||||
f"WHERE table_schema = 'public' AND table_name = '{table}') THEN "
|
||||
f"DROP POLICY IF EXISTS tenant_isolation ON public.{table}; "
|
||||
f"DROP POLICY IF EXISTS {table}_tenant_isolation ON public.{table}; "
|
||||
f"ALTER TABLE public.{table} DISABLE ROW LEVEL SECURITY; "
|
||||
f"END IF; END $$"
|
||||
)
|
||||
|
||||
# Ensure crm_auth can read roles and permissions (needed for login flow)
|
||||
for table in LOGIN_RELATED_TABLES:
|
||||
_exec(
|
||||
f"DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables "
|
||||
f"WHERE table_schema = 'public' AND table_name = '{table}') THEN "
|
||||
f"GRANT SELECT ON public.{table} TO crm_auth; "
|
||||
f"END IF; END $$"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
pass
|
||||
Reference in New Issue
Block a user