Security Label Inheritance

From: Damien Clochard <damien(at)dalibo(dot)info>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Security Label Inheritance
Date: 2025-02-25 09:08:44
Message-ID: 3d9303b89d9f53e966b054ce094bccdb@dalibo.info
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2025-02-25 09:34:16 Re: Security Label Inheritance
Previous Message John Naylor 2025-02-25 09:07:16 Re: Improve CRC32C performance on SSE4.2