Usar a compatibilidade com extensões delegadas do Amazon RDS para PostgreSQL
Usando a compatibilidade com extensões delegadas do PostgreSQL, é possível delegar o gerenciamento de extensões a um usuário que não precise ser um rds_superuser
. Com esse suporte de extensão delegado, um novo perfil chamado rds_extension
é criado, e você deve atribuí-lo a um usuário para gerenciar outras extensões. Esse perfil pode criar, atualizar e eliminar extensões.
É possível especificar quais extensões podem ser instaladas na instância de banco de dados do RDS listando-as no parâmetro rds.allowed_extensions
. Para obter mais informações, consulte Usar extensões PostgreSQL com o Amazon RDS para PostgreSQL.
É possível restringir a lista de extensões disponíveis que podem ser gerenciadas pelo usuário com o perfil rds_extension
usando o parâmetro rds.allowed_delegated_extensions
.
O suporte de extensão delegado está disponível nas seguintes versões:
-
Todas as versões posteriores
-
16.4 e versões 16 posteriores
-
15.8 e versões 15 posteriores
-
14.13 e versões 14 posteriores
-
13.16 e versões 13 posteriores
-
12.20 e versões 12 posteriores
Tópicos
- Ativar o suporte de extensão delegado a um usuário
- Configuração usada na compatibilidade com extensões delegadas do PostgreSQL
- Desativar o suporte para a extensão delegada
- Benefícios de usar a compatibilidade com extensões delegadas do Amazon RDS
- Limitação da compatibilidade com extensões delegadas do PostgreSQL
- Permissões necessárias para determinadas extensões
- Considerações sobre segurança
- Descartar cascata de extensão desabilitado
- Exemplos de extensões que podem ser adicionadas usando o suporte de extensão delegado
Ativar o suporte de extensão delegado a um usuário
É necessário executar o seguinte para habilitar o suporte de extensão delegado a um usuário:
-
Conceder o perfil
rds_extension
a um usuário: conecte-se ao banco de dadosrds_superuser
e execute o seguinte comando:Postgres => grant rds_extension to
user_name
; -
Definir a lista de extensões disponíveis para usuários delegados gerenciarem: o
rds.allowed_delegated_extensions
permite que você especifique um subconjunto das extensões disponíveis usando o parâmetro de cluster de banco de dadosrds.allowed_extensions
. É possível fazer isso em um dos seguintes níveis:-
No cluster ou no grupo de parâmetros da instância, por meio do AWS Management Console ou da API. Para ter mais informações, consulte Grupos de parâmetros para Amazon RDS.
-
Use o seguinte comando em nível de banco de dados:
alter database
database_name
set rds.allowed_delegated_extensions = 'extension_name_1
,extension_name_2
,...extension_name_n
'; -
Use o seguinte comando em nível de usuário:
alter user
user_name
set rds.allowed_delegated_extensions = 'extension_name_1
,extension_name_2
,...extension_name_n
';
nota
Não é necessário reiniciar o banco de dados depois de alterar o parâmetro dinâmico
rds.allowed_delegated_extensions
. -
-
Permitir que o usuário delegado acesse os objetos criados durante o processo de criação da extensão: determinadas extensões criam objetos que exigem que permissões adicionais sejam concedidas para que o usuário com o perfil
rds_extension
possa acessá-los. Ords_superuser
deve conceder ao usuário delegado acesso a esses objetos. Uma das opções é usar um gatilho de eventos para conceder permissão automaticamente ao usuário delegado. Para ter mais informações, consulte o exemplo do gatilho de eventos em Desativar o suporte para a extensão delegada.
Configuração usada na compatibilidade com extensões delegadas do PostgreSQL
Nome da configuração | Descrição | Valor padrão | Observações | Quem pode modificar ou conceder permissão |
---|---|---|---|---|
|
Esse parâmetro limita as extensões que um perfil rds_extension pode gerenciar em um banco de dados. Ele deve ser um subconjunto de rds.allowed_extensions. |
string vazia |
Para saber mais sobre como configurar esse parâmetro, consulte Ativar o suporte de extensão delegado a um usuário. |
rds_superuser |
|
Esse parâmetro permite que o cliente limite as extensões que podem ser instaladas na instância de banco de dados do RDS. Para ter mais informações, consulte Restringir a instalação de extensões do PostgreSQL. |
"*" |
Por padrão, esse parâmetro é definido como “*”, o que significa que todas as extensões aceitas no RDS para PostgreSQL e no Aurora PostgreSQL podem ser criadas por usuários com os privilégios necessários. Vazio significa que nenhuma extensão pode ser instalada na instância de banco de dados do RDS. |
Administrador |
|
Esse parâmetro controla a capacidade do usuário com |
off |
Por padrão, Para conceder essa capacidade, o parâmetro |
rds_superuser |
Desativar o suporte para a extensão delegada
Desativar parcialmente
Os usuários delegados não podem criar extensões, mas ainda podem atualizar as existentes.
-
Redefina
rds.allowed_delegated_extensions
como o valor padrão no grupo de parâmetros de cluster de banco de dados. -
Use o seguinte comando em nível de banco de dados:
alter database
database_name
reset rds.allowed_delegated_extensions; -
Use o seguinte comando em nível de usuário:
alter user
user_name
reset rds.allowed_delegated_extensions;
Desativar totalmente
Revogar o perfil rds_extension
de um usuário vai restaurar as permissões padrão do usuário. O usuário não pode mais criar, atualizar nem descartar extensões.
postgres => revoke rds_extension from
user_name
;
Exemplo de gatilho de eventos
Se quiser permitir que um usuário delegado com rds_extension
use extensões que exijam permissões de configuração nos objetos criados pela criação da extensão, você poderá personalizar o exemplo abaixo de um gatilho de eventos e adicionar somente as extensões para as quais você deseja que os usuários delegados tenham acesso à funcionalidade completa. Esse gatilho de eventos pode ser criado no modelo 1 (o modelo padrão), portanto, todo banco de dados criado a partir do modelo 1 terá esse gatilho de eventos. Quando um usuário delegado instalar a extensão, esse gatilho concederá automaticamente a propriedade dos objetos criados pela extensão.
CREATE OR REPLACE FUNCTION create_ext() RETURNS event_trigger AS $$ DECLARE schemaname TEXT; databaseowner TEXT; r RECORD; BEGIN IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN RAISE NOTICE 'SECURITY INVOKER'; RAISE NOTICE 'user: %', current_user; FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension'; schemaname = ( SELECT n.nspname FROM pg_catalog.pg_extension AS e INNER JOIN pg_catalog.pg_namespace AS n ON e.extnamespace = n.oid WHERE e.oid = r.objid ); databaseowner = ( SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = current_database() ); RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner; IF r.object_identity = 'address_standardizer_data_us' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner); ELSIF r.object_identity = 'dict_int' THEN EXECUTE format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner); ELSIF r.object_identity = 'pg_partman' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner); ELSIF r.object_identity = 'postgis_topology' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); END IF; END LOOP; END IF; END; $$ LANGUAGE plpgsql SECURITY DEFINER; CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
Benefícios de usar a compatibilidade com extensões delegadas do Amazon RDS
Usando a compatibilidade com extensões delegadas do PostgreSQL, é possível delegar, com segurança, o gerenciamento de extensões a usuários que não têm o perfil rds_superuser
. Esse recurso oferece os seguintes benefícios:
-
É possível delegar facilmente o gerenciamento de extensões aos usuários de sua escolha.
-
Isso não exige o perfil
rds_superuser
. -
Oferece a capacidade de oferecer compatibilidade com um conjunto diferente de extensões para bancos de dados diferentes no mesmo cluster de banco de dados.
Limitação da compatibilidade com extensões delegadas do PostgreSQL
-
Objetos criados durante o processo de criação da extensão podem exigir privilégios adicionais para que a extensão funcione corretamente.
-
Algumas extensões não podem ser gerenciadas pelo usuário da extensão delegada por padrão, incluindo as seguintes:
log_fdw
,pg_cron
,pg_tle
,pgactive
,pglogical
,postgis_raster
,postgis_tiger_geocoder
,postgis_topology
.
Permissões necessárias para determinadas extensões
Para criar, usar ou atualizar as extensões a seguir, o usuário delegado deve ter os privilégios necessários nestas funções, tabelas e esquemas.
Extensões que precisam de propriedade ou permissões | Função | Tabelas | Schema | Dicionário de pesquisa de texto | Comentário |
---|---|---|---|---|---|
address_standardizer_data_us |
nenhuma |
us_gaz, us_lex, us_lex, I.us_rules |
nenhuma |
nenhuma |
nenhuma |
amcheck |
bt_index_check, bt_index_parent_check |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
dict_int |
nenhuma |
nenhuma |
nenhuma |
intdict |
nenhuma |
pg_partman |
nenhuma |
custom_time_partitions, part_config, part_config_sub |
nenhuma |
nenhuma |
nenhuma |
pg_stat_statements |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
PostGIS |
st_tileenvelope |
spatial_ref_sys |
nenhuma |
nenhuma |
nenhuma |
postgis_raster |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
postgis_topology |
nenhuma |
topologia, camada |
topologia |
nenhuma |
o usuário delegado deve ser o proprietário do banco de dados |
log_fdw |
create_foreign_table_for_log_file |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
rds_tools |
role_password_encryption_type |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
postgis_tiger_geocoder |
nenhuma |
geocode_settings_default, geocode_settings |
tiger |
nenhuma |
nenhuma |
pg_freespacemap |
pg_freespace |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
pg_visibility |
pg_visibility |
nenhuma |
nenhuma |
nenhuma |
nenhuma |
Considerações sobre segurança
Lembre-se de que um usuário com o perfil rds_extension
poderá gerenciar extensões em todos os bancos de dados nos quais tiver o privilégio de conexão. Se a intenção for fazer com que um usuário delegado gerencie a extensão em um único banco de dados, uma prática recomendada é revogar todos os privilégios públicos em cada banco de dados e, depois, conceder explicitamente o privilégio de conexão desse banco de dados específico ao usuário delegado.
Existem várias extensões que podem permitir que um usuário acesse informações de vários bancos de dados. Garanta que os usuários que receberem rds_extension
tenham recursos de vários bancos de dados antes de adicionar essas extensões a rds.allowed_delegated_extensions
. Por exemplo, postgres_fdw
e dblink
oferecem a capacidade de consultar vários bancos de dados na mesma instância ou em instâncias remotas. log_fdw
lê os arquivos de log do mecanismo postgres, relacionados a todos os bancos de dados na instância, possivelmente contendo consultas lentas ou mensagens de erro de vários bancos de dados. pg_cron
permite a execução de trabalhos agendados em segundo plano na instância de banco de dados e pode configurar trabalhos para execução em um banco de dados diferente.
Descartar cascata de extensão desabilitado
A capacidade de descartar a extensão com a opção em cascata por um usuário com o perfil rds_extension
é controlada pelo parâmetro rds.delegated_extension_allow_drop_cascade
. Por padrão, rds-delegated_extension_allow_drop_cascade
é definido como off
. Isso significa que os usuários com o perfil rds_extension
não têm permissão para descartar uma extensão usando a opção em cascata, conforme mostrado na consulta a seguir.
DROP EXTENSION CASCADE;
Pois isso descartará automaticamente os objetos que dependem da extensão e, por sua vez, todos os objetos que dependem desses objetos. A tentativa de usar a opção em cascata gerará um erro.
Para conceder essa capacidade, o parâmetro rds.delegated_extension_allow_drop_cascade
deve ser definido como on
.
Alterar o parâmetro dinâmico rds.delegated_extension_allow_drop_cascade
não requer a reinicialização do banco de dados. É possível fazer isso em um dos seguintes níveis:
-
No cluster ou no grupo de parâmetros da instância, por meio do AWS Management Console ou da API.
-
Usar o seguinte comando em nível de banco de dados:
alter database
database_name
set rds.delegated_extension_allow_drop_cascade = 'on'; -
Usar o seguinte comando em nível de usuário:
alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
Exemplos de extensões que podem ser adicionadas usando o suporte de extensão delegado
-
rds_tools
extension_test_db=> create extension rds_tools; CREATE EXTENSION extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files'; ERROR: permission denied for function role_password_encryption_type
-
amcheck
extension_test_db=> CREATE TABLE amcheck_test (id int); CREATE TABLE extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000)); INSERT 0 100000 extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id); CREATE INDEX extension_test_db=> create extension amcheck; CREATE EXTENSION extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass); ERROR: permission denied for function bt_index_check extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass); ERROR: permission denied for function bt_index_parent_check
-
pg_freespacemap
extension_test_db=> create extension pg_freespacemap; CREATE EXTENSION extension_test_db=> SELECT * FROM pg_freespace('pg_authid'); ERROR: permission denied for function pg_freespace extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0); ERROR: permission denied for function pg_freespace
-
pg_visibility
extension_test_db=> create extension pg_visibility; CREATE EXTENSION extension_test_db=> select * from pg_visibility('pg_database'::regclass); ERROR: permission denied for function pg_visibility
-
postgres_fdw
extension_test_db=> create extension postgres_fdw; CREATE EXTENSION extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432'); ERROR: permission denied for foreign-data wrapper postgres_fdw