Skip to content

Commit

Permalink
Simplify table marking utility methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianberneanu committed May 2, 2022
1 parent 8bec2aa commit 73522b6
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 94 deletions.
18 changes: 9 additions & 9 deletions docker/demo/02-banking-constraints.sql
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
--
-- accounts
--
CALL diffix.mark_personal('public', 'accounts', 'account_id');
CALL diffix.mark_personal('accounts', 'account_id');
ALTER TABLE accounts ADD CONSTRAINT accounts_pkey PRIMARY KEY (account_id);

--
-- accounts_receivables
--
CALL diffix.mark_personal('public', 'accounts_receivables', 'customerid');
CALL diffix.mark_personal('accounts_receivables', 'customerid');

--
-- credit_cards
--
CALL diffix.mark_personal('public', 'credit_cards', 'disp_id');
CALL diffix.mark_personal('credit_cards', 'disp_id');

--
-- clients
--
CALL diffix.mark_personal('public', 'clients', 'client_id');
CALL diffix.mark_personal('clients', 'client_id');

ALTER TABLE clients ADD CONSTRAINT clients_pkey PRIMARY KEY (client_id);

--
-- dispositions
--
CALL diffix.mark_personal('public', 'dispositions', 'client_id', 'account_id');
CALL diffix.mark_personal('dispositions', 'client_id', 'account_id');

ALTER TABLE dispositions ADD CONSTRAINT dispositions_pkey PRIMARY KEY (disp_id);

--
-- loans
--
CALL diffix.mark_personal('public', 'loans', 'account_id');
CALL diffix.mark_personal('loans', 'account_id');

ALTER TABLE loans ADD CONSTRAINT loans_pkey PRIMARY KEY (loan_id);

--
-- loss_events
--
SECURITY LABEL FOR pg_diffix ON TABLE loss_events IS 'public';
CALL diffix.mark_public('loss_events');

--
-- orders
--
CALL diffix.mark_personal('public', 'orders', 'account_id', 'account_to');
CALL diffix.mark_personal('orders', 'account_id', 'account_to');

ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY (order_id);

--
-- transactions
--
CALL diffix.mark_personal('public', 'transactions', 'account_id');
CALL diffix.mark_personal('transactions', 'account_id');

ALTER TABLE transactions ADD CONSTRAINT transactions_pkey PRIMARY KEY (trans_id);
8 changes: 4 additions & 4 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Tables may have one of two security labels, `public` or `personal`.
* Tables labeled as `personal` are anonymized by the extension (for `anonymized_trusted` and `anonymized_untrusted` users, not `direct` users).
* Tables labeled as `public` are not anonymized: all users have full access to these tables.

The procedure `diffix.mark_public(namespace, table_name)` labels a table as `public`.
The procedure `diffix.mark_public(table_name)` labels a table as `public`.

Note that unlabeled tables can not be queried by `anonymized_trusted` and `anonymized_untrusted` users (unless the setting variable `pg_diffix.treat_unmarked_tables_as_public` is set to `true`).

Expand All @@ -71,18 +71,18 @@ Each protected entity must have at least one column that contains the identifier

__NOTE:__ if AID columns are not correctly labeled, the extension may fail to anonymize appropriately.

The procedure `diffix.mark_personal(namespace, table_name, aid_columns...)` is used to label a table as personal and to label its AID columns.
The procedure `diffix.mark_personal(table_name, aid_columns...)` is used to label a table as personal and to label its AID columns.

For example,

```SQL
CALL diffix.mark_personal('public', 'employee_info', 'employee_id');
CALL diffix.mark_personal('employee_info', 'employee_id');
```

labels the table `employee_info` as personal, and labels the `employee_id` column as `employee_id` an AID column.

```SQL
CALL diffix.mark_personal('public', 'transactions', 'sender_acct', 'receiver_acct');
CALL diffix.mark_personal('transactions', 'sender_acct', 'receiver_acct');
```

labels the table `transactions` as personal, and labels the `sender_acct` and `receiver_acct` columns as AID columns.
Expand Down
36 changes: 9 additions & 27 deletions pg_diffix--0.0.1.sql
Original file line number Diff line number Diff line change
Expand Up @@ -39,47 +39,29 @@ AS $$
$$
SECURITY INVOKER SET search_path = '';

CREATE PROCEDURE mark_personal(table_namespace text, table_name text, variadic aid_columns text[])
CREATE PROCEDURE mark_personal(table_name text, variadic aid_columns text[])
AS $$
DECLARE
table_oid integer := (SELECT pg_class.oid
FROM pg_class, pg_namespace
WHERE pg_class.relnamespace = pg_namespace.oid AND relname = table_name AND nspname = table_namespace);
table_fullname text := quote_ident(table_namespace) || '.' || quote_ident(table_name);
aid_column text;
BEGIN
IF (SELECT @[email protected]_level()) <> 'direct' THEN
RAISE EXCEPTION '"mark_personal" requires direct access mode.';
END IF;
DELETE FROM pg_catalog.pg_seclabel WHERE provider = 'pg_diffix' AND objoid = table_name::regclass::oid AND label = 'aid';

DELETE FROM pg_catalog.pg_seclabel WHERE provider = 'pg_diffix' AND objoid = table_oid AND label = 'aid';

EXECUTE 'SECURITY LABEL FOR pg_diffix ON TABLE ' || table_fullname || ' IS ''personal''';
EXECUTE 'SECURITY LABEL FOR pg_diffix ON TABLE ' || table_name || ' IS ''personal''';

FOREACH aid_column IN ARRAY aid_columns LOOP
EXECUTE 'SECURITY LABEL FOR pg_diffix ON COLUMN ' || table_fullname || '.' || quote_ident(aid_column) || ' IS ''aid''';
EXECUTE 'SECURITY LABEL FOR pg_diffix ON COLUMN ' || table_name || '.' || aid_column || ' IS ''aid''';
END LOOP;
END;
$$ LANGUAGE plpgsql
SECURITY INVOKER SET search_path = '';
$$ LANGUAGE plpgsql;

CREATE PROCEDURE mark_public(table_namespace text, table_name text)
CREATE PROCEDURE mark_public(table_name text)
AS $$
DECLARE
table_oid integer := (SELECT pg_class.oid
FROM pg_class, pg_namespace
WHERE pg_class.relnamespace = pg_namespace.oid AND relname = table_name AND nspname = table_namespace);
BEGIN
DELETE FROM pg_catalog.pg_seclabel WHERE provider = 'pg_diffix' AND objoid = table_oid AND label = 'aid';
DELETE FROM pg_catalog.pg_seclabel WHERE provider = 'pg_diffix' AND objoid = table_name::regclass::oid AND label = 'aid';

EXECUTE 'SECURITY LABEL FOR pg_diffix ON TABLE '
|| quote_ident(table_namespace)
|| '.'
|| quote_ident(table_name)
|| ' IS ''public''';
EXECUTE 'SECURITY LABEL FOR pg_diffix ON TABLE ' || table_name || ' IS ''public''';
END;
$$ LANGUAGE plpgsql
SECURITY INVOKER SET search_path = '';
$$ LANGUAGE plpgsql;

/* ----------------------------------------------------------------
* Common aggregation interface
Expand Down
14 changes: 7 additions & 7 deletions test/expected/_setup.out
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ INSERT INTO test_patients VALUES
CREATE TABLE empty_test_customers (id INTEGER PRIMARY KEY, name TEXT, city TEXT, discount REAL);
-- Pre-filtered table to maintain LCF tests which relied on WHERE clause.
CREATE TABLE london_customers AS (SELECT * FROM test_customers WHERE city = 'London');
-- Config tables.
CALL diffix.mark_personal('public', 'test_customers', 'id');
CALL diffix.mark_personal('public', 'test_purchases', 'cid');
CALL diffix.mark_personal('public', 'test_patients', 'id', 'name');
CALL diffix.mark_personal('public', 'empty_test_customers', 'id');
CALL diffix.mark_personal('public', 'london_customers', 'id');
CALL diffix.mark_public('public', 'test_products');
-- Config tables (and also check handling of namespaces).
CALL diffix.mark_personal('public.test_customers', 'id');
CALL diffix.mark_personal('public.test_purchases', 'cid');
CALL diffix.mark_personal('public.test_patients', 'id', 'name');
CALL diffix.mark_personal('public.empty_test_customers', 'id');
CALL diffix.mark_personal('public.london_customers', 'id');
CALL diffix.mark_public('public.test_products');
-- There is no CREATE USER IF NOT EXISTS, we need to wrap and silence the output
DO $$
BEGIN
Expand Down
12 changes: 6 additions & 6 deletions test/expected/led.out
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ INSERT INTO led_with_different_titles VALUES (22, 'cs', 'f', 'asst');
CREATE TABLE led_with_star_bucket AS TABLE led_with_victim;
INSERT INTO led_with_star_bucket VALUES
(22, 'biol', 'f', 'asst'), (23, 'chem', 'm', 'asst'), (24, 'biol', 'f', 'prof');
CALL diffix.mark_personal('public', 'led_base', 'id');
CALL diffix.mark_personal('public', 'led_with_victim', 'id');
CALL diffix.mark_personal('public', 'led_with_two_victims', 'id');
CALL diffix.mark_personal('public', 'led_with_three_cs_women', 'id');
CALL diffix.mark_personal('public', 'led_with_different_titles', 'id');
CALL diffix.mark_personal('public', 'led_with_star_bucket', 'id');
CALL diffix.mark_personal('led_base', 'id');
CALL diffix.mark_personal('led_with_victim', 'id');
CALL diffix.mark_personal('led_with_two_victims', 'id');
CALL diffix.mark_personal('led_with_three_cs_women', 'id');
CALL diffix.mark_personal('led_with_different_titles', 'id');
CALL diffix.mark_personal('led_with_star_bucket', 'id');
SET ROLE diffix_test;
SET pg_diffix.session_access_level = 'anonymized_trusted';
----------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions test/expected/star_bucket.out
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ INSERT INTO star_bucket_only VALUES
(3, 'phys', 'm', 'asst'),
(4, 'cs', 'f', 'prof'),
(5, 'history', 'f', 'asst');
CALL diffix.mark_personal('public', 'star_bucket_base', 'id');
CALL diffix.mark_personal('public', 'star_bucket', 'id');
CALL diffix.mark_personal('public', 'star_bucket_suppressed_1', 'id');
CALL diffix.mark_personal('public', 'star_bucket_suppressed_2', 'id');
CALL diffix.mark_personal('public', 'star_bucket_empty', 'id');
CALL diffix.mark_personal('public', 'star_bucket_only', 'id');
CALL diffix.mark_personal('star_bucket_base', 'id');
CALL diffix.mark_personal('star_bucket', 'id');
CALL diffix.mark_personal('star_bucket_suppressed_1', 'id');
CALL diffix.mark_personal('star_bucket_suppressed_2', 'id');
CALL diffix.mark_personal('star_bucket_empty', 'id');
CALL diffix.mark_personal('star_bucket_only', 'id');
SET ROLE diffix_test;
SET pg_diffix.session_access_level = 'anonymized_trusted';
----------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion test/expected/stress.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CREATE TABLE test_stress AS (
i AS id, left(md5(random()::text), 4) AS t, (random() * 10.0)::real AS r, round(random() * 1000)::integer AS i
FROM generate_series(1, 50000) series(i)
);
CALL diffix.mark_personal('public', 'test_stress', 'id');
CALL diffix.mark_personal('test_stress', 'id');
-- Prepare test session.
SET pg_diffix.noise_layer_sd = 0;
SET pg_diffix.low_count_layer_sd = 0;
Expand Down
18 changes: 9 additions & 9 deletions test/expected/validation.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ CREATE TABLE test_validation (
lunchtime TIME,
last_seen TIMESTAMP
);
CALL diffix.mark_personal('public', 'test_validation', 'id');
CALL diffix.mark_personal('test_validation', 'id');
CREATE TABLE superclass (x INTEGER);
CREATE TABLE subclass (x INTEGER, y INTEGER);
INSERT INTO subclass VALUES (1, 2);
CALL diffix.mark_personal('public', 'superclass', 'x');
CALL diffix.mark_personal('public', 'subclass', 'y');
CALL diffix.mark_personal('superclass', 'x');
CALL diffix.mark_personal('subclass', 'y');
ALTER TABLE subclass INHERIT superclass;
-- No-op. Repeated to test the error on conflicting configuration
CALL diffix.mark_personal('public', 'superclass', 'x');
CALL diffix.mark_personal('superclass', 'x');
ERROR: [PG_DIFFIX] Anonymization over tables using inheritance is not supported.
CONTEXT: SQL statement "SECURITY LABEL FOR pg_diffix ON TABLE public.superclass IS 'personal'"
PL/pgSQL function diffix.mark_personal(text,text,text[]) line 15 at EXECUTE
CALL diffix.mark_personal('public', 'subclass', 'y');
CONTEXT: SQL statement "SECURITY LABEL FOR pg_diffix ON TABLE superclass IS 'personal'"
PL/pgSQL function diffix.mark_personal(text,text[]) line 7 at EXECUTE
CALL diffix.mark_personal('subclass', 'y');
ERROR: [PG_DIFFIX] Anonymization over tables using inheritance is not supported.
CONTEXT: SQL statement "SECURITY LABEL FOR pg_diffix ON TABLE public.subclass IS 'personal'"
PL/pgSQL function diffix.mark_personal(text,text,text[]) line 15 at EXECUTE
CONTEXT: SQL statement "SECURITY LABEL FOR pg_diffix ON TABLE subclass IS 'personal'"
PL/pgSQL function diffix.mark_personal(text,text[]) line 7 at EXECUTE
SET ROLE diffix_test;
----------------------------------------------------------------
-- Trusted mode query restrictions
Expand Down
14 changes: 7 additions & 7 deletions test/sql/_setup.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ CREATE TABLE empty_test_customers (id INTEGER PRIMARY KEY, name TEXT, city TEXT,
-- Pre-filtered table to maintain LCF tests which relied on WHERE clause.
CREATE TABLE london_customers AS (SELECT * FROM test_customers WHERE city = 'London');

-- Config tables.
CALL diffix.mark_personal('public', 'test_customers', 'id');
CALL diffix.mark_personal('public', 'test_purchases', 'cid');
CALL diffix.mark_personal('public', 'test_patients', 'id', 'name');
CALL diffix.mark_personal('public', 'empty_test_customers', 'id');
CALL diffix.mark_personal('public', 'london_customers', 'id');
CALL diffix.mark_public('public', 'test_products');
-- Config tables (and also check handling of namespaces).
CALL diffix.mark_personal('public.test_customers', 'id');
CALL diffix.mark_personal('public.test_purchases', 'cid');
CALL diffix.mark_personal('public.test_patients', 'id', 'name');
CALL diffix.mark_personal('public.empty_test_customers', 'id');
CALL diffix.mark_personal('public.london_customers', 'id');
CALL diffix.mark_public('public.test_products');

-- There is no CREATE USER IF NOT EXISTS, we need to wrap and silence the output
DO $$
Expand Down
12 changes: 6 additions & 6 deletions test/sql/led.sql
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ CREATE TABLE led_with_star_bucket AS TABLE led_with_victim;
INSERT INTO led_with_star_bucket VALUES
(22, 'biol', 'f', 'asst'), (23, 'chem', 'm', 'asst'), (24, 'biol', 'f', 'prof');

CALL diffix.mark_personal('public', 'led_base', 'id');
CALL diffix.mark_personal('public', 'led_with_victim', 'id');
CALL diffix.mark_personal('public', 'led_with_two_victims', 'id');
CALL diffix.mark_personal('public', 'led_with_three_cs_women', 'id');
CALL diffix.mark_personal('public', 'led_with_different_titles', 'id');
CALL diffix.mark_personal('public', 'led_with_star_bucket', 'id');
CALL diffix.mark_personal('led_base', 'id');
CALL diffix.mark_personal('led_with_victim', 'id');
CALL diffix.mark_personal('led_with_two_victims', 'id');
CALL diffix.mark_personal('led_with_three_cs_women', 'id');
CALL diffix.mark_personal('led_with_different_titles', 'id');
CALL diffix.mark_personal('led_with_star_bucket', 'id');

SET ROLE diffix_test;
SET pg_diffix.session_access_level = 'anonymized_trusted';
Expand Down
12 changes: 6 additions & 6 deletions test/sql/star_bucket.sql
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ INSERT INTO star_bucket_only VALUES
(4, 'cs', 'f', 'prof'),
(5, 'history', 'f', 'asst');

CALL diffix.mark_personal('public', 'star_bucket_base', 'id');
CALL diffix.mark_personal('public', 'star_bucket', 'id');
CALL diffix.mark_personal('public', 'star_bucket_suppressed_1', 'id');
CALL diffix.mark_personal('public', 'star_bucket_suppressed_2', 'id');
CALL diffix.mark_personal('public', 'star_bucket_empty', 'id');
CALL diffix.mark_personal('public', 'star_bucket_only', 'id');
CALL diffix.mark_personal('star_bucket_base', 'id');
CALL diffix.mark_personal('star_bucket', 'id');
CALL diffix.mark_personal('star_bucket_suppressed_1', 'id');
CALL diffix.mark_personal('star_bucket_suppressed_2', 'id');
CALL diffix.mark_personal('star_bucket_empty', 'id');
CALL diffix.mark_personal('star_bucket_only', 'id');

SET ROLE diffix_test;
SET pg_diffix.session_access_level = 'anonymized_trusted';
Expand Down
2 changes: 1 addition & 1 deletion test/sql/stress.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE test_stress AS (
FROM generate_series(1, 50000) series(i)
);

CALL diffix.mark_personal('public', 'test_stress', 'id');
CALL diffix.mark_personal('test_stress', 'id');

-- Prepare test session.
SET pg_diffix.noise_layer_sd = 0;
Expand Down
10 changes: 5 additions & 5 deletions test/sql/validation.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ CREATE TABLE test_validation (
last_seen TIMESTAMP
);

CALL diffix.mark_personal('public', 'test_validation', 'id');
CALL diffix.mark_personal('test_validation', 'id');

CREATE TABLE superclass (x INTEGER);
CREATE TABLE subclass (x INTEGER, y INTEGER);
INSERT INTO subclass VALUES (1, 2);

CALL diffix.mark_personal('public', 'superclass', 'x');
CALL diffix.mark_personal('public', 'subclass', 'y');
CALL diffix.mark_personal('superclass', 'x');
CALL diffix.mark_personal('subclass', 'y');

ALTER TABLE subclass INHERIT superclass;

-- No-op. Repeated to test the error on conflicting configuration
CALL diffix.mark_personal('public', 'superclass', 'x');
CALL diffix.mark_personal('public', 'subclass', 'y');
CALL diffix.mark_personal('superclass', 'x');
CALL diffix.mark_personal('subclass', 'y');

SET ROLE diffix_test;

Expand Down

0 comments on commit 73522b6

Please sign in to comment.