postgresqldatabase-permissions

How to Revoke INSERT, UPDATE privileges on a specific column?


I need to revoke INSERT and UPDATE privileges on the uid column in the test.persons table.

Here's what I have done so far:

CREATE TABLE test.persons (
    uid UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    name VARCHAR(255),
    description TEXT
);

REVOKE INSERT (uid) ON test.persons FROM hasura;
GRANT INSERT (name, description) ON test.persons TO hasura;
REVOKE UPDATE (uid) ON test.persons FROM hasura;
GRANT UPDATE (name, description) ON test.persons TO hasura;


INSERT INTO test.persons (uid, name, description) 
VALUES ('e7443661-f6c3-4448-8df7-c65e3f8243ca', 'John Doe', 'Some description');
//correct: ERROR: permission denied for table persons

INSERT INTO test.persons (uid) 
VALUES (gen_random_uuid());
//correct: ERROR: permission denied for table persons

INSERT INTO test.persons (name, description) 
VALUES ('John Doe', 'Some description');
//correct: Successfully inserted

INSERT INTO test.persons (name) 
VALUES ('John Doe1');
//correct: Successfully inserted

So far so good.

But when I try to perform the following UPDATE:

UPDATE test.persons SET uid = gen_random_uuid() WHERE name = 'John Doe';

It successfully updated, although it shouldn't, as I revoked the UPDATE privileges on the uid column.

What am I doing wrong and how should I correctly revoke the UPDATE privileges on the uid column?


Solution

  • REVOKE will only revoke privileges that were (implicitly or explicitly) granted. So the following statement has no effect:

    REVOKE UPDATE (uid) ON test.persons FROM hasura;
    

    Since hasura already has the UPDATE privilege on the table, that user has the same privilege on all columns.

    So you first have to revoke the privilege on the table:

    REVOKE UPDATE ON test.persons FROM hasura;
    

    Then you grant the privilege only on the allowed columns:

    GRANT UPDATE (name, description) ON test.persons TO hasura;
    

    Now it should work like you desire. INSERT works just the same.