Security Label Inheritance
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
Hi,
On February 25, 2025 10:08:44 AM GMT+01:00, Damien Clochard <damien@dalibo.info> wrote:
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 ?
Couldn't hurt.
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.
I doubt that is viable. That'd mean we somehow need to teach the label infrastructure about all kinds of inheritance *and* make that recursive label collection fast. The caching right now uses generic infrastructure, it certainly couldn't with inheritance support.That'd be a fair bit of infrastructure.
Greetings,
Andres
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Le 25.02.2025 10:34, Andres Freund a écrit :
Hi,
On February 25, 2025 10:08:44 AM GMT+01:00, Damien Clochard
<damien@dalibo.info> wrote: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 ?Couldn't hurt.
Please find attached a small change to documentation explaining that
security labels are not inherited.
Regards,
--
Damien Clochard
Attachments:
0001-doc-security-labels-are-not-inherited.patchtext/x-diff; name=0001-doc-security-labels-are-not-inherited.patchDownload
From b088c59030d139604bcf1125815818d1bc99726a Mon Sep 17 00:00:00 2001
From: damien clochard <damien@dalibo.com>
Date: Mon, 23 Jun 2025 15:04:02 +0200
Subject: [PATCH] doc: security labels are not inherited
---
doc/src/sgml/ref/security_label.sgml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/doc/src/sgml/ref/security_label.sgml b/doc/src/sgml/ref/security_label.sgml
index aa45c0af248..8562745648d 100644
--- a/doc/src/sgml/ref/security_label.sgml
+++ b/doc/src/sgml/ref/security_label.sgml
@@ -88,6 +88,14 @@ SECURITY LABEL [ FOR <replaceable class="parameter">provider</replaceable> ] ON
<para>
You must own the database object to use <command>SECURITY LABEL</command>.
</para>
+
+ <para>
+ Security labels are not inherited through object inheritance, meaning labels
+ applied to a parent object, like a table or a role, are not automatically passed
+ down to its child objects. Each database object has its own independent set of
+ security labels, requiring administrators to explicitly declare labels to each
+ individual object rather than relying on automatic inheritance.
+ </para>
</refsect1>
<refsect1>
--
2.34.1
On 23 Jun 2025, at 15:18, Damien Clochard <damien@dalibo.info> wrote:
Le 25.02.2025 10:34, Andres Freund a écrit :
Hi,
On February 25, 2025 10:08:44 AM GMT+01:00, Damien Clochard
<damien@dalibo.info> wrote: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 ?
Couldn't hurt.
Please find attached a small change to documentation explaining that security labels are not inherited.
Seems like a good improvement. The first sentence feels a bit long, but it's
no dealbreaker.
--
Daniel Gustafsson