No meu blog anterior, exploramos novos recursos de replicação lógica com tabelas de partição no PostgreSQL 13. Desnecessário dizer que existem muitos desses recursos na versão mencionada que em breve aprimorarão a experiência para DBA e aplicativos desenvolvedores iguais.
Ao olhar para o PostgreSQL 13, observei uma entrada que me chamou a atenção:
O PostgreSQL 13 introduz o conceito de "extensão confiável", que permite a um superusuário especificar extensões que um usuário pode instalar em seu banco de dados desde que tenha o privilégio CREATE.
Vamos voltar
Sabemos que o PostgreSQL tem poder de extensão para adicionar penas ao seu cap sem perturbar muito seu núcleo. Em outras palavras, as extensões aprimoram os recursos funcionais do PostgreSQL Server de maneira não intrusiva.
Na verdade, existem muitas organizações terceirizadas que usaram o mecanismo de extensões para gerar conjuntos de recursos incríveis. O TimescaleDB é uma dessas extensões em que meio que altera a personalidade do PostgreSQL Server para torná-lo mais adequado para a carga de trabalho da IOT.
Vamos dar uma olhada no que havia antes do PostgreSQL 13 e por que era uma dor de cabeça. Considere uma instância do PostgreSQL hospedada contendo duas funções:
- postgres (o superusuário)
- johnsmith (um usuário normal)
E o banco de dados wooliesdb.
John Smith gostaria de adicionar a extensão postgres hstore ao wooliedb, já que o código de sua aplicação depende disso. Vamos tentar fazer isso.
psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must be superuser to create this extension.
O erro indica claramente que a extensão só pode ser criada pelo superusuário, ou seja, postgres. Mesmo que extensões como hstore não tenham nenhuma preocupação de segurança no contexto de seu uso, ainda são apenas superusuários que podem criar essa extensão no banco de dados.
E se o banco de dados for de propriedade ou criado por johnsmith - podemos tentar isso também. No trecho a seguir, o superusuário postgres está permitindo que johnsmith crie um banco de dados totalmente novo para brincar:
$ psql -U postgres
postgres=# ALTER ROLE johnsmith CREATEDB;
postgres=# \q
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE DATABASE jsDB;
wooliesdb=>\c jsDB;
You are now connected to database "jsDB" as user "johnsmith".
jsDB=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must be superuser to create this extension.
Ah! Não faz diferença. Embora johnsmith seja o proprietário do jsDB, ele ainda não pode instalar extensões simples e relevantes em seu banco de dados.
Mas isso é tudo no servidor PostgreSQL 12 (e abaixo); ele vai mudar com o PostgreSQL versão 13. No momento em que escrevo este blog - o PostgreSQL versão 13 está na fase Beta2 e a equipe já está escrevendo um anúncio de lançamento. Vou tentar “extensões confiáveis” com binários Beta2.
Aí vem o PostgreSQL 13
Espere um comportamento diferente com o conceito de extensões confiáveis (pelo menos para módulos contrib ou extensões pré-empacotadas). Vamos verificar o comportamento com o PostgreSQL13 para os mesmos comandos que fizemos para o PostgreSQL12.
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must have CREATE privilege on current database to create this extension.
O que é praticamente o mesmo, ou seja, johnsmith ainda não pode criar a extensão. Mas ainda há uma diferença sutil - a HINT que sugere que o privilégio CREATE está ausente. Nosso segundo conjunto de comandos deve cuidar disso:
$ psql -U postgres
postgres=# ALTER ROLE johnsmith CREATEDB;
postgres=# \q
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE DATABASE jsDB;
wooliesdb=>\c jsDB;
You are now connected to database "jsDB" as user "johnsmith".
jsDB=>CREATE EXTENSION hstore;
jsDB=>SELECT extname from pg_extension;
extname
---------
plpgsql
hstore
(2 rows)
As coisas realmente funcionaram desta vez. O superusuário pode permitir os mesmos privilégios no banco de dados postgres executando o seguinte comando:
postgres=# GRANT CREATE ON DATABASE postgres FOR johnsmith;
Mas há mais na extensão confiável do que isso, vamos tentar criar outra extensão:
jsDB=> create extension file_fdw;
ERROR: permission denied to create extension "file_fdw"
HINT: Must be superuser to create this extension.
A diferença vem do fato de que enquanto hstore é marcado como confiável, file_fdw NÃO é marcado como confiável. Onde isso está marcado? Está no arquivo de controle das extensões.
$ cd /usr/pgsql-13/share/extension
$ grep -l trusted hstore.control file_fdw.control;
hstore.control
Na verdade, existem 24 extensões confiáveis e 24 não tão confiáveis que vêm com o postgreSQL13.
Em poucas palavras, os superusuários podem abrir mão do controle sobre essas extensões confiáveis; e qualquer usuário com as permissões CREATE em um banco de dados pode habilitar extensões confiáveis sem entrar em contato com o administrador do banco de dados.
Conclusão
Nos bastidores, o comportamento é controlado por dois parâmetros no arquivo de controle de extensão:
- superusuário, cujo padrão é true
- confiável, cujo padrão é falso
Uma extensão pode ser criada por um não superusuário somente se ambas forem verdadeiras. Na verdade, uma extensão confiável é o script de instalação ou atualização executado como o superusuário de bootstrap, não como o usuário de chamada. Lembre-se de que as extensões podem ser escritas em uma linguagem que não é confiável - daí a necessidade.