Usar a compatibilidade com extensões delegadas do Amazon RDS para PostgreSQL - Amazon Relational Database Service

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

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:

  1. Conceder o perfil rds_extension a um usuário: conecte-se ao banco de dados rds_superuser e execute o seguinte comando:

    Postgres => grant rds_extension to user_name;
  2. 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 dados rds.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.

  3. 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. O rds_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

rds.allowed_delegated_extensions

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

  • Por padrão, esse parâmetro é uma string vazia, o que significa que nenhuma extensão foi delegada aos usuários com rds_extension.

  • Qualquer extensão compatível poderá ser adicionada se o usuário tiver permissões para isso. Para fazer isso, defina o parâmetro rds.allowed_delegated_extensions como uma string de nomes de extensão separados por vírgulas. Ao adicionar uma lista de extensões a esse parâmetro, você deve identificar explicitamente as extensões que o usuário com o perfil rds_extension pode instalar.

  • Quando definido como *, significa que todas as extensões listadas em rds_allowed_extensions são delegadas aos usuários com o perfil rds_extension.

Para saber mais sobre como configurar esse parâmetro, consulte Ativar o suporte de extensão delegado a um usuário.

rds_superuser

rds.allowed_extensions

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

rds-delegated_extension_allow_drop_cascade

Esse parâmetro controla a capacidade do usuário com rds_extension de eliminar a extensão usando uma opção em cascata.

off

Por padrão, rds-delegated_extension_allow_drop_cascade é definido como off. Isso significa que os usuários com rds_extension não têm permissão para descartar uma extensão usando a opção em cascata.

Para conceder essa capacidade, o parâmetro rds.delegated_extension_allow_drop_cascade deve ser definido como on.

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