Skip to content

Commit 029e549

Browse files
committed
sql: validate RLS policy exemptions for constraints
Unique and foreign key constraints on tables with row-level security (RLS) enabled are exempt from RLS policies when enforcing constraints. This exemption was implemented previously. This commit adds tests to validate that RLS policies do not interfere with constraint enforcement. Closes cockroachdb#136747 Epic: CRDB-45203 Release note: none
1 parent 7c6e428 commit 029e549

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

pkg/sql/logictest/testdata/logic_test/row_level_security

+173
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,179 @@ SET ROLE root
14571457
statement ok
14581458
DROP TABLE force_check CASCADE;
14591459

1460+
# Test to make sure that the scan to enforce uniqueness is done without RLS policies.
1461+
subtest uniq
1462+
1463+
statement ok
1464+
CREATE TABLE uniq (rls_col TEXT, uniq_col INT8 UNIQUE);
1465+
1466+
statement ok
1467+
CREATE USER uniq_user;
1468+
1469+
statement ok
1470+
GRANT ALL ON uniq TO uniq_user;
1471+
1472+
statement ok
1473+
ALTER TABLE uniq OWNER TO uniq_user;
1474+
1475+
statement ok
1476+
SET ROLE uniq_user;
1477+
1478+
statement ok
1479+
ALTER TABLE uniq NO FORCE ROW LEVEL SECURITY, ENABLE ROW LEVEL SECURITY;
1480+
1481+
statement ok
1482+
CREATE POLICY access ON uniq USING (rls_col = 'cat');
1483+
1484+
statement ok
1485+
INSERT INTO uniq VALUES ('cat', 1), ('cat', 2), ('dog', 3), ('cat', 4), ('hamster', 5);
1486+
1487+
statement ok
1488+
ALTER TABLE uniq FORCE ROW LEVEL SECURITY;
1489+
1490+
statement error pq: duplicate key value violates unique constraint "uniq_uniq_col_key"\nDETAIL: Key \(uniq_col\)=\(3\) already exists.
1491+
INSERT INTO uniq VALUES ('cat', 3);
1492+
1493+
statement ok
1494+
INSERT INTO uniq VALUES ('cat', 6);
1495+
1496+
statement error pq: duplicate key value violates unique constraint "uniq_uniq_col_key"\nDETAIL: Key \(uniq_col\)=\(5\) already exists.
1497+
UPDATE uniq SET uniq_col = 5 WHERE uniq_col = 1;
1498+
1499+
statement ok
1500+
UPDATE uniq SET uniq_col = 7 WHERE uniq_col = 1;
1501+
1502+
# Ensure that any attempts to update an invisible row will be a no-op
1503+
query TI
1504+
UPDATE uniq SET uniq_col = 8 WHERE uniq_col = 5 RETURNING rls_col, uniq_col;
1505+
----
1506+
1507+
statement ok
1508+
ALTER TABLE uniq NO FORCE ROW LEVEL SECURITY;
1509+
1510+
query TI
1511+
select rls_col, uniq_col FROM uniq ORDER BY uniq_col;
1512+
----
1513+
cat 2
1514+
dog 3
1515+
cat 4
1516+
hamster 5
1517+
cat 6
1518+
cat 7
1519+
1520+
statement ok
1521+
SET ROLE root;
1522+
1523+
statement ok
1524+
DROP TABLE uniq;
1525+
1526+
statement ok
1527+
DROP USER uniq_user;
1528+
1529+
# Test to make sure that the scan to enforce foreign keys is done without RLS policies.
1530+
subtest fk
1531+
1532+
statement ok
1533+
CREATE TABLE parent (key INT8 NOT NULL PRIMARY KEY);
1534+
1535+
statement ok
1536+
CREATE TABLE child (
1537+
rls_col TEXT,
1538+
key INT8 NOT NULL,
1539+
CONSTRAINT fk FOREIGN KEY (key) REFERENCES parent(key) ON DELETE CASCADE
1540+
);
1541+
1542+
statement ok
1543+
CREATE USER fk_user;
1544+
1545+
statement ok
1546+
GRANT ALL ON parent TO fk_user;
1547+
1548+
statement ok
1549+
GRANT ALL ON child TO fk_user;
1550+
1551+
statement ok
1552+
ALTER TABLE parent OWNER TO fk_user;
1553+
1554+
statement ok
1555+
ALTER TABLE child OWNER TO fk_user;
1556+
1557+
statement ok
1558+
SET ROLE fk_user;
1559+
1560+
statement ok
1561+
INSERT INTO parent SELECT * FROM generate_series(1,6);
1562+
1563+
statement ok
1564+
INSERT INTO child VALUES ('bedroom', 1), ('office', 2)
1565+
1566+
# Set RLS at the parent and ensure FK still enforced.
1567+
statement ok
1568+
ALTER TABLE parent ENABLE ROW LEVEL SECURITY, FORCE ROW LEVEL SECURITY;
1569+
1570+
statement error pq: insert on table "child" violates foreign key constraint "fk"
1571+
INSERT INTO child VALUES ('hall', 7);
1572+
1573+
statement ok
1574+
INSERT INTO child VALUES ('hall', 3);
1575+
1576+
# mimic the FK lookup to show that the given RLS policies will hide the value
1577+
query I
1578+
SELECT 1 FROM parent WHERE key = 3;
1579+
----
1580+
1581+
query I
1582+
SELECT key FROM child ORDER BY key;
1583+
----
1584+
1
1585+
2
1586+
3
1587+
1588+
# Set RLS at the child and ensure FK still enforced
1589+
statement ok
1590+
ALTER TABLE child ENABLE ROW LEVEL SECURITY, FORCE ROW LEVEL SECURITY;
1591+
1592+
statement ok
1593+
CREATE POLICY ins1 ON child FOR INSERT WITH CHECK (rls_col = 'bedroom');
1594+
1595+
statement error pq: insert on table "child" violates foreign key constraint "fk"
1596+
INSERT INTO child VALUES ('bedroom', 7);
1597+
1598+
statement error pq: new row violates row-level security policy for table "child"
1599+
INSERT INTO child VALUES ('deck', 7);
1600+
1601+
statement ok
1602+
INSERT INTO child VALUES ('bedroom', 4);
1603+
1604+
# Disable RLS at the parent so that we can do a delete and have it cascade down
1605+
statement ok
1606+
ALTER TABLE parent NO FORCE ROW LEVEL SECURITY;
1607+
1608+
statement ok
1609+
DELETE FROM parent WHERE key = 1;
1610+
1611+
statement ok
1612+
CREATE POLICY sel1 ON child FOR SELECT USING (true);
1613+
1614+
query I
1615+
SELECT key FROM child ORDER BY key;
1616+
----
1617+
2
1618+
3
1619+
4
1620+
1621+
statement ok
1622+
SET ROLE root
1623+
1624+
statement ok
1625+
DROP TABLE child;
1626+
1627+
statement ok
1628+
DROP TABLE parent;
1629+
1630+
statement ok
1631+
DROP USER fk_user;
1632+
14601633
subtest truncate
14611634

14621635
statement ok

0 commit comments

Comments
 (0)