/ script / meta_rbac_init.sql
meta_rbac_init.sql
  1  -- SPDX-FileCopyrightText: 2023 LakeSoul Contributors
  2  --
  3  -- SPDX-License-Identifier: Apache-2.0
  4  
  5  ALTER TABLE namespace
  6      ENABLE ROW LEVEL SECURITY;
  7  CREATE INDEX CONCURRENTLY IF NOT EXISTS namespace_domain_index ON namespace (domain);
  8  DO
  9  $$
 10      BEGIN
 11          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'namespace') THEN
 12              -- admins/users can read namespaces in the domains they belong to and the public domain
 13              CREATE POLICY read_policy ON namespace AS PERMISSIVE FOR SELECT USING (
 14                          domain = 'public'
 15                      OR domain = 'lake-public'
 16                      OR domain = current_user
 17                      OR domain IN (SELECT rolname
 18                                    FROM pg_roles
 19                                    WHERE pg_has_role(current_user, oid, 'member')));
 20  
 21              -- only admin role in workspace is allowed to create/drop namespace
 22              CREATE POLICY update_policy ON namespace AS PERMISSIVE FOR UPDATE
 23                  USING (concat(domain, '_admins') IN (SELECT rolname
 24                                                       FROM pg_roles
 25                                                       WHERE pg_has_role(current_user, oid, 'member')));
 26              CREATE POLICY insert_policy ON namespace AS PERMISSIVE FOR INSERT
 27                  WITH CHECK (concat(domain, '_admins') IN (SELECT rolname
 28                                                       FROM pg_roles
 29                                                       WHERE pg_has_role(current_user, oid, 'member')));
 30              CREATE POLICY delete_policy ON namespace AS PERMISSIVE FOR DELETE
 31                  USING (concat(domain, '_admins') IN (SELECT rolname
 32                                                       FROM pg_roles
 33                                                       WHERE pg_has_role(current_user, oid, 'member')));
 34          END IF;
 35      END
 36  $$;
 37  
 38  ALTER TABLE table_info
 39      ENABLE ROW LEVEL SECURITY;
 40  CREATE INDEX CONCURRENTLY IF NOT EXISTS table_info_domain_index ON table_info (domain);
 41  DO
 42  $$
 43      BEGIN
 44          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'table_info') THEN
 45              CREATE POLICY domain_only_policy ON table_info
 46                  USING (
 47                          domain = 'public'
 48                      OR domain = 'lake-public'
 49                      OR domain = current_user
 50                      OR domain IN (SELECT rolname
 51                                    FROM pg_roles
 52                                    WHERE pg_has_role(current_user, oid, 'member')));
 53          END IF;
 54      END
 55  $$;
 56  
 57  ALTER TABLE table_path_id
 58      ENABLE ROW LEVEL SECURITY;
 59  CREATE INDEX CONCURRENTLY IF NOT EXISTS table_path_id_domain_index ON table_path_id (domain);
 60  DO
 61  $$
 62      BEGIN
 63          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'table_path_id') THEN
 64              CREATE POLICY domain_only_policy ON table_path_id
 65                  USING (
 66                          domain = 'public'
 67                      OR domain = 'lake-public'
 68                      OR domain = current_user
 69                      OR domain IN (SELECT rolname
 70                                    FROM pg_roles
 71                                    WHERE pg_has_role(current_user, oid, 'member')));
 72          END IF;
 73      END
 74  $$;
 75  
 76  ALTER TABLE table_name_id
 77      ENABLE ROW LEVEL SECURITY;
 78  CREATE INDEX CONCURRENTLY IF NOT EXISTS table_name_id_domain_index ON table_name_id (domain);
 79  DO
 80  $$
 81      BEGIN
 82          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'table_name_id') THEN
 83              CREATE POLICY domain_only_policy ON table_name_id
 84                  USING (
 85                          domain = 'public'
 86                      OR domain = 'lake-public'
 87                      OR domain = current_user
 88                      OR domain IN (SELECT rolname
 89                                    FROM pg_roles
 90                                    WHERE pg_has_role(current_user, oid, 'member')));
 91          END IF;
 92      END
 93  $$;
 94  
 95  ALTER TABLE data_commit_info
 96      ENABLE ROW LEVEL SECURITY;
 97  CREATE INDEX CONCURRENTLY IF NOT EXISTS data_commit_info_domain_index ON data_commit_info (domain);
 98  DO
 99  $$
100      BEGIN
101          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'data_commit_info') THEN
102              CREATE POLICY domain_only_policy ON data_commit_info
103                  USING (
104                          domain = 'public'
105                      OR domain = 'lake-public'
106                      OR domain = current_user
107                      OR domain IN (SELECT rolname
108                                    FROM pg_roles
109                                    WHERE pg_has_role(current_user, oid, 'member')));
110          END IF;
111      END
112  $$;
113  
114  ALTER TABLE partition_info
115      ENABLE ROW LEVEL SECURITY;
116  CREATE INDEX CONCURRENTLY IF NOT EXISTS partition_info_domain_index ON partition_info (domain);
117  DO
118  $$
119      BEGIN
120          IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename = 'partition_info') THEN
121              CREATE POLICY domain_only_policy ON partition_info
122                  USING (
123                          domain = 'public'
124                      OR domain = 'lake-public'
125                      OR domain = current_user
126                      OR domain IN (SELECT rolname
127                                    FROM pg_roles
128                                    WHERE pg_has_role(current_user, oid, 'member')));
129          END IF;
130      END
131  $$;
132  
133  
134  
135  -- create table if not exists casbin_rule
136  -- (
137  --     id    integer default nextval('casbin_sequence'::regclass) not null
138  --     primary key,
139  --     ptype varchar(100)                                         not null,
140  --     v0    varchar(100),
141  --     v1    varchar(100),
142  --     v2    varchar(100),
143  --     v3    varchar(100),
144  --     v4    varchar(100),
145  --     v5    varchar(100)
146  -- );
147  DO
148  $$
149      BEGIN
150          IF (select count(*) from information_schema.tables where table_name = 'casbin_rule') = 0
151          THEN
152              CREATE SEQUENCE IF NOT EXISTS CASBIN_SEQUENCE START 1;
153              CREATE TABLE IF NOT EXISTS casbin_rule
154              (
155                  id    int          NOT NULL PRIMARY KEY default nextval('CASBIN_SEQUENCE'::regclass),
156                  ptype VARCHAR(100) NOT NULL,
157                  v0    VARCHAR(100),
158                  v1    VARCHAR(100),
159                  v2    VARCHAR(100),
160                  v3    VARCHAR(100),
161                  v4    VARCHAR(100),
162                  v5    VARCHAR(100)
163              );
164              CREATE POLICY read_policy ON casbin_rule FOR SELECT
165                  USING (
166                      (ptype = 'g' AND v0 = current_user AND v1 IN (SELECT rolname
167                                                                    FROM pg_roles
168                                                                    WHERE pg_has_role(current_user, oid, 'member')))
169                      OR
170                      (ptype = 'p' AND v0 IN (SELECT rolname
171                                              FROM pg_roles
172                                              WHERE pg_has_role(current_user, oid, 'member'))));
173              CREATE POLICY update_policy ON casbin_rule FOR UPDATE
174                  USING (
175                      (ptype = 'g' AND v0 = current_user
176                          AND concat(v1, '_admins') IN (SELECT rolname
177                                                        FROM pg_roles
178                                                        WHERE pg_has_role(current_user, oid, 'member')))
179                      OR
180                      (ptype = 'p'
181                          AND concat(v0, '_admins') IN (SELECT rolname
182                                                        FROM pg_roles
183                                                        WHERE pg_has_role(current_user, oid, 'member'))));
184              CREATE POLICY insert_policy ON casbin_rule FOR INSERT
185                  WITH CHECK (
186                      (ptype = 'g' AND v0 = current_user
187                          AND concat(v1, '_admins') IN (SELECT rolname
188                                                        FROM pg_roles
189                                                        WHERE pg_has_role(current_user, oid, 'member')))
190                      OR
191                      (ptype = 'p'
192                          AND concat(v0, '_admins') IN (SELECT rolname
193                                                        FROM pg_roles
194                                                        WHERE pg_has_role(current_user, oid, 'member'))));
195              CREATE POLICY delete_policy ON casbin_rule FOR DELETE
196                  USING (
197                      (ptype = 'g' AND v0 = current_user
198                          AND concat(v1, '_admins') IN (SELECT rolname
199                                                        FROM pg_roles
200                                                        WHERE pg_has_role(current_user, oid, 'member')))
201                      OR
202                      (ptype = 'p'
203                          AND concat(v0, '_admins') IN (SELECT rolname
204                                                        FROM pg_roles
205                                                        WHERE pg_has_role(current_user, oid, 'member'))));
206          END IF;
207      END
208  $$;
209  
210  CREATE INDEX CONCURRENTLY IF NOT EXISTS casbin_rule_ptype_index ON casbin_rule (ptype);
211  CREATE INDEX CONCURRENTLY IF NOT EXISTS casbin_rule_v0_index ON casbin_rule (v0);
212  CREATE INDEX CONCURRENTLY IF NOT EXISTS casbin_rule_v1_index ON casbin_rule (v1);
213  
214  
215  
216  INSERT INTO global_config
217  VALUES ('lakesoul.authz.enabled', 'true')
218  ON CONFLICT (key) DO UPDATE SET value = 'true';
219  
220  INSERT INTO global_config
221  VALUES ('lakesoul.authz.casbin.model', '[request_definition]
222  r = sub, dom, obj, act
223  
224  [policy_definition]
225  p = sub, dom, obj, act
226  
227  [role_definition]
228  g = _, _, _
229  
230  [policy_effect]
231  e = some(where (p.eft == allow))
232  
233  [matchers]
234  m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act')
235  ON CONFLICT (key) DO UPDATE SET value = '[request_definition]
236  r = sub, dom, obj, act
237  
238  [policy_definition]
239  p = sub, dom, obj, act
240  
241  [role_definition]
242  g = _, _, _
243  
244  [policy_effect]
245  e = some(where (p.eft == allow))
246  
247  [matchers]
248  m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act';
249  
250  DO
251  $$
252      BEGIN
253          IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'base_user_role') THEN
254              CREATE ROLE base_super_admin_role WITH BYPASSRLS CREATEROLE;
255              CREATE ROLE base_admin_role;
256              CREATE ROLE base_user_role;
257          END IF;
258      END
259  $$;
260  
261  GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO base_super_admin_role;
262  GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO base_admin_role;
263  GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO base_user_role;
264  
265  -- admins are not allowed to modify global_config table
266  REVOKE INSERT, UPDATE, DELETE ON TABLE global_config FROM base_admin_role;
267  
268  -- users are not allowed to modify global_config, namespace and casbin_rule table
269  REVOKE INSERT, UPDATE, DELETE ON TABLE namespace FROM base_user_role;
270  REVOKE INSERT, UPDATE, DELETE ON TABLE global_config FROM base_user_role;
271  REVOKE INSERT, UPDATE, DELETE ON TABLE casbin_rule FROM base_user_role;
272  
273  ALTER TABLE table_info ADD creator TEXT default current_user;
274  ALTER TABLE namespace ADD creator TEXT default current_user;