Hi

My name's Damien Clochard and I'm the main developer of the PostgreSQL Anonymizer extension. This extension relies heavily on security labels. Among other things, users can add labels to define a "masking rule" upon a column and to declare that a roles is "masked".

More details on how this works on the documentation:
https://postgresql-anonymizer.readthedocs.io/en/latest/dynamic_masking/

Currently a security label is applied to one and only one object. In particular a label does not apply to the objects that inherit from the objet it is originally associated with.

Consider the following

ALTER DATABASE foo SET session_preload_libraries = 'anon';
ALTER DATABASE foo SET anon.transparent_dynamic_masking = TRUE;

CREATE TABLE people AS SELECT 5432 AS id, 'slonik' AS name;
CREATE EXTENSION anon;
SECURITY LABEL FOR anon ON COLUMN people.name IS 'MASKED WITH VALUE NULL';
CREATE ROLE extern INHERIT;
SECURITY LABEL FOR anon ON ROLE extern IS 'MASKED';
GRANT USAGE ON SCHEMA public TO extern;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO extern;
CREATE ROLE joe LOGIN IN ROLE extern;

When connecting as role joe, I will have all the privileges granted to extern. However, joe is not affected by the security label defined on the extern group. He can read the personal data.

\connect - joe

SELECT * FROM people;
  id  |  name
------+--------
 5432 | slonik

I need to explicitly change the role for the label to be applied and in that case the mask upon the people.name column is applied

SET ROLE extern;

SELECT * FROM people;
  id  | name
------+------
 5432 |

I am not suggesting that this behaviour should change but I receive a lot of feedback from users showing some confusion as they would expect that the INHERIT clause would also apply to security labels, just like granted privileges.

A similar confusion occurs with inherited tables :

\connect - postgres
CREATE TABLE french (eat_frogs BOOLEAN) INHERITS(people);
INSERT INTO french VALUES (0,'damien', FALSE);
GRANT SELECT ON TABLE french TO extern;

SET ROLE extern;

The mask is applied to the parent table

SELECT * FROM people;
  id  |  name
------+--------
 5432 |
    0 |

But it is not applied to the child table

SELECT * FROM french;
 id |  name  | eat_frogs
----+--------+-----------
  0 | damien | f

Again most users expect that the masking rule on people.name would also be applied to french.name.


So my first question is : Do you think it would be helpful to update the SECURITY LABEL command documentation to clarify that security labels are not concerned by object inheritance ?

My second question is more open : do you think it would be worth adding a new way to declare that a security label applies to an object and all its inheritants ? As I understand this would concern only roles and tables.

Maybe a new optional `[ [WITH] INHERIT | NOINHERIT ]` syntax at the end of the SECURITY LABEL command....

Something like this :

SECURITY LABEL FOR anon ON ROLE extern IS 'MASKED' WITH INHERIT;

SECURITY LABEL FOR anon ON COLUMN people.name
  IS 'MASKED WITH VALUE NULL'
  WITH INHERIT;

The default would be NOINHERIT and all extensions that rely on the current behaviour would continue to work without any change.

Let me know if I missed anything or if there's another way to achieve this kind of security label inheritance.

Regards,

--
Damien



Reply via email to