set client_min_messages = warning; drop extension if exists pg_liquid cascade; reset client_min_messages; create extension pg_liquid; select count(*) as seed_edge_count from liquid.query($$ DefPred("name", "1", "liquid/node", "0", "liquid/string"). DefPred("owner", "1", "liquid/node", "0", "liquid/string"). DefPred("member_of", "1", "liquid/node", "0", "liquid/node"). DefPred("member", "1", "liquid/node", "0", "liquid/string"). DefCompound("Email", "user", "0", "liquid/string"). DefCompound("Email", "domain", "0", "liquid/string"). Edge("Email", "liquid/mutable", "false"). Edge("name", "liquid/readable_if_subject_has", "owner"). Edge("member_of", "liquid/readable_if_object_has", "member"). Edge("Email", "liquid/readable_compound_if_role_has", "user"). Edge("person:alice", "owner", "liquid_alice"). Edge("person:alice", "name", "Alice Example"). Edge("person:bob", "name", "Bob Example"). Edge("person:alice", "member_of", "org:acme"). Edge("org:acme", "member", "liquid_bob"). Email@(user="liquid_alice", domain="example.com"). ReadTriple@(principal="liquid_charlie", user="liquid_charlie", subject="person:bob", predicate="name", object="Bob Example"). Edge(subject_literal, predicate_literal, object_literal)? $$) as t(subject_literal text, predicate_literal text, object_literal text) where predicate_literal in ('name', 'member_of'); seed_edge_count ----------------- 3 (1 row) set pg_liquid.policy_principal = 'liquid_alice'; select subject_literal, object_literal from liquid.query($$ Edge(subject_literal, "name", object_literal)? $$) as t(subject_literal text, object_literal text) order by 1, 2; subject_literal | object_literal -----------------+---------------- person:alice | Alice Example (1 row) select cid, account_user, domain from liquid.query($$ Email@(cid=cid, user=account_user, domain=domain)? $$) as t(cid text, account_user text, domain text); cid | account_user | domain ---------------------------------------------------+--------------+------------- Email@(domain='example.com', user='liquid_alice') | liquid_alice | example.com (1 row) select count(*) as hidden_email_role_edges from liquid.query($$ Edge(subject_literal, "user", object_literal)? $$) as t(subject_literal text, object_literal text); hidden_email_role_edges ------------------------- 0 (1 row) reset pg_liquid.policy_principal; drop role if exists liquid_reader; NOTICE: role "liquid_reader" does not exist, skipping create role liquid_reader; revoke all on schema liquid from public; revoke all on all tables in schema liquid from public; revoke all on all functions in schema liquid from public; grant usage on schema liquid to liquid_reader; grant execute on function liquid.read_as(text, text) to liquid_reader; select has_table_privilege('liquid_reader', 'liquid.edges', 'select') as reader_has_edge_select; reader_has_edge_select ------------------------ f (1 row) select has_function_privilege('liquid_reader', 'liquid.read_as(text, text)', 'execute') as reader_has_read_as_execute; reader_has_read_as_execute ---------------------------- t (1 row) select has_function_privilege('liquid_reader', 'liquid.query_as(text, text)', 'execute') as reader_has_query_as_execute; reader_has_query_as_execute ----------------------------- f (1 row) set role liquid_reader; select subject_literal, object_literal from liquid.read_as('liquid_alice', $$ Edge(subject_literal, "name", object_literal)? $$) as t(subject_literal text, object_literal text) order by 1, 2; subject_literal | object_literal -----------------+---------------- person:alice | Alice Example (1 row) do $$ begin perform count(*) from liquid.read_as('liquid_alice', $liquid$ Edge("person:eve", "name", "Eve Example"). Edge(subject_literal, "name", object_literal)? $liquid$) as t(subject_literal text, object_literal text); exception when insufficient_privilege then raise notice 'read_as_rejected_assertions'; end $$; NOTICE: read_as_rejected_assertions reset role; drop owned by liquid_reader; drop role liquid_reader; set pg_liquid.policy_principal = 'liquid_bob'; select subject_literal, object_literal from liquid.query($$ Edge(subject_literal, "member_of", object_literal)? $$) as t(subject_literal text, object_literal text) order by 1, 2; subject_literal | object_literal -----------------+---------------- person:alice | org:acme (1 row) select count(*) as bob_visible_names from liquid.query($$ Edge(subject_literal, "name", object_literal)? $$) as t(subject_literal text, object_literal text); bob_visible_names ------------------- 0 (1 row) reset pg_liquid.policy_principal; set pg_liquid.policy_principal = 'liquid_charlie'; select subject_literal, object_literal from liquid.query($$ Edge(subject_literal, "name", object_literal)? $$) as t(subject_literal text, object_literal text) order by 1, 2; subject_literal | object_literal -----------------+---------------- person:bob | Bob Example (1 row) reset pg_liquid.policy_principal;