Preciso revogar os privilégios INSERT e UPDATE na coluna uid na tabela test.persons.
Aqui está o que eu fiz até agora:
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
Até agora tudo bem.
Mas quando tento executar a seguinte ATUALIZAÇÃO:
UPDATE test.persons SET uid = gen_random_uuid() WHERE name = 'John Doe';
Ele foi atualizado com sucesso, embora não devesse, pois revoguei os privilégios UPDATE na coluna uid.
O que estou fazendo errado e como devo revogar corretamente os privilégios UPDATE na coluna uid?
Você está no caminho certo, mas o PostgreSQL não suporta REVOKE em nível de coluna para INSERT/UPDATE . Revogar privilégios de coluna só funciona para SELECT .
Por que o UPDATE
uid
ainda está funcionando?Mesmo que você tenha revogado
UPDATE (uid)
, o PostgreSQL verifica UPDATE no nível da tabela , então sehasura
puder atualizar a tabela, ele poderá atualizar qualquer coluna.Solução: Use uma política de segurança em nível de linha (RLS)
Para impor essa restrição, você pode usar RLS :
Garante que
uid
não pode ser modificado durante uma atualização.MANEIRA alternativa: Use um gatilho BEFORE UPDATE
se alguém tentar atualizar
uid
, ocorrerá um erro .Solução alternativa adicionada para RLS específico
Política RLS para
UPDATE
(Preveniruid
Modificação)Para impedir que os usuários atualizem a
uid
coluna, você pode usar uma política RLS como esta:USING (true)
: Permite que o usuário tente uma atualização.WITH CHECK (uid = old.uid)
: Garanteuid
que permaneça o mesmo, evitando modificações.Política RLS para
INSERT
(Preveniruid
Inserção Manual)Para evitar que os usuários insiram manualmente um
uid
e apliquem o padrãogen_random_uuid()
, use:WITH CHECK (uid IS NULL)
: Os usuários só podem inserir se não especificarem umuid
.uid
tem umDEFAULT gen_random_uuid()
, o PostgreSQL irá gerá-lo automaticamente.Habilitar RLS
Resolução:
uid
, mas podem atualizar outras colunas.uid
, forçando o PostgreSQL a gerar um.REVOKE
revogará apenas privilégios que foram (implícita ou explicitamente) concedidos. Então a seguinte declaração não tem efeito:Como
hasura
já tem oUPDATE
privilégio na tabela, esse usuário tem o mesmo privilégio em todas as colunas.Então você primeiro tem que revogar o privilégio na tabela :
Então você concede o privilégio somente nas colunas permitidas :
Agora deve funcionar como você deseja.
INSERT
funciona da mesma forma.