Files
pgmorbac/src/system_rls.sql
T

227 lines
10 KiB
SQL

-- RLS policies for morbac system tables.
--
-- is_allowed() and its internal callees are SECURITY DEFINER, so they run as
-- the extension owner and bypass RLS. This prevents infinite recursion when
-- these policies fire.
--
-- View names used in rules are config-driven (system_view.*).
-- Override with morbac.set_config('system_view.orgs', 'my_orgs') etc.
-- The new name must exist in morbac.views and your rules must reference it.
--
-- RLS is disabled for the superuser/extension owner by default (PostgreSQL
-- behavior). Bootstrap the first organization and superuser role as the
-- database owner before enabling this in production.
-- morbac.orgs
-- Row's org context is the org itself.
ALTER TABLE morbac.orgs ENABLE ROW LEVEL SECURITY;
CREATE POLICY orgs_select ON morbac.orgs FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), id, 'read',
morbac.get_config('system_view.orgs')));
CREATE POLICY orgs_insert ON morbac.orgs FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'create',
morbac.get_config('system_view.orgs')));
CREATE POLICY orgs_update ON morbac.orgs FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), id, 'update',
morbac.get_config('system_view.orgs')));
CREATE POLICY orgs_delete ON morbac.orgs FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), id, 'delete',
morbac.get_config('system_view.orgs')));
-- morbac.roles
ALTER TABLE morbac.roles ENABLE ROW LEVEL SECURITY;
CREATE POLICY roles_select ON morbac.roles FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'read',
morbac.get_config('system_view.roles')));
CREATE POLICY roles_insert ON morbac.roles FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), org_id, 'create',
morbac.get_config('system_view.roles')));
CREATE POLICY roles_update ON morbac.roles FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'update',
morbac.get_config('system_view.roles')));
CREATE POLICY roles_delete ON morbac.roles FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'delete',
morbac.get_config('system_view.roles')));
-- morbac.rules
ALTER TABLE morbac.rules ENABLE ROW LEVEL SECURITY;
CREATE POLICY rules_select ON morbac.rules FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'read',
morbac.get_config('system_view.rules')));
CREATE POLICY rules_insert ON morbac.rules FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), org_id, 'create',
morbac.get_config('system_view.rules')));
CREATE POLICY rules_update ON morbac.rules FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'update',
morbac.get_config('system_view.rules')));
CREATE POLICY rules_delete ON morbac.rules FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'delete',
morbac.get_config('system_view.rules')));
-- morbac.user_roles
ALTER TABLE morbac.user_roles ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_roles_select ON morbac.user_roles FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'read',
morbac.get_config('system_view.user_roles')));
CREATE POLICY user_roles_insert ON morbac.user_roles FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), org_id, 'create',
morbac.get_config('system_view.user_roles')));
CREATE POLICY user_roles_delete ON morbac.user_roles FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'delete',
morbac.get_config('system_view.user_roles')));
-- morbac.contexts (global — use current session org for writes)
ALTER TABLE morbac.contexts ENABLE ROW LEVEL SECURITY;
CREATE POLICY contexts_select ON morbac.contexts FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'read',
morbac.get_config('system_view.contexts')));
CREATE POLICY contexts_insert ON morbac.contexts FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'create',
morbac.get_config('system_view.contexts')));
CREATE POLICY contexts_update ON morbac.contexts FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'update',
morbac.get_config('system_view.contexts')));
CREATE POLICY contexts_delete ON morbac.contexts FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'delete',
morbac.get_config('system_view.contexts')));
-- morbac.activities (global — use current session org for writes)
ALTER TABLE morbac.activities ENABLE ROW LEVEL SECURITY;
CREATE POLICY activities_select ON morbac.activities FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'read',
morbac.get_config('system_view.activities')));
CREATE POLICY activities_insert ON morbac.activities FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'create',
morbac.get_config('system_view.activities')));
CREATE POLICY activities_update ON morbac.activities FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'update',
morbac.get_config('system_view.activities')));
CREATE POLICY activities_delete ON morbac.activities FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'delete',
morbac.get_config('system_view.activities')));
-- morbac.views (global — use current session org for writes)
ALTER TABLE morbac.views ENABLE ROW LEVEL SECURITY;
CREATE POLICY views_select ON morbac.views FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'read',
morbac.get_config('system_view.views')));
CREATE POLICY views_insert ON morbac.views FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'create',
morbac.get_config('system_view.views')));
CREATE POLICY views_update ON morbac.views FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'update',
morbac.get_config('system_view.views')));
CREATE POLICY views_delete ON morbac.views FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'delete',
morbac.get_config('system_view.views')));
-- morbac.delegations
ALTER TABLE morbac.delegations ENABLE ROW LEVEL SECURITY;
CREATE POLICY delegations_select ON morbac.delegations FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'read',
morbac.get_config('system_view.delegations')));
CREATE POLICY delegations_insert ON morbac.delegations FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), org_id, 'create',
morbac.get_config('system_view.delegations')));
CREATE POLICY delegations_update ON morbac.delegations FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'update',
morbac.get_config('system_view.delegations')));
CREATE POLICY delegations_delete ON morbac.delegations FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'delete',
morbac.get_config('system_view.delegations')));
-- morbac.user_rules
ALTER TABLE morbac.user_rules ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_rules_select ON morbac.user_rules FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'read',
morbac.get_config('system_view.user_rules')));
CREATE POLICY user_rules_insert ON morbac.user_rules FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), org_id, 'create',
morbac.get_config('system_view.user_rules')));
CREATE POLICY user_rules_update ON morbac.user_rules FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'update',
morbac.get_config('system_view.user_rules')));
CREATE POLICY user_rules_delete ON morbac.user_rules FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), org_id, 'delete',
morbac.get_config('system_view.user_rules')));
-- morbac.system_principals (no org_id — SELECT only; INSERT/UPDATE/DELETE reserved for DB owner)
ALTER TABLE morbac.system_principals ENABLE ROW LEVEL SECURITY;
CREATE POLICY system_principals_select ON morbac.system_principals FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'read',
morbac.get_config('system_view.system_principals')));
-- morbac.global_rules (no org_id — use current session org for write checks)
ALTER TABLE morbac.global_rules ENABLE ROW LEVEL SECURITY;
CREATE POLICY global_rules_select ON morbac.global_rules FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'read',
morbac.get_config('system_view.global_rules')));
CREATE POLICY global_rules_insert ON morbac.global_rules FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'create',
morbac.get_config('system_view.global_rules')));
CREATE POLICY global_rules_update ON morbac.global_rules FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'update',
morbac.get_config('system_view.global_rules')));
CREATE POLICY global_rules_delete ON morbac.global_rules FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), morbac.current_org_id(), 'delete',
morbac.get_config('system_view.global_rules')));
-- morbac.cross_org_rules
ALTER TABLE morbac.cross_org_rules ENABLE ROW LEVEL SECURITY;
CREATE POLICY cross_org_rules_select ON morbac.cross_org_rules FOR SELECT
USING (morbac.is_allowed(morbac.current_user_id(), source_org_id, 'read',
morbac.get_config('system_view.cross_org_rules')));
CREATE POLICY cross_org_rules_insert ON morbac.cross_org_rules FOR INSERT
WITH CHECK (morbac.is_allowed(morbac.current_user_id(), source_org_id, 'create',
morbac.get_config('system_view.cross_org_rules')));
CREATE POLICY cross_org_rules_update ON morbac.cross_org_rules FOR UPDATE
USING (morbac.is_allowed(morbac.current_user_id(), source_org_id, 'update',
morbac.get_config('system_view.cross_org_rules')));
CREATE POLICY cross_org_rules_delete ON morbac.cross_org_rules FOR DELETE
USING (morbac.is_allowed(morbac.current_user_id(), source_org_id, 'delete',
morbac.get_config('system_view.cross_org_rules')));