Não há "privilégio em
SELECT
". Tudo que você precisa é o privilégio de EXECUTAR
funções. A função relevante pode ser executada com SECURITY DEFINIDO
herdar todos os privilégios do proprietário. Para restringir o possível escalonamento de privilégios ao mínimo a priori, faça com que uma função de daemon possua funções relevantes apenas com os privilégios necessários - não um superusuário! Receita
Como superusuário...
Crie uma função de não superusuário
myuser
. CREATE ROLE myuser PASSWORD ...;
Crie uma função de grupo
mygroup
e faça meuusuário
membro nele. CREATE ROLE mygroup;
GRANT mygroup TO myuser;
Você pode querer adicionar mais usuários como
myuser
mais tarde. não conceda nenhum privilégio para
meuusuário
.Conceda-os apenas a
mygroup
:GRANT CONNECT ON DATABASE mydb TO mygroup;
GRANT USUSE ON SCHEMA public TO mygroup;
GRANT EXECUTE ON FUNCTION foo() PARA mygroup;
Remover todos privilégios para
public
que meuusuário
não deveria. REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;
Pode haver mais. Cito o manual:
Crie uma função de daemon para possuir funções relevantes.
CREATE ROLE mydaemon;
Conceda apenas os privilégios necessários para executar essas funções para
mydaemon
, (incluindo EXECUTAR NA FUNÇÃO
para permitir que outra função seja chamada). Novamente, você pode usar funções de grupo para agrupar privilégios e concedê-los a mydaemon
GRANT bundle1 TO mydaemon;
Além disso, você pode usar
DEFAULT PRIVILEGES
para conceder automaticamente certos privilégios para objetos futuros a um pacote ou ao daemon diretamente:ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE ON SEQUENCES TO bundle1;
Isso se aplica apenas à função para a qual é executado. De acordo com a documentação:
Para também abranger objetos pré-existentes no esquema (consulte comentário de rob ):
GRANT SELECT ON ALL TABLES IN SCHEMA public TO bundle1;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bundle1;
Faça
mydaemon
próprias funções relevantes. Poderia ficar assim:CREATE OR REPLACE FUNCTION foo()
...
SECURITY DEFINER SET search_path = myschema, pg_temp;
ALTER FUNCTION foo() OWNER TO mydaemon;
REVOKE EXECUTE ON FUNCTION foo() FROM public;
GRANT EXECUTE ON FUNCTION foo() TO mydaemon;
GRANT EXECUTE ON FUNCTION foo() TO mygroup;
-- possibly others ..
Devido a este bug na versão atual 1.16.1 do pgAdmin o comando necessário
REVOKE EXECUTE ON FUNCTION foo() FROM public;
está faltando no script DDL de engenharia reversa. Lembre-se de adicioná-lo, ao recriar.
Este bug foi corrigido na versão atual pgAdmin 1.18.1.