PostgreSQL: Usuários, Roles e Gerenciamento de Privilégios…

Última atualização: 2026-08-26

1. O Que Você Vai Aprender


2. A História

Charlie é o DBA de uma plataforma SaaS de e-commerce e precisa configurar privilégios de banco de dados para 5 equipes:

Equipe Privilégios necessários
dev (desenvolvimento) Leitura/escrita em todas as tabelas de negócio, criar tabelas de teste
analytics (analítica) Somente leitura em todas as tabelas de negócio, criar views materializadas
ops (operações) Gerenciar usuários, monitorar o banco de dados
audit (auditoria) Ler apenas logs de auditoria, não dados de negócio
app (serviço de aplicação) Leitura/escrita em tabelas de negócio, sem DDL

Charlie usa herança de roles e RLS para implementar o princípio do menor privilégio.


3. Conceito: Roles e Usuários

(1) CREATE ROLE vs CREATE USER

Comando Privilégio LOGIN Forma equivalente
CREATE ROLE r1; Nenhum (não pode fazer login)
CREATE USER u1; Sim (pode fazer login) CREATE ROLE u1 LOGIN;

No PG, usuários e roles são o mesmo conceito; USER é apenas uma ROLE com o atributo LOGIN.

(2) Atributos de Role em Resumo

Atributo Descrição Sintaxe de criação
LOGIN Permitir conexão ao banco de dados LOGIN / NOLOGIN
SUPERUSER Superusuário, ignora todos os privilégios SUPERUSER
CREATEDB Pode criar bancos de dados CREATEDB
CREATEROLE Pode criar/gerenciar roles CREATEROLE
INHERIT Herda automaticamente privilégios das roles possuídas INHERIT (padrão)
NOINHERIT Não herda automaticamente; precisa de SET ROLE NOINHERIT
PASSWORD Definir senha PASSWORD 'xxx'
VALID UNTIL Data de expiração da senha VALID UNTIL 'timestamp'

▶ Exemplo: Criar Roles e Usuários

SQL
-- Roles de grupo (não podem fazer login)
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team NOINHERIT;
CREATE ROLE audit_team NOINHERIT;

-- Usuários de login
-- ⚠️ Não codifique senhas em produção; use variáveis de ambiente ou um gerenciador de segredos
CREATE USER alice_dev PASSWORD 'SecureP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'SecureP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'SecureP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'SecureP@ss4' IN ROLE ops_team INHERIT;

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: Modificar Atributos de Role

SQL
-- Adicionar privilégio CREATEDB ao líder de operações
ALTER ROLE diana_ops CREATEDB;

-- Definir expiração de senha
ALTER ROLE charlie_analyst VALID UNTIL '2025-12-31';

-- Renomear uma role
ALTER ROLE dev_team RENAME TO engineering_team;

-- Desabilitar login temporariamente
ALTER ROLE bob_dev NOLOGIN;

Output:

TEXT 📖 Somente leitura
CREATE TABLE

4. Conceito: Privilégios GRANT / REVOKE

(1) Hierarquia de Privilégios

100%
flowchart TD
    A[Banco de Dados<br/>CONNECT / CREATE / TEMP] --> B[Esquema<br/>CREATE / USAGE]
    B --> C[Tabela<br/>SELECT / INSERT / UPDATE / DELETE / TRUNCATE / REFERENCES / TRIGGER]
    C --> D[Coluna<br/>SELECT / INSERT / UPDATE / REFERENCES]
    B --> E[Função<br/>EXECUTE]
    B --> F[Sequence<br/>USAGE / SELECT / UPDATE]
    A --> G[Role<br/>MEMBER / SET]

    style A fill:#e1f5fe
    style B fill:#bbdefb
    style C fill:#c8e6c9
    style D fill:#fff9c4

(2) Palavras-Chave de Privilégios Comuns

Objeto Privilégios concedíveis Descrição
DATABASE CONNECT, CREATE, TEMP Conectar, criar esquema, tabelas temporárias
SCHEMA CREATE, USAGE Criar objetos, acessar objetos
TABLE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER CRUD completo + referência de chave estrangeira
COLUMN SELECT, INSERT, UPDATE, REFERENCES Controle em nível de coluna
FUNCTION EXECUTE Chamar função
SEQUENCE USAGE, SELECT, UPDATE Usar sequence

▶ Exemplo: GRANT de Privilégios em Nível de Tabela

SQL
-- Equipe dev: CRUD completo nas tabelas de negócio
GRANT SELECT, INSERT, UPDATE, DELETE ON products TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON customers TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON order_items TO dev_team;

-- Equipe analytics: somente leitura
GRANT SELECT ON products TO analytics_team;
GRANT SELECT ON orders TO analytics_team;
GRANT SELECT ON customers TO analytics_team;

-- Equipe audit: apenas logs de auditoria
GRANT SELECT ON price_audit_log TO audit_team;
GRANT SELECT ON ddl_audit_log TO audit_team;

Output:

TEXT 📖 Somente leitura
INSERT 0 1

▶ Exemplo: GRANT de Privilégios de Esquema e Banco de Dados

SQL
-- Equipe dev pode criar objetos no esquema dev
GRANT CREATE, USAGE ON SCHEMA dev TO dev_team;

-- Equipe analytics pode usar mas não criar no esquema public
GRANT USAGE ON SCHEMA public TO analytics_team;

-- Permitir analytics criar views materializadas em seu próprio esquema
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;

-- Serviço de aplicação conecta ao banco de dados
GRANT CONNECT ON DATABASE shop_db TO app_service;

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: REVOKE de Privilégios

SQL
-- Revogar DELETE da equipe dev em products
REVOKE DELETE ON products FROM dev_team;

-- Revogar todos os privilégios em uma tabela
REVOKE ALL PRIVILEGES ON orders FROM public;

-- Revogar direito de criação de esquema
REVOKE CREATE ON SCHEMA dev FROM dev_team;

-- Cascata: revogar e concessões dependentes
REVOKE SELECT ON products FROM analytics_team CASCADE;

Output:

TEXT 📖 Somente leitura
DELETE 2

(3) GRANT ALL e GRANT SELECT ALL TABLES

Comando Efeito
GRANT ALL ON t TO r; Conceder todos os privilégios na tabela t
GRANT ALL ON SCHEMA s TO r; Conceder todos os privilégios no esquema s
GRANT SELECT ON ALL TABLES IN SCHEMA s TO r; Conceder SELECT em todas as tabelas no esquema s
GRANT USAGE ON ALL SEQUENCES IN SCHEMA s TO r; Conceder USAGE em todas as sequences

5. Conceito: DEFAULT PRIVILEGES

(1) Por que Privilégios Padrão São Necessários

Um GRANT simples afeta apenas objetos já existentes. Tabelas criadas no futuro não receberão privilégios automaticamente. DEFAULT PRIVILEGES resolve isso.

Comando Efeito
ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON TABLES TO r; Novas tabelas em s recebem concessão automática
ALTER DEFAULT PRIVILEGES FOR ROLE owner GRANT ... Privilégios padrão para um criador específico

▶ Exemplo: Definir Privilégios Padrão

SQL
-- Todas as tabelas futuras no esquema public são legíveis por analytics_team
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO analytics_team;

-- Todas as tabelas futuras criadas por app_service são graváveis por dev_team
ALTER DEFAULT PRIVILEGES FOR ROLE app_service IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE ON TABLES TO dev_team;

-- Todas as sequences futuras no esquema public
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO dev_team;

-- Todas as funções futuras
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT EXECUTE ON FUNCTIONS TO analytics_team;

Output:

TEXT 📖 Somente leitura
INSERT 0 1

▶ Exemplo: Visualizar Privilégios Padrão Atuais

SQL
SELECT
  pg_get_userbyid(defaclrole) AS grantor,
  pg_get_userbyid(defaclnamespace) AS namespace_owner,
  n.nspname AS schema,
  defaclobjtype AS object_type,
  defaclacl AS acl
FROM pg_default_acl d
JOIN pg_namespace n ON n.oid = d.defaclnamespace;

Output:

TEXT 📖 Somente leitura
 id | name     | value 
----+----------+-------
  1 | example  | 42
(1 row)

6. Conceito: Políticas de Segurança em Nível de Linha (RLS)

(1) Como o RLS Funciona (Recurso do PG)

RLS permite controlar o acesso a dados no nível da linha—diferentes roles veem linhas diferentes na mesma tabela.

Passo Comando Descrição
1. Habilitar RLS ALTER TABLE t ENABLE ROW LEVEL SECURITY; Habilitar segurança em nível de linha na tabela
2. Criar política CREATE POLICY ... ON t ...; Definir a regra de nível de linha
3. SUPERUSER ignora SUPERUSER não está sujeito a RLS por padrão
4. Proprietário da tabela ignora O proprietário da tabela não está sujeito por padrão; use FORCE para impor

(2) Tipos de Política

Tipo de política Palavra-chave Descrição
SELECT FOR SELECT Controla linhas visíveis
INSERT FOR INSERT Controla linhas inseríveis
UPDATE FOR UPDATE Controla linhas atualizáveis (inclui BEFORE/AFTER)
DELETE FOR DELETE Controla linhas excluíveis
ALL FOR ALL Compartilhado em todas as operações

▶ Exemplo: Habilitar RLS e Criar uma Política

SQL
-- Habilitar RLS na tabela orders
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Analistas só podem ver pedidos concluídos
CREATE POLICY pol_analytics_completed
  ON orders FOR SELECT
  TO analytics_team
  USING (order_status = 'completed');

-- Equipe dev pode ver todas as linhas
CREATE POLICY pol_dev_all
  ON orders FOR ALL
  TO dev_team
  USING (true)
  WITH CHECK (true);

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: RLS Baseado no Usuário Atual

SQL
-- Habilitar RLS na tabela customers
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;

-- Cada usuário de atendimento vê apenas sua região atribuída
CREATE POLICY pol_region_access
  ON customers FOR SELECT
  USING (region = current_setting('app.region', true));

-- Forçar o proprietário da tabela a também cumprir RLS
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: WITH CHECK para INSERT/UPDATE

SQL
-- Equipe de vendas só pode inserir pedidos em sua região
CREATE POLICY pol_sales_insert
  ON orders FOR INSERT
  TO dev_team
  WITH CHECK (region = current_setting('app.region', true));

-- Equipe de vendas só pode atualizar pedidos em sua região
CREATE POLICY pol_sales_update
  ON orders FOR UPDATE
  TO dev_team
  USING (region = current_setting('app.region', true))
  WITH CHECK (region = current_setting('app.region', true));

Output:

TEXT 📖 Somente leitura
INSERT 0 1

(3) USING vs WITH CHECK

Cláusula Papel Aplica-se a
USING Filtra linhas visíveis (o WHERE de SELECT/UPDATE/DELETE) SELECT/UPDATE/DELETE
WITH CHECK Valida se a nova linha é permitida (novos valores de INSERT/UPDATE) INSERT/UPDATE

7. Conceito: Herança de Roles e Views de Sistema

(1) INHERIT vs NOINHERIT

Atributo Comportamento Cenário
INHERIT (padrão) Obtém automaticamente privilégios das roles possuídas Usuários regulares
NOINHERIT Precisa de SET ROLE r para usar privilégios Elevação temporária de privilégio, separação de auditoria

▶ Exemplo: NOINHERIT e SET ROLE

SQL
-- Criar uma role poderosa com NOINHERIT
CREATE ROLE admin_role NOINHERIT;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin_role;

-- Diana está em admin_role mas não pode usar privilégios de admin automaticamente
CREATE USER diana PASSWORD 'SecureP@ss5' IN ROLE admin_role NOINHERIT;

-- Diana deve alternar explicitamente para usar direitos de admin
SET ROLE admin_role;
-- Agora diana pode realizar operações de admin
RESET ROLE;
-- De volta aos privilégios normais

Output:

TEXT 📖 Somente leitura
CREATE TABLE

(2) Views de Sistema

View Conteúdo
pg_roles Todas as roles e seus atributos
pg_auth_members Relacionamentos role–membro
information_schema.role_table_grants Privilégios em nível de tabela
information_schema.role_usage_grants Privilégios de esquema/função

▶ Exemplo: Consultar Roles e Privilégios

SQL
-- Listar todas as roles e seus atributos
SELECT rolname, rolsuper, rolcreatedb, rolcanlogin, rolinherit
FROM pg_roles
WHERE rolname NOT LIKE 'pg_%'
ORDER BY rolname;

-- Listar associação de roles
SELECT
  r1.rolname AS member,
  r2.rolname AS role
FROM pg_auth_members m
JOIN pg_roles r1 ON r1.oid = m.member
JOIN pg_roles r2 ON r2.oid = m.roleid
ORDER BY r2.rolname, r1.rolname;

-- Verificar privilégios de tabela para uma role
SELECT table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'analytics_team'
ORDER BY table_name, privilege_type;

Output:

TEXT 📖 Somente leitura
CREATE TABLE

8. Fluxograma: Decisão de Configuração de Privilégios

100%
flowchart TD
    A[Configurar privilégios] --> B{Precisa de controle em nível de linha?}
    B -->|Sim| C[Habilitar RLS<br/>CREATE POLICY]
    B -->|Não| D{Granularidade do privilégio?}
    D -->|Tabela inteira| E[GRANT ON TABLE]
    D -->|Coluna específica| F[GRANT nome_coluna ON TABLE]
    D -->|Todas as tabelas no esquema| G[GRANT ALL TABLES IN SCHEMA]
    E --> H{Precisa de concessão automática em novas tabelas?}
    G --> H
    H -->|Sim| I[ALTER DEFAULT PRIVILEGES]
    H -->|Não| J[GRANT manual]
    C --> K{Precisa restringir o proprietário da tabela também?}
    K -->|Sim| L[FORCE ROW LEVEL SECURITY]
    K -->|Não| M[Proprietário ignora RLS por padrão]
    I --> N{Usuário precisa de elevação temporária?}
    J --> N
    N -->|Sim| O[NOINHERIT + SET ROLE]
    N -->|Não| P[INHERIT por padrão]

    style C fill:#fff9c4
    style I fill:#c8e6c9
    style O fill:#ffcdd2

9. Exemplo Completo

Charlie configura um sistema de privilégios completo para as 5 equipes:

SQL
-- Passo 1: Criar roles de grupo
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team INHERIT;
CREATE ROLE audit_team NOINHERIT;
CREATE ROLE app_service LOGIN PASSWORD 'AppSecRet!';

-- Passo 2: Conceder permissões de esquema
GRANT CREATE, USAGE ON SCHEMA public TO dev_team;
GRANT USAGE ON SCHEMA public TO analytics_team;
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
GRANT USAGE ON SCHEMA public TO ops_team;
GRANT USAGE ON SCHEMA audit TO audit_team;

-- Passo 3: Conceder permissões de tabela
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO dev_team;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analytics_team;
GRANT SELECT ON ALL TABLES IN SCHEMA audit TO audit_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON products, orders, order_items, customers TO app_service;

-- Passo 4: Privilégios padrão para tabelas futuras
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO analytics_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dev_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA audit
  GRANT SELECT ON TABLES TO audit_team;

-- Passo 5: Permissões de sequence e função
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO dev_team;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO dev_team;

-- Passo 6: RLS - analistas só veem pedidos concluídos
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_analytics_orders
  ON orders FOR SELECT
  TO analytics_team
  USING (order_status = 'completed');

-- Passo 7: RLS - equipe de auditoria só vê o esquema audit
ALTER TABLE price_audit_log ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_audit_read
  ON price_audit_log FOR SELECT
  TO audit_team
  USING (true);

-- Passo 8: Criar usuários de login e atribuir roles
CREATE USER alice_dev PASSWORD 'DevP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'DevP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'AnlP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'OpsP@ss4' IN ROLE ops_team CREATEROLE;
CREATE USER eve_audit PASSWORD 'AudP@ss5' IN ROLE audit_team;

❓ Perguntas Frequentes

P: Qual a diferença entre CREATE USER e CREATE ROLE? R: CREATE USER é equivalente a CREATE ROLE ... LOGIN. No PG, usuários e roles são o mesmo conceito; USER é apenas uma role que carrega o atributo LOGIN por padrão.

P: GRANT SELECT ON ALL TABLES inclui tabelas criadas no futuro? R: Não. ALL TABLES concede apenas para tabelas atualmente existentes. Tabelas futuras precisam de ALTER DEFAULT PRIVILEGES para concessão automática ou um GRANT manual.

P: RLS afeta superusuários? R: Não por padrão. SUPERUSER ignora todas as políticas RLS. Para forçar, use ALTER TABLE ... FORCE ROW LEVEL SECURITY, mas isso só se aplica ao proprietário da tabela—SUPERUSER ainda ignora.

P: Como uma role NOINHERIT obtém privilégios temporariamente? R: Use SET ROLE role_alvo para alternar para a role alvo e obter seus privilégios; após terminar, RESET ROLE restaura os privilégios originais. SET ROLE afeta apenas a sessão atual.

P: REVOKE precisa de CASCADE? R: Se o privilégio revogado foi por sua vez concedido a outra role (uma concessão dependente), você precisa de CASCADE para revogar tudo de uma vez. O RESTRICT padrão gerará erro quando houver dependência.

P: Como visualizar quais privilégios um usuário realmente tem? R: Consulte a view information_schema.role_table_grants ou use os comandos \dp e \du+ do psql. Note que roles INHERIT obtêm automaticamente os privilégios das roles às quais pertencem.

P: USING e WITH CHECK do RLS podem ser escritos separadamente? R: Sim. Se apenas USING for escrito, WITH CHECK assume o mesmo valor de USING. Para uma política ALL, recomenda-se escrever ambos explicitamente para tornar o controle claro.

P: E se USAGE em um esquema não for suficiente para acessar uma tabela? R: USAGE apenas permite "entrar" no esquema e ver a lista de objetos; você também precisa de um privilégio como SELECT na tabela específica. Ambas as camadas de privilégio devem ser satisfeitas.


📖 Resumo


📝 Exercícios

  1. ⭐ Crie uma role readonly e um usuário report_user, conceda a readonly SELECT em todas as tabelas no esquema public e defina privilégios padrão para que tabelas recém-criadas também recebam concessão automática.

  2. ⭐⭐ Habilite RLS na tabela orders e crie políticas: sales_team só pode ver pedidos em sua própria região (region = current_setting('app.region')); audit_team só pode ver pedidos com order_status = 'completed'.

  3. ⭐⭐⭐ Projete um sistema de privilégios completo: crie 3 roles de grupo (backend_dev, data_analyst, db_admin), concedendo a cada uma diferentes níveis de privilégio (esquema/tabela/coluna/função/sequence), configure DEFAULT PRIVILEGES, conceda a coluna salary separadamente (analista não pode vê-la) e use pg_roles e information_schema para consultar e verificar o resultado da configuração.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%