将行级安全策略继承到 children/relations
Inherit row level security policy to children/relations
考虑按照以下步骤对我目前关注的两个 table 应用 row-level 安全措施:
create table parent
(
parent_id bigint primary key,
qualifier text not null,
content text
);
create table child1
(
child1_id bigint primary key,
parent_id bigint references parent on delete cascade,
qualifier text not null,
content text
);
-- trying to boost rls performance
create index on parent (qualifier);
create index on child1 (qualifier);
-- insert test data
insert into parent values (1, 'CH', 'some secret values');
insert into parent values (2, 'FR', 'some secret values');
insert into parent values (3, 'MX', 'some secret values');
insert into child1 values (1, 1, 'CH', 'CH addendum');
insert into child1 values (2, 2, 'FR', 'FR addendum');
insert into child1 values (3, 3, 'MX', 'MX addendum');
-- create roles
create role readers;
create role ch_readers;
create role fr_readers;
-- Add roles to group role
grant readers to ch_readers, fr_readers;
-- grant basic read privileges
grant select on parent, child1 to readers;
-- create concrete users and grant corresponding roles
create user ueli with password 'pass123' role ch_readers;
create user jaques with password 'pass123' role fr_readers;
-- enable rls on tables
alter table parent enable row level security;
alter table child1 enable row level security;
-- create policies
create policy ch_reader_policy on parent for select to ch_readers using (qualifier = 'CH');
create policy ch_reader_policy on child1 for select to ch_readers using (qualifier = 'CH');
create policy fr_reader_policy on parent for select to fr_readers using (qualifier = 'FR');
create policy fr_reader_policy on child1 for select to fr_readers using (qualifier = 'FR');
这将只允许 select 行,其中 qualifier = 'CH'
用户 ueli
分别 FR
用户 jaques
并且按缩进方式工作。
但是,有没有办法只依赖parent.qualifier
,让策略对关系中的每一行都生效?
喜欢 child1,child2,...,这样我就不必 a) create/maintain 每个 child table 和 b) 更重要的是可以为每个角色节省额外的策略吗?
我面临 20 个 table 需要 RLS 保护,大约有 20 个不同的限定词。如果我的数学是正确的,我最终会得到 400 条政策。
so that I don't have to create/maintain an additional qualifier for each child table
是:
CREATE POLICY ch_reader_policy ON child1
FOR SELECT
TO ch_readers
USING ((
SELECT qualifier
FROM public.parent
WHERE public.parent.parent_id = parent_id
) = 'CH');
或更简单(因为 parent
上的 ch_reader_policy
也将应用于子策略中的 SELECT
:
CREATE POLICY ch_reader_policy ON child1
FOR SELECT
TO ch_readers
USING (EXISTS(
SELECT *
FROM public.parent
WHERE public.parent.parent_id = parent_id
));
more important: so that I can spare the additional policy for each role?
没有。您仍然需要每个 table 和角色的策略。
考虑按照以下步骤对我目前关注的两个 table 应用 row-level 安全措施:
create table parent
(
parent_id bigint primary key,
qualifier text not null,
content text
);
create table child1
(
child1_id bigint primary key,
parent_id bigint references parent on delete cascade,
qualifier text not null,
content text
);
-- trying to boost rls performance
create index on parent (qualifier);
create index on child1 (qualifier);
-- insert test data
insert into parent values (1, 'CH', 'some secret values');
insert into parent values (2, 'FR', 'some secret values');
insert into parent values (3, 'MX', 'some secret values');
insert into child1 values (1, 1, 'CH', 'CH addendum');
insert into child1 values (2, 2, 'FR', 'FR addendum');
insert into child1 values (3, 3, 'MX', 'MX addendum');
-- create roles
create role readers;
create role ch_readers;
create role fr_readers;
-- Add roles to group role
grant readers to ch_readers, fr_readers;
-- grant basic read privileges
grant select on parent, child1 to readers;
-- create concrete users and grant corresponding roles
create user ueli with password 'pass123' role ch_readers;
create user jaques with password 'pass123' role fr_readers;
-- enable rls on tables
alter table parent enable row level security;
alter table child1 enable row level security;
-- create policies
create policy ch_reader_policy on parent for select to ch_readers using (qualifier = 'CH');
create policy ch_reader_policy on child1 for select to ch_readers using (qualifier = 'CH');
create policy fr_reader_policy on parent for select to fr_readers using (qualifier = 'FR');
create policy fr_reader_policy on child1 for select to fr_readers using (qualifier = 'FR');
这将只允许 select 行,其中 qualifier = 'CH'
用户 ueli
分别 FR
用户 jaques
并且按缩进方式工作。
但是,有没有办法只依赖parent.qualifier
,让策略对关系中的每一行都生效?
喜欢 child1,child2,...,这样我就不必 a) create/maintain 每个 child table 和 b) 更重要的是可以为每个角色节省额外的策略吗?
我面临 20 个 table 需要 RLS 保护,大约有 20 个不同的限定词。如果我的数学是正确的,我最终会得到 400 条政策。
so that I don't have to create/maintain an additional qualifier for each child table
是:
CREATE POLICY ch_reader_policy ON child1
FOR SELECT
TO ch_readers
USING ((
SELECT qualifier
FROM public.parent
WHERE public.parent.parent_id = parent_id
) = 'CH');
或更简单(因为 parent
上的 ch_reader_policy
也将应用于子策略中的 SELECT
:
CREATE POLICY ch_reader_policy ON child1
FOR SELECT
TO ch_readers
USING (EXISTS(
SELECT *
FROM public.parent
WHERE public.parent.parent_id = parent_id
));
more important: so that I can spare the additional policy for each role?
没有。您仍然需要每个 table 和角色的策略。