Security Label Inheritance - Mailing list pgsql-hackers

From Damien Clochard
Subject Security Label Inheritance
Date
Msg-id 3d9303b89d9f53e966b054ce094bccdb@dalibo.info
Whole thread Raw
Responses Re: Security Label Inheritance
List pgsql-hackers
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




pgsql-hackers by date:

Previous
From: John Naylor
Date:
Subject: Re: Improve CRC32C performance on SSE4.2
Next
From: Andres Freund
Date:
Subject: Re: Security Label Inheritance