CREATE POLICY

CREATE POLICY — define uma nova política de segurança no nível de linha para uma tabela

Sinopse

CREATE POLICY nome ON nome_da_tabela
    [ AS { PERMISSIVE | RESTRICTIVE } ]
    [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
    [ TO { nome_da_role | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
    [, ...] ]
    [ USING ( expressão_USING ) ]
    [ WITH CHECK ( expressão_CHECK ) ]

Descrição

O comando CREATE POLICY define uma nova política de segurança no nível de linha para uma tabela. Note que a segurança no nível de linha deve ser ativada na tabela (usando ALTER TABLE ... ENABLE ROW LEVEL SECURITY) para que as políticas criadas sejam aplicadas.

Uma política concede permissão para selecionar, inserir, atualizar ou excluir linhas que correspondam à expressão de política relevante. As linhas existentes da tabela são verificadas em relação à expressão especificada em USING, enquanto as novas linhas a serem criadas via INSERT ou UPDATE são verificadas em relação à expressão especificada em WITH CHECK. Quando a expressão USING retorna verdade para uma determinada linha, esta linha fica visível para o usuário, enquanto se retornar falso ou nulo, a linha não ficará visível. Quando uma expressão WITH CHECK retorna verdade para uma linha, esta linha é inserida ou atualizada, enquanto se retornar falso ou nulo, ocorrerá um erro.

Para os comandos INSERT, UPDATE e MERGE as expressões WITH CHECK são aplicadas depois que os gatilhos BEFORE são disparados, e antes que quaisquer modificações de dados reais sejam feitas. Assim, um gatilho BEFORE ROW pode modificar os dados a serem inseridos, afetando o resultado da verificação da política de segurança. As expressões WITH CHECK são impostas antes de qualquer outra restrição.

Os nomes das políticas são por tabela. Portanto, o mesmo nome de política pode ser usado para muitas tabelas diferentes, e ter uma definição apropriada para cada tabela.

As políticas podem ser aplicadas para comandos específicos ou para funções de banco de dados (identificadores de autorização/roles) específicas. O padrão para políticas recém-criadas é que as mesmas se aplicam a todos os comandos e funções de banco de dados, a menos que seja especificado de outra forma. Podem ser aplicadas várias políticas a um único comando; veja abaixo para obter mais detalhes. A Tabela 300 resume como os diferentes tipos de política se aplicam a comandos específicos.

Para as políticas que podem ter as duas expressões USING e WITH CHECK (ALL e UPDATE), se não for definida nenhuma expressão WITH CHECK, então a expressão USING será usada para determinar quais linhas são visíveis (modo USING normal), e quais novas linhas poderão ser adicionadas (modo WITH CHECK).

Se a segurança no nível de linha estiver ativada para uma tabela, mas não existir nenhuma política aplicável, será assumida a política de negação padrão, para que nenhuma linha fique visível ou atualizável.

Parâmetros

nome

O nome da política a ser criada. Deve ser diferente do nome de qualquer outra política para a tabela.

nome_da_tabela

O nome (opcionalmente qualificado pelo esquema) da tabela à qual a política se aplica.

PERMISSIVE

Especifica que a política deve ser criada como uma política permissiva. Todas as políticas permissivas aplicáveis ​​a uma determinada consulta são combinadas usando o operador booleano OR. Ao criar políticas permissivas, os administradores podem ampliar o conjunto de registros que podem ser acessados. As políticas são permissivas por padrão.

RESTRICTIVE

Especifica que a política deve ser criada como uma política restritiva. Todas as políticas restritivas aplicáveis ​​a uma determinada consulta serão combinadas usando o operador booleano AND. Ao criar políticas restritivas, os administradores podem reduzir o conjunto de registros que podem ser acessados, porque todas as políticas restritivas devem ser aprovadas para cada registro.

Note que deve haver pelo menos uma política permissiva para conceder acesso aos registros antes que as políticas restritivas possam ser usadas de forma útil para reduzir este acesso. Se existirem apenas políticas restritivas, nenhum registro estará acessível. Quando há uma mistura de políticas permissivas e restritivas, o registro só será acessível se pelo menos uma das políticas permissivas for aprovada, além de todas as políticas restritivas.

comando

O comando ao qual a política se aplica. As opções válidas são ALL, SELECT, INSERT, UPDATE, e DELETE. ALL é o padrão. Veja abaixo os detalhes sobre como são aplicadas.

nome_da_role

As funções de banco de dados (roles) às quais a política deve ser aplicada. O padrão é PUBLIC, que aplicará a política a todas as funções de banco de dados.

expressão_USING

Qualquer expressão SQL condicional (retornando boolean). A expressão condicional não pode conter nenhuma função de agregação ou de janela. Esta expressão será adicionada às consultas que se referem à tabela, se a segurança no nível de linha estiver ativada. As linhas para as quais a expressão retorna verdade ficarão visíveis. Quaisquer linhas para as quais a expressão retorne falso ou nulo não serão visíveis para o usuário (no SELECT), e não estarão disponível para modificação (no UPDATE ou DELETE). Estas linhas são suprimidas silenciosamente; nenhum erro é relatado.

expressão_CHECK

Qualquer expressão SQL condicional (retornando boolean). A expressão condicional não pode conter nenhuma função de agregação ou de janela. Esta expressão será usada em consultas INSERT e UPDATE na tabela, se a segurança no nível de linha estiver ativada. Somente as linhas para as quais a expressão é avaliada como verdade serão permitidas. Será relatado um erro se a expressão for avaliada como falso ou nulo para qualquer um dos registros inseridos, ou qualquer um dos registros resultantes da atualização. Note que a expressão_CHECK é avaliada em relação ao novo conteúdo proposto para a linha, e não ao conteúdo original.

Políticas por-comando

ALL #

Usar ALL para uma política significa que esta será aplicada a todos os comandos, independentemente do tipo de comando. Se existir uma política ALL e políticas mais específicas, tanto a política ALL quanto a política (ou políticas) mais específica serão aplicadas. Além disso, as políticas ALL serão aplicadas tanto no lado da seleção de uma consulta, quanto no lado da modificação, usando a expressão USING para os dois casos se apenas a expressão USING tiver sido definida.

Como exemplo, se for executado um UPDATE, então a política ALL será aplicável tanto nas linhas que o comando UPDATE poderá selecionar para serem atualizadas (aplicando a expressão USING), quanto nas linhas atualizadas resultantes, para verificar se estas podem ser adicionadas à tabela (caso contrário, aplicando a expressão WITH CHECK, se definida, e a expressão USING). Se o comando INSERT ou UPDATE tentar adicionar linhas à tabela que não passam pela expressão WITH CHECK da política ALL, todo o comando será interrompido.

SELECT #

Usar SELECT para uma política significa que ela será aplicada a consultas SELECT, e sempre que as permissões SELECT forem necessárias na relação para a qual a política foi definida. O resultado é que apenas os registros da relação que passam pela política SELECT serão retornados durante uma consulta SELECT, e que os comandos que exigem permissões SELECT, como UPDATE, também verão apenas os registros permitidos pela política SELECT. Uma política SELECT não pode ter uma expressão WITH CHECK, porque ela só se aplica nos casos em que os registros estão sendo obtidos da relação.

INSERT #

Para uma política, usar INSERT significa que ela será aplicada aos comandos INSERT e MERGE contendo ações INSERT. As linhas inseridas que não forem aprovadas por esta política resultarão em erro de violação de política, e todo o comando INSERT será interrompido. Uma política INSERT não pode ter uma expressão USING, porque ela só se aplica nos casos em que registros estão sendo adicionados à relação.

Note que INSERT com a cláusula ON CONFLICT DO UPDATE verifica as expressões WITH CHECK das políticas INSERT apenas para as linhas adicionadas à relação pelo caminho INSERT.

UPDATE #

Usar UPDATE para uma política significa que esta se aplicará aos comandos UPDATE, SELECT FOR UPDATE e SELECT FOR SHARE, assim bem como cláusulas auxiliares ON CONFLICT DO UPDATE de comandos INSERT. Os comandos MERGE contendo ações UPDATE também são afetados. Uma vez que o comando UPDATE envolve extrair um registro existente e substituí-lo por um novo registro modificado, as políticas UPDATE aceitam uma expressão USING e uma expressão WITH CHECK. A expressão USING determina quais registros o comando UPDATE terá acesso para operar, enquanto a expressão WITH CHECK define quais linhas modificadas poderão ser armazenadas de volta na relação.

Qualquer linha cujos valores atualizados não sejam aprovados pela expressão WITH CHECK causará um erro, e todo o comando será interrompido. Se for especificada apenas a cláusula USING, então esta cláusula será usada para os casos USING e WITH CHECK.

Normalmente, um comando UPDATE também precisa ler dados de colunas na relação que está sendo atualizada (por exemplo, em uma cláusula WHERE ou uma cláusula RETURNING, ou em uma expressão no lado direito da cláusula SET). Neste caso, os direitos para SELECT também são necessários na relação que está sendo atualizada, e as políticas SELECT ou ALL apropriadas serão aplicadas além das políticas UPDATE. Assim, o usuário deve ter acesso à(s) linha(s) sendo atualizada(s) por meio de uma política SELECT ou ALL, além de receber permissão para atualizar a(s) linha(s) por meio de uma política UPDATE ou ALL.

Quando o comando INSERT tem uma cláusula auxiliar ON CONFLICT DO UPDATE, se for usado o caminho UPDATE, a linha a ser atualizada é primeiro verificada em relação às expressões USING de qualquer política UPDATE e, em seguida, a nova linha atualizada é verificada em relação às expressões WITH CHECK. Note, no entanto, que, ao contrário de um comando UPDATE autônomo, se a linha existente não for aprovada pelas expressões USING, será relatado um erro (o caminho UPDATE nunca será evitado silenciosamente).

DELETE #

Usar DELETE para uma política significa que esta será aplicada aos comandos DELETE. Apenas as linhas que forem aprovadas por esta política serão vistas por um comando DELETE. Pode haver linhas visíveis por meio do SELECT que não estarão disponíveis para exclusão, se as mesmas não forem aprovadas pela expressão USING da política DELETE.

Geralmente, o comando DELETE também precisa ler dados de colunas na relação que está excluindo (por exemplo, em uma cláusula WHERE ou uma cláusula RETURNING). Neste caso, também são necessários os direitos SELECT na relação, e as políticas SELECT ou ALL apropriadas serão aplicadas além das políticas DELETE. Assim, o usuário deve ter acesso à(s) linha(s) que está(ão) sendo excluída(s) por meio de uma política SELECT ou ALL, além de receber permissão para excluir a(s) linha(s) por meio de uma política DELETE ou ALL.

A política DELETE não pode ter uma expressão WITH CHECK, porque ela só se aplica nos casos em que os registros estão sendo excluídos da relação, de modo que não há nenhuma nova linha a ser verificada.

Tabela 300. Políticas aplicadas por tipo de comando

ComandoSELECT/ALL políticaINSERT/ALL políticaUPDATE/ALL políticaDELETE/ALL política
USING expressãoWITH CHECK expressãoUSING expressãoWITH CHECK expressãoUSING expressão
SELECTLinha existente
SELECT FOR UPDATE/SHARELinha existenteLinha existente
INSERT / MERGE ... THEN INSERTNova linha
INSERT ... RETURNING Nova linha [a] Nova linha
UPDATE / MERGE ... THEN UPDATE Existente & novas linhas [a] Linha existenteNova linha
DELETE Linha existente [a] Linha existente
ON CONFLICT DO UPDATEExistente & novas linhasLinha existenteNova linha

[a] Se for necessário o acesso de leitura para a linha existente ou nova (por exemplo, uma cláusula WHERE ou RETURNING que se refere a colunas da relação).


Aplicação de várias políticas

Quando várias políticas de diferentes tipos de comando se aplicam ao mesmo comando (por exemplo, políticas SELECT e UPDATE aplicadas a um comando UPDATE), então o usuário deverá ter os dois tipos de permissão (por exemplo, permissão para selecionar linhas da relação, bem como permissão para atualizá-las). Assim, as expressões para um tipo de política são combinadas com as expressões para o outro tipo de política usando o operador AND.

Quando várias políticas do mesmo tipo de comando se aplicam ao mesmo comando, deve haver pelo menos uma política PERMISSIVE concedendo acesso à relação, e todas as políticas RESTRICTIVE devem ser aprovadas. Assim, todas as expressões de política PERMISSIVE são combinadas usando OR, todas as expressões de política RESTRICTIVE são combinadas usando AND, e os resultados são combinados usando AND. Se não houver políticas PERMISSIVE, o acesso será negado.

Note que, para fins de combinação de várias políticas, as políticas ALL são tratadas como tendo o mesmo tipo de qualquer outro tipo de política que esteja sendo aplicada.

Por exemplo, em um comando UPDATE que requer as permissões SELECT e UPDATE, se houver várias políticas aplicáveis ​​de cada tipo, estas serão combinadas como mostrado a seguir:

expressão from RESTRICTIVE SELECT/ALL política 1
AND
expressão from RESTRICTIVE SELECT/ALL política 2
AND
...
AND
(
  expressão from PERMISSIVE SELECT/ALL política 1
  OR
  expressão from PERMISSIVE SELECT/ALL política 2
  OR
  ...
)
AND
expressão from RESTRICTIVE UPDATE/ALL política 1
AND
expressão from RESTRICTIVE UPDATE/ALL política 2
AND
...
AND
(
  expressão from PERMISSIVE UPDATE/ALL política 1
  OR
  expressão from PERMISSIVE UPDATE/ALL política 2
  OR
  ...
)

Notas

É necessário ser o dono da tabela para criar ou alterar políticas para ela.

Embora as políticas sejam aplicadas para consultas explícitas em tabelas no banco de dados, elas não são aplicadas quando o sistema está executando verificações internas de integridade referencial ou validando restrições. Isto significa que existem maneiras indiretas de determinar a existência de um determinado valor. Um exemplo disso é tentar inserir um valor duplicado em uma coluna que é chave primária, ou possui restrição de unicidade. Se a inserção falhar, o usuário poderá inferir que o valor já existe. (Este exemplo assume que o usuário tem permissão pela política para inserir registros que ele não tem permissão para ver.) Outro exemplo é quando um usuário tem permissão para inserir linhas em uma tabela que faz referência a outra tabela que, de outra forma, seria uma tabela oculta. A existência pode ser determinada pelo usuário inserindo valores na tabela que faz a referência, onde o sucesso indicaria que o valor existe na tabela referenciada. Estes problemas podem ser resolvidos com a criação cuidadosa de políticas para impedir que os usuários possam inserir, excluir ou atualizar registros que poderiam indicar um valor que eles não poderiam ver, ou usando valores gerados (por exemplo, chaves alternativas) em vez de chaves com significado externo.

Geralmente, o sistema aplicará as condições de filtro impostas usando políticas de segurança antes das qualificações que aparecem nas consultas do usuário, a fim de evitar a exposição inadvertida de dados protegidos a funções definidas pelo usuário que podem não ser confiáveis. No entanto, funções e operadores marcados pelo sistema (ou pelo administrador do sistema) como LEAKPROOF podem ser avaliadas antes das expressões de política, porque são consideradas confiáveis.

Como as expressões de política são adicionadas diretamente à consulta do usuário, estas serão executadas com os direitos do usuário que está executando a consulta geral. Portanto, os usuários que estão usando uma determinada política devem ser capazes de acessar quaisquer tabelas ou funções referenciadas na expressão, ou simplesmente receberão um erro de permissão negada ao tentar consultar a tabela com segurança no nível de linha ativada. No entanto, isto não muda como as visões funcionam. Assim como nas consultas e visões normais, as verificações de permissão e as políticas para as tabelas referenciadas por uma visão usarão os direitos do dono da visão, e quaisquer políticas que se apliquem ao dono da visão, exceto se a visão for definida usando a opção security_invoker (veja CREATE VIEW).

Não existe uma política separada para MERGE. Em vez disso, as políticas definidas para SELECT, INSERT, UPDATE e DELETE são aplicadas durante a execução do comando MERGE, dependendo das ações que forem realizadas.

Uma discussão adicional e exemplos práticos podem ser encontrados na Políticas de segurança de linha.

Conformidade

O comando CREATE POLICY é uma extensão do PostgreSQL.

Veja também

ALTER POLICY, DROP POLICY, ALTER TABLE