Conceda tudo em um esquema específico no banco de dados para uma função de grupo no PostgreSQL

91

Usando o PostgreSQL 9.0, tenho uma função de grupo chamada "equipe" e gostaria de conceder todos (ou certos) privilégios a esta função em tabelas em um esquema específico. Nenhum dos trabalhos a seguir

GRANT ALL ON SCHEMA foo TO staff;
GRANT ALL ON DATABASE mydb TO staff;

Membros da "equipe" ainda são incapazes de SELECIONAR ou ATUALIZAR nas tabelas individuais no esquema "foo" ou (no caso do segundo comando) em qualquer tabela no banco de dados, a menos que eu conceda tudo naquela tabela específica.

O que posso fazer para facilitar a minha vida e a de meus usuários?

Atualização: descobri com a ajuda de uma pergunta semelhante em serverfault.com .

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA foo TO staff;
punk
fonte

Respostas:

120

Você encontrou o atalho para definir privilégios para todas as tabelas existentes no esquema fornecido. O manual esclarece :

(mas observe que isso ALL TABLESinclui visualizações e tabelas estrangeiras ).

Ênfase em negrito minha. serialcolunas são implementadas com nextval()uma sequência como padrão de coluna e, citando o manual :

Para sequências, este privilégio permite o uso das funções currvale nextval.

Então, se houver serialcolunas, você também vai querer conceder USAGE(ou ALL PRIVILEGES) em sequências

GRANT USAGE ON ALL SEQUENCES IN SCHEMA foo TO mygrp;

Nota: as colunas de identidade no Postgres 10 ou posterior usam sequências implícitas que não requerem privilégios adicionais. (Considere atualizar as serialcolunas.)

E quanto a novos objetos?

Você também terá interesse em DEFAULT PRIVILEGESpara usuários ou esquemas :

ALTER DEFAULT PRIVILEGES IN SCHEMA foo GRANT ALL PRIVILEGES ON TABLES TO staff;
ALTER DEFAULT PRIVILEGES IN SCHEMA foo GRANT USAGE          ON SEQUENCES TO staff;
ALTER DEFAULT PRIVILEGES IN SCHEMA foo REVOKE ...;

Isso define privilégios para objetos criados no futuro automaticamente - mas não para objetos pré-existentes.

Os privilégios padrão são aplicados apenas a objetos criados pelo usuário de destino ( FOR ROLE my_creating_role). Se essa cláusula for omitida, o padrão é o usuário atual em execução ALTER DEFAULT PRIVILEGES. Para ser explícito:

ALTER DEFAULT PRIVILEGES FOR ROLE my_creating_role IN SCHEMA foo GRANT ...;
ALTER DEFAULT PRIVILEGES FOR ROLE my_creating_role IN SCHEMA foo REVOKE ...;

Observe também que todas as versões do pgAdmin III têm um bug sutil e exibem privilégios padrão no painel SQL, mesmo se eles não se aplicarem à função atual. Certifique-se de ajustar a FOR ROLEcláusula manualmente ao copiar o script SQL.

Erwin Brandstetter
fonte
2
Só para você conhecer Erwin, 10 minutos depois de postar seu conselho, eu precisava dele. É como se você soubesse o que eu ia fazer ... criar uma nova mesa e descobrir que ela não tinha os privs certos. Sua resposta veio em seu socorro.
punk de
5
@punkish: Eu exijo meu distintivo de precog! Droga, isso já é usado para outra coisa.
Erwin Brandstetter
Ao executar ALTER DEFAULT PRIVILEGES IN SCHEMA foo GRANT ALL PRIVILEGES ON TABLES TO staff;como ele sabe qual banco de dados? SCHEMA foopode existir em banco de dados diferente?
J86,
2
@ J86: aplica-se apenas ao banco de dados atual - onde o comando é executado.
Erwin Brandstetter
1
@ErwinBrandstetter Posso conceder acesso para tabelas / sequências futuras ao app_user (leitura-gravação), desde que as tabelas sejam criadas por outro migration_user dedicado automaticamente (as migrações flyway são executadas na inicialização do aplicativo)?
Lexeme
43

Minha resposta é semelhante a esta em ServerFault.com .

Para ser conservador

Se você quiser ser mais conservador do que conceder "todos os privilégios", pode tentar algo mais parecido com isso.

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO some_user_;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO some_user_;

O uso de publiclá se refere ao nome do esquema padrão criado para cada novo banco de dados / catálogo. Substitua pelo seu próprio nome se você criou um esquema.

Acesso ao Esquema

Para acessar um esquema, para qualquer ação, o usuário deve receber direitos de "uso". Antes que um usuário possa selecionar, inserir, atualizar ou excluir, ele deve primeiro ter o "uso" concedido a um esquema.

Você não perceberá este requisito ao usar o Postgres pela primeira vez. Por padrão, cada banco de dados possui um primeiro esquema denominado public. E cada usuário, por padrão, recebeu automaticamente direitos de "uso" para esse esquema específico. Ao adicionar um esquema adicional, você deve conceder direitos de uso explicitamente.

GRANT USAGE ON SCHEMA some_schema_ TO some_user_ ;

Trecho do documento Postgres :

Para esquemas, permite o acesso a objetos contidos no esquema especificado (assumindo que os próprios requisitos de privilégio dos objetos também sejam atendidos). Essencialmente, isso permite que o donatário "procure" objetos dentro do esquema. Sem essa permissão, ainda é possível ver os nomes dos objetos, por exemplo, consultando as tabelas do sistema. Além disso, depois de revogar essa permissão, os back-ends existentes podem ter instruções que já executaram essa pesquisa, portanto, essa não é uma maneira totalmente segura de impedir o acesso ao objeto.

Para obter mais discussão, consulte a pergunta, o que exatamente o uso de concessão no esquema faz? . Preste atenção especial à resposta do especialista em Postgres Craig Ringer .

Objetos Existentes Versus Futuro

Esses comandos afetam apenas objetos existentes. As tabelas e outras que você criar no futuro terão privilégios padrão até que você execute novamente as linhas acima. Veja a outra resposta de Erwin Brandstetter para alterar os padrões que afetam os objetos futuros.

Basil Bourque
fonte
1
além das duas concessões acima, precisa de mais uma concessão: CONCESSÃO DE USO NO ESQUEMA público PARA algum_usuário_;
Ning Liu
1
@NingLiu Muito obrigado por apontar GRANT USAGE e por me ensinar isso. Eu adicionei uma seção à Resposta.
Basil Bourque
GRANT USAGE ON SCHEMA é o que eu estava procurando.
Basil Musa