

# Segurança com o Amazon Aurora PostgreSQL
<a name="AuroraPostgreSQL.Security"></a>

Para obter uma visão geral da segurança do Aurora, consulte [Segurança no Amazon Aurora](UsingWithRDS.md). É possível gerenciar a segurança do Amazon Aurora PostgreSQL em alguns níveis diferentes:
+ Para controlar quem pode realizar ações de gerenciamento do Amazon RDS em clusters de banco de dados e instâncias de banco de dados Aurora PostgreSQL, use o AWS Identity and Access Management (IAM). O IAM processa a autenticação da identidade do usuário antes que o usuário possa acessar o serviço. Ele também processa a autorização, ou seja, se o usuário tem permissão para fazer o que está tentando fazer. A autenticação de banco de dados do IAM é um método de autenticação adicional que pode ser escolhido ao criar o cluster de banco de dados do Aurora PostgreSQL. Para ter mais informações, consulte [Gerenciamento de identidade e acesso no Amazon Aurora](UsingWithRDS.IAM.md).

  Ao usar o IAM com o cluster de banco de dados do Aurora PostgreSQL, primeiro faça login no Console de gerenciamento da AWS com suas credenciais do IAM, antes de abrir o console do Amazon RDS em [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).
+ Crie clusters de banco de dados do Aurora em uma nuvem privada virtual (VPC) com base no serviço Amazon VPC. Para controlar quais dispositivos e instâncias do Amazon EC2 podem abrir conexões para o endpoint e a porta da instância de banco de dados dos clusters de banco de dados Aurora em uma VPC, use um grupo de segurança da VPC. Você pode fazer essas conexões de endpoint e de porta usando o Secure Sockets Layer (SSL). Além disso, as regras de firewall em sua empresa podem controlar se dispositivos sendo executados nela podem abrir conexões em uma instância de banco de dados. Para ter mais informações sobre VPCs, consulte [Amazon VPC e Amazon Aurora](USER_VPC.md).

  A locação da VPC compatível depende da classe de instância de banco de dados usada pelos seus clusters de bancos de dados Aurora PostgreSQL. Com a locação de VPC `default`, o cluster de banco de dados é executado em hardware compartilhado. Com a locação de VPC `dedicated`, o cluster de banco de dados é executado em uma instância de hardware dedicado. As classes de instâncias de banco de dados com performance intermitente apenas oferecem suporte para locação de VPC padrão. As classes de instância de banco de dados de performance intermitente incluem db.t3 e db.t4g. Todas as outras classes de instâncias de banco de dados Aurora PostgreSQL oferecem suporte a locações de VPC padrão e dedicada.

  Para ter mais informações sobre as classes da instância, consulte [Classes de instâncias de banco de dados do Amazon Aurora](Concepts.DBInstanceClass.md). Para ter mais informações sobre a locação de VPC `default` e `dedicated`, consulte [Instâncias dedicadas](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-instance.html) no *Guia do usuário do Amazon Elastic Compute Cloud*.
+ Para conceder permissões aos bancos de dados do PostgreSQL em execução no cluster de banco de dados do Amazon Aurora, é possível usar a mesma abordagem geral usada em instâncias autônomas do PostgreSQL. Comandos, como `CREATE ROLE`, `ALTER ROLE`, `GRANT` e `REVOKE`, funcionam exatamente como em bancos de dados on-premises, assim como a modificação direta de bancos de dados, esquemas e tabelas.

  O PostgreSQL gerencia privilégios usando *perfis*. O perfil `rds_superuser` é o mais privilegiado em um cluster de banco de dados do Aurora PostgreSQL. Esse perfil é criado automaticamente e concedido ao usuário que cria o cluster de banco de dados (a conta de usuário mestre, `postgres` por padrão). Para saber mais, consulte [Noções básicas de perfis e permissões do PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Roles.md). 

Todas as versões disponíveis do Aurora PostgreSQL, incluindo as versões 10, 11, 12, 13, 14 e posteriores, são compatíveis com o SCRAM (Salted Challenge Response Authentication Mechanism) para senhas como uma alternativa ao resumo de mensagens (MD5). Recomendamos que você use o SCRAM porque ele é mais seguro que o MD5. Para ter mais informações, inclusive como migrar senhas de usuários do banco de dados do MD5 para o SCRAM, consulte [Usar criptografia de senha SCRAM para PostgreSQL](PostgreSQL_Password_Encryption_configuration.md).

# Noções básicas de perfis e permissões do PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles"></a>

Ao criar um cluster de banco de dados do Aurora PostgreSQL usando o Console de gerenciamento da AWS, uma conta de administrador é criada ao mesmo tempo. Por padrão, o nome é `postgres`, conforme mostrado na captura de tela a seguir:

![\[A identidade de login padrão para credenciais na página Create database (Criar banco de dados) é postgres.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/AuroraUserGuide/images/default-login-identity-apg-rpg.png)


É possível escolher outro nome em vez de aceitar esse padrão (`postgres`). Se você fizer isso, o nome escolhido deverá começar com uma letra e ter 1 a 16 caracteres alfanuméricos. Para simplificar, nós nos referimos a essa conta de usuário principal pelo seu valor padrão (`postgres`) ao longo deste guia.

 Ao usar `create-db-cluster` na AWS CLI, em vez de usar o Console de gerenciamento da AWS, você cria o nome do usuário ao passá-lo com o parâmetro `master-username`. Para obter mais informações, consulte [Etapa 2: Criar um cluster de banco de dados do Aurora PostgreSQL](CHAP_GettingStartedAurora.AuroraPostgreSQL.FullConfig.md#CHAP_GettingStarted.AuroraPostgreSQL.CreateDBCluster).

Se você usar o Console de gerenciamento da AWS, a AWS CLI ou a API do Amazon RDS e se usar o nome `postgres` padrão ou escolher um nome diferente, essa primeira conta de usuário do banco de dados será membro do grupo `rds_superuser` e terá privilégios de `rds_superuser`.

**Topics**
+ [Noções básicas sobre o perfil rds\$1superuser](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)
+ [Controlar o acesso de usuários ao banco de dados PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Access.md)
+ [Delegar e controlar o gerenciamento de senhas de usuários](Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt.md)
+ [Usar criptografia de senha SCRAM para PostgreSQL](PostgreSQL_Password_Encryption_configuration.md)

# Noções básicas sobre o perfil rds\$1superuser
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser"></a>

No PostgreSQL, um *perfil* pode definir um usuário, um grupo ou um conjunto de permissões específicas concedidas a um grupo ou usuário a vários objetos no banco de dados. Os comandos do PostgreSQL para `CREATE USER` e `CREATE GROUP` foram substituídos pelo comando mais geral `CREATE ROLE` com propriedades específicas para distinguir usuários de banco de dados. Um usuário de banco de dados pode ser considerado um perfil com o privilégio LOGIN. 

**nota**  
Os comandos `CREATE USER` e `CREATE GROUP` ainda podem ser usados. Para obter mais informações, consulte [Database Roles](https://www.postgresql.org/docs/current/user-manag.html) (Perfis de banco de dados) na documentação do PostgreSQL.

O usuário `postgres` é o usuário de banco de dados mais privilegiado no cluster de banco de dados do Aurora PostgreSQL. Ele tem as características definidas pela seguinte instrução `CREATE ROLE`. 

```
CREATE ROLE postgres WITH LOGIN NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION VALID UNTIL 'infinity'
```

As propriedades `NOSUPERUSER`, `NOREPLICATION`, `INHERIT` e `VALID UNTIL 'infinity'` são as opções padrão da instrução CREATE ROLE, a menos que especificado de outra forma. 

Por padrão, `postgres` tem privilégios concedidos à função `rds_superuser` e permissões para criar funções e bancos de dados. O perfil `rds_superuser` permite que o usuário `postgres` faça o seguinte: 
+ Adicione as extensões que estão disponíveis para uso com o Aurora PostgreSQL. Para obter mais informações, consulte [Trabalhar com extensões e invólucros de dados externos](Appendix.PostgreSQL.CommonDBATasks.md). 
+ Crie funções para usuários e conceda privilégios aos usuários. Para obter mais informações, consulte [CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html) e [GRANT](https://www.postgresql.org/docs/14/sql-grant.html) na documentação do PostgreSQL. 
+ Crie bancos de dados. Para obter mais informações, consulte [CREATE DATABASE](https://www.postgresql.org/docs/14/sql-createdatabase.html) na documentação do PostgreSQL.
+ Conceda privilégios de `rds_superuser` a outras funções de usuário que não têm esses privilégios e revogue esses privilégios conforme necessário. Recomendamos que você conceda esse perfil somente aos usuários que executam tarefas de superusuário. Em outras palavras, você pode conceder esse perfil a administradores de banco de dados (DBAs) ou administradores de sistema.
+ Conceda (e revogue) o perfil `rds_replication` a usuários de banco de dados que não têm o perfil `rds_superuser`. 
+ Conceda (e revogue) o perfil `rds_password` a usuários de banco de dados que não têm o perfil `rds_superuser`. 
+ Obtenha informações de status sobre todas as conexões de banco de dados usando a visualização `pg_stat_activity`. Quando necessário, `rds_superuser` pode interromper qualquer conexão usando `pg_terminate_backend` ou `pg_cancel_backend`. 

Na instrução `CREATE ROLE postgres...`, é possível ver que o perfil do usuário `postgres` não autoriza especificamente as permissões de `superuser` do PostgreSQL. O Aurora PostgreSQL é um serviço gerenciado, portanto, você não pode acessar o sistema operacional host nem se conectar usando a conta `superuser` do PostgreSQL. Muitas das tarefas que exigem o acesso de `superuser` em um PostgreSQL autônomo são gerenciadas automaticamente pelo Aurora. 

Para obter mais informações sobre como conceder privilégios, consulte [GRANT](http://www.postgresql.org/docs/current/sql-grant.html) na documentação do PostgreSQL.

O perfil `rds_superuser` é um dos vários perfis *predefinidos* em um cluster de banco de dados do Aurora PostgreSQL. 

**nota**  
No PostgreSQL 13 e em versões anteriores, os perfis *predefinidos* são conhecidos como perfis *padrão*.

Na lista a seguir, você encontra alguns dos outros perfis predefinidos que são criados automaticamente para um novo cluster de banco de dados do Aurora PostgreSQL. Os perfis predefinidos e seus privilégios não podem ser alterados. Não é possível descartar, renomear ou modificar os privilégios desses perfis predefinidos. Qualquer tentativa de fazer isso gerará um erro. 
+ **rds\$1password**: um perfil que pode alterar senhas e configurar restrições de senha para usuários de bancos de dados. O perfil `rds_superuser` recebe esse perfil por padrão e pode concedê-lo aos usuários do banco de dados. Para obter mais informações, consulte [Controlar o acesso de usuários ao banco de dados PostgreSQLControlar o acesso de usuários ao PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Access.md).
  + Para versões do RDS para PostgreSQL anteriores à 14, o perfil `rds_password` pode alterar senhas e configurar restrições de senha para usuários de bancos de dados e usuários com o perfil `rds_superuser`. Para versões do RDS para PostgreSQL 14 e posteriores, o perfil `rds_password` pode alterar senhas e configurar restrições de senha somente para usuários de banco de dados. Somente usuários com o perfil `rds_superuser` podem realizar essas ações em outros usuários com o perfil `rds_superuser`. 
+ **rdsadmin**: um perfil criado para lidar com muitas das tarefas de gerenciamento que o administrador com privilégios de `superuser` executaria em um banco de dados PostgreSQL autônomo. Esse perfil é usado internamente pelo Aurora PostgreSQL para várias tarefas de gerenciamento. 

# Visualizar perfis e os respectivos privilégios
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.View"></a>

Você pode visualizar perfis predefinidos e os respectivos privilégios na instância de banco de dados do RDS para PostgreSQL usando comandos diferentes, dependendo da versão do PostgreSQL. Para ver todos os perfis predefinidos, você pode se conectar à sua instância de banco de dados do RDS para PostgreSQL e executar os comandos a seguir usando o `psql`.

**Para o `psql` 15 e versões anteriores**

Conecte-se à instância de banco de dados do RDS para PostgreSQL e use o comando `\du` no psql:

```
postgres=> \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+------------------------------------------------------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_monitor,pg_signal_backend,rds_password,rds_replication}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
```

**Para o `psql` 16 e versões posteriores**

```
postgres=> \drg+
                             List of role grants
   Role name   |          Member of          |       Options       | Grantor
---------------+-----------------------------+---------------------+----------
 postgres      | rds_superuser               | INHERIT, SET        | rdsadmin
 rds_superuser | pg_checkpoint               | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_monitor                  | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_signal_backend           | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_use_reserved_connections | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_password                | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_replication             | ADMIN, INHERIT, SET | rdsadmin
```

Para verificar a associação sem dependência de versão, você pode usar a seguinte consulta SQL:

```
SELECT m.rolname AS "Role name", r.rolname AS "Member of"
FROM pg_catalog.pg_roles m
JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)
LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)
WHERE m.rolname !~ '^pg_'
ORDER BY 1, 2;
```

Na saída, é possível ver que `rds_superuser` não é um perfil de usuário de banco de dados (não pode fazer login), mas tem os privilégios de muitos outros perfis. Também é possível ver que esse usuário do banco de dados `postgres` é membro do perfil `rds_superuser`. Como mencionado anteriormente, `postgres` é o valor padrão na página **Create database** (Criar banco de dados) do console do Amazon RDS. Se você escolheu outro nome, esse nome será mostrado na lista de perfis. 

**nota**  
 O Aurora PostgreSQL versões 15.2 e 14.7 introduziram um comportamento restritivo do perfil de `rds_superuser`. Um usuário do Aurora PostgreSQL precisa receber o privilégio `CONNECT` no banco de dados correspondente para se conectar, mesmo que ele receba o perfil de `rds_superuser`. Antes das versões 14.7 e 15.2 do Aurora PostgreSQL, um usuário podia se conectar a qualquer banco de dados e tabela do sistema se recebesse o perfil de `rds_superuser`. Esse comportamento restritivo alinha-se com a AWS e os compromissos do Amazon Aurora com a melhoria contínua da segurança.  
Atualize a respectiva lógica nas aplicações se o aprimoramento acima tiver algum impacto.

# Controlar o acesso de usuários ao banco de dados PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Access"></a>

Os novos bancos de dados no PostgreSQL são sempre criados com um conjunto padrão de privilégios no esquema `public` do banco de dados que permite que todos os usuários e perfis do banco de dados criem objetos. Esses privilégios permitem que os usuários do banco de dados se conectem ao banco de dados, por exemplo, e criem tabelas temporárias durante a conexão.

Para controlar melhor o acesso dos usuários às instâncias de bancos de dados que você cria no nó primário do cluster de banco de dados do Aurora PostgreSQL , recomendamos que você revogue esses privilégios de `public` padrão. Depois disso, conceda privilégios específicos aos usuários do banco de dados de forma mais granular, conforme mostrado no procedimento a seguir. 

**Como configurar perfis e privilégios para uma nova instância de banco de dados**

Suponha que você esteja configurando um banco de dados em um cluster de banco de dados do Aurora PostgreSQL recém-criado para uso por vários pesquisadores que precisam de acesso de leitura-gravação ao banco de dados. 

1. Use o `psql` (ou o pgAdmin) para se conectar à instância do banco de dados primário no cluster de banco de dados do Aurora PostgreSQL: 

   ```
   psql --host=your-cluster-instance-1.666666666666.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

   Insira sua senha quando for solicitado. O cliente `psql` conecta-se e exibe o banco de dados de conexão administrativa padrão, `postgres=>`, como o prompt.

1. Para evitar que os usuários do banco de dados criem objetos no esquema `public`, faça o seguinte:

   ```
   postgres=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
   REVOKE
   ```

1. Em seguida, crie uma nova instância de banco de dados:

   ```
   postgres=> CREATE DATABASE lab_db;
   CREATE DATABASE
   ```

1. Revogue todos os privilégios do esquema `PUBLIC` nesse novo banco de dados.

   ```
   postgres=> REVOKE ALL ON DATABASE lab_db FROM public;
   REVOKE
   ```

1. Crie um perfil para os usuários do banco de dados.

   ```
   postgres=> CREATE ROLE lab_tech;
   CREATE ROLE
   ```

1. Permita que os usuários do banco de dados que têm esse perfil conectem-se ao banco de dados.

   ```
   postgres=> GRANT CONNECT ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. Conceda a todos os usuários com o perfil `lab_tech` todos os privilégios nesse banco de dados.

   ```
   postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. Crie os usuários do banco de dados, da seguinte forma:

   ```
   postgres=> CREATE ROLE lab_user1 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   postgres=> CREATE ROLE lab_user2 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   ```

1. Conceda a esses dois usuários os privilégios associados ao perfil lab\$1tech:

   ```
   postgres=> GRANT lab_tech TO lab_user1;
   GRANT ROLE
   postgres=> GRANT lab_tech TO lab_user2;
   GRANT ROLE
   ```

Neste ponto, o `lab_user1` e o `lab_user2` podem conectar-se ao banco de dados `lab_db`. Este exemplo não segue as práticas recomendadas para uso corporativo, o que pode incluir a criação de várias instâncias de banco de dados, esquemas diferentes e concessão de permissões limitadas. Para obter informações mais completas e cenários adicionais, consulte [Managing PostgreSQL Users and Roles](https://aws.amazon.com/blogs//database/managing-postgresql-users-and-roles/) (Gerenciar usuários e perfis do PostgreSQL). 

Para obter mais informações sobre privilégios nos bancos de dados PostgreSQL, consulte o comando [GRANT](https://www.postgresql.org/docs/current/static/sql-grant.html) na documentação do PostgreSQL.

# Delegar e controlar o gerenciamento de senhas de usuários
<a name="Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt"></a>

Como DBA, talvez você queira delegar o gerenciamento de senhas de usuários. Ou talvez você queira impedir que os usuários do banco de dados alterem senhas ou reconfigurem restrições de senha, como o tempo de vida da senha. Para garantir que somente os usuários do banco de dados escolhidos possam alterar as configurações de senha, é possível ativar o recurso de gerenciamento restrito de senhas. Quando você ativa esse recurso, somente os usuários do banco de dados que receberam o perfil `rds_password` podem gerenciar senhas. 

**nota**  
Para usar o gerenciamento restrito de senhas, o cluster de banco de dados do Aurora PostgreSQL deve estar executando o Amazon Aurora PostgreSQL 10.6 ou superior.

Por padrão, esse recurso está `off`, conforme mostrado a seguir:

```
postgres=> SHOW rds.restrict_password_commands;
  rds.restrict_password_commands
--------------------------------
 off
(1 row)
```

Para ativar esse recurso, use um grupo de parâmetros personalizado e altere a configuração de `rds.restrict_password_commands` para 1. Reinicialize a instância do banco de dados primário do Aurora PostgreSQL para que a configuração entre em vigor. 

Com esse recurso ativo, os privilégios de `rds_password` são necessários para os seguintes comandos SQL:

```
CREATE ROLE myrole WITH PASSWORD 'mypassword';
CREATE ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword';
ALTER ROLE myrole VALID UNTIL '2023-01-01';
ALTER ROLE myrole RENAME TO myrole2;
```

A renomeação de um perfil (`ALTER ROLE myrole RENAME TO newname`) também será restrita se a senha usar o algoritmo de hash MD5. 

Com esse recurso ativo, qualquer tentativa de executar um desses comandos SQL sem as permissões do perfil `rds_password` gerará o seguinte erro: 

```
ERROR: must be a member of rds_password to alter passwords
```

Recomendamos conceder a `rds_password` a apenas alguns perfis usados exclusivamente para o gerenciamento de senhas. Se você conceder privilégios de `rds_password` a usuários de banco de dados que não têm privilégios de `rds_superuser`, também precisará conceder o atributo `CREATEROLE` a eles.

Verifique os requisitos de senha, como expiração e complexidade necessária, no lado do cliente. Se você usar seu próprio utilitário do lado do cliente para alterações relacionadas a senhas, o utilitário precisará ser membro de `rds_password` e ter privilégios de `CREATE ROLE`. 

# Usar criptografia de senha SCRAM para PostgreSQL
<a name="PostgreSQL_Password_Encryption_configuration"></a>

O *Salted Challenge Response Authentication Mechanism (SCRAM)* é uma alternativa ao algoritmo de resumo de mensagens padrão (MD5) do PostgreSQL para senhas de criptografia. O mecanismo de autenticação SCRAM é considerado mais seguro que o MD5. Para saber mais sobre essas duas abordagens diferentes para proteger senhas, consulte [Autorização com senha](https://www.postgresql.org/docs/14/auth-password.html) na documentação do PostgreSQL.

Recomendamos que você use o SCRAM em vez de o MD5 como o esquema de criptografia de senha para seu cluster de banco de dados do Aurora PostgreSQL. O SCRAM é compatível com o Aurora PostgreSQL versão 10 e todas as versões principais e secundárias posteriores. É um mecanismo criptográfico de resposta a desafios que usa o algoritmo scram-sha-256 para autenticação e criptografia de senha. 

Convém atualizar as bibliotecas das aplicações cliente para oferecer compatibilidade com o SCRAM. Por exemplo, versões do JDBC anteriores à 42.2.0 não são compatíveis com o SCRAM. Para obter mais informações, consulte [Driver JDBC do PostgreSQL](https://jdbc.postgresql.org/changelogs/2018-01-17-42.2.0-release/) na documentação do driver JDBC do PostgreSQL. Para obter uma lista de outros drivers do PostgreSQL e compatibilidade com o SCRAM, consulte [Lista de drivers](https://wiki.postgresql.org/wiki/List_of_drivers) na documentação do PostgreSQL.

A versão 14 do Aurora PostgreSQL e versões posteriores são compatíveis com scram-sha-256 para criptografia de senha por padrão para novos clusters de banco de dados. Para essas versões, o grupo de parâmetros de cluster de banco de dados padrão (`default.aurora-postgresql14`) tem seu valor `password_encryption` definido como scram-sha-256. Não é possível usar o SCRAM com o Aurora Serverless v1.

## Configurar o cluster de banco de dados do Aurora PostgreSQL para exigir o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.preliminary"></a>

Para o Aurora PostgreSQL 14.3 e versões superiores, você pode exigir que o cluster de banco de dados do Aurora PostgreSQL aceite apenas senhas que usem o algoritmo scram-sha-256.

**Importante**  
Para proxies RDS existentes com bancos de dados PostgreSQL, se você modificar a autenticação do banco de dados para usar somente `SCRAM`, o proxy ficará indisponível por até 60 segundos. Para evitar o problema, faça o seguinte:  
O banco de dados deve permitir tanto a autenticação `SCRAM` quanto a `MD5`.
Para usar somente a autenticação `SCRAM`, crie um proxy, migre o tráfego da aplicação para o novo proxy e exclua o proxy anteriormente associado ao banco de dados.

Antes de fazer alterações em seu sistema, entenda o processo completo da seguinte forma:
+ Obtenha informações sobre todos os perfis e criptografia de senha para todos os usuários do banco de dados. 
+ Confira novamente as configurações dos parâmetros do cluster de banco de dados do Aurora PostgreSQL para verificar os parâmetros que controlam a criptografia de senha.
+ Se o cluster de banco de dados do Aurora PostgreSQL usar um grupo de parâmetros padrão, será necessário criar um grupo de parâmetros de cluster de banco de dados personalizado e aplicá-lo ao cluster de banco de dados do Aurora PostgreSQL para poder modificar parâmetros quando necessário. Se seu cluster de banco de dados do Aurora PostgreSQL usa um grupo de parâmetros personalizado, você poderá modificar os parâmetros necessários posteriormente no processo, conforme necessário. 
+ Altere o parâmetro `password_encryption` para `scram-sha-256`.
+ Avise a todos os usuários do banco de dados que eles precisam atualizar as senhas. Faça o mesmo para a conta `postgres`. As novas senhas são criptografadas e armazenadas usando o algoritmo scram-sha-256.
+ Verifique se todas as senhas são criptografadas usando o tipo de criptografia. 
+ Se todas as senhas utilizarem scram-sha-256, você poderá alterar o parâmetro de `rds.accepted_password_auth_method` para `md5+scram`. 

**Atenção**  
Depois de alterar `rds.accepted_password_auth_method` para scram-sha-256, os usuários (perfis) com senhas criptografadas com `md5` não conseguirão se conectar. 

### Preparar-se para exigir o SCRAM para seu cluster de banco de dados do Aurora PostgreSQL
<a name="PostgreSQL_Password_Encryption_configuration.getting-ready"></a>

Antes de fazer qualquer alteração em seu cluster de banco de dados do Aurora PostgreSQL, confira todas as contas de usuário do banco de dados existentes. Além disso, verifique o tipo de criptografia usada para senhas. Você pode realizar essas tarefas usando a extensão `rds_tools`. Consulte quais versões do PostgreSQL são compatíveis com `rds_tools` em [Extension versions for Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html).

**Como obter uma lista de usuários (perfis) de banco de dados e métodos de criptografia de senha**

1. Use o `psql` para conectar-se à instância primária de seu cluster de banco de dados do Aurora PostgreSQL conforme mostrado a seguir.

   ```
   psql --host=cluster-name-instance-1.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. Instale a extensão `rds_tools`.

   ```
   postgres=> CREATE EXTENSION rds_tools;
   CREATE EXTENSION
   ```

1. Obtenha uma lista de perfis e criptografias.

   ```
   postgres=> SELECT * FROM 
         rds_tools.role_password_encryption_type();
   ```

   Você verá uma saída semelhante à seguinte.

   ```
          rolname        | encryption_type
   ----------------------+-----------------
    pg_monitor           |
    pg_read_all_settings |
    pg_read_all_stats    |
    pg_stat_scan_tables  |
    pg_signal_backend    |
    lab_tester           | md5
    user_465             | md5
    postgres             | md5
   (8 rows)
   ```

### Criar um grupo de parâmetros de cluster de banco de dados personalizado
<a name="PostgreSQL_Password_Encryption_configuration.custom-parameter-group"></a>

**nota**  
Se seu cluster de banco de dados do Aurora PostgreSQL já usa um grupo de parâmetros personalizado, não é necessário criar outro. 

Para obter uma visão geral dos grupos de parâmetros do Aurora, consulte [Criar um grupo de parâmetros de cluster de banco de dadosno Amazon Aurora](USER_WorkingWithParamGroups.CreatingCluster.md). 

O tipo de criptografia de senha usada para senhas é definido em um parâmetro, `password_encryption`. A criptografia permitida pelo cluster de banco de dados do Aurora PostgreSQL é definida em outro parâmetro, `rds.accepted_password_auth_method`. Alterar qualquer um desses valores padrão exige que você crie um grupo de parâmetros de cluster de banco de dados personalizado e aplique-o ao seu cluster. 

Você também pode usar o Console de gerenciamento da AWS ou a API do RDS para criar um grupo de parâmetros de cluster de banco de dados personalizado. Consulte mais informações em [Criar um grupo de parâmetros de cluster de banco de dadosno Amazon Aurora](USER_WorkingWithParamGroups.CreatingCluster.md). 

Associe o grupo de parâmetros personalizado à sua instância de banco de dados. 

**Como criar um grupo de parâmetros de cluster de banco de dados personalizado**

1. Use o comando `[create-db-cluster-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-cluster-parameter-group.html)` da CLI para criar o grupo de parâmetros personalizado para o cluster. O exemplo a seguir usa `aurora-postgresql13` como a origem desse grupo de parâmetros personalizado. 

   Para Linux, macOS ou Unix:

   ```
   aws rds create-db-cluster-parameter-group --db-cluster-parameter-group-name 'docs-lab-scram-passwords' \
     --db-parameter-group-family aurora-postgresql13  --description 'Custom DB cluster parameter group for SCRAM'
   ```

   Para Windows:

   ```
   aws rds create-db-cluster-parameter-group --db-cluster-parameter-group-name "docs-lab-scram-passwords" ^
     --db-parameter-group-family aurora-postgresql13  --description "Custom DB cluster parameter group for SCRAM"
   ```

   Depois, associe o grupo de parâmetros personalizado ao seu cluster. 

1. Use o comando `[modify-db-cluster](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-cluster.html)` da CLI para aplicar esse grupo de parâmetros personalizado ao cluster de banco de dados do Aurora PostgreSQL.

   Para Linux, macOS ou Unix:

   ```
   aws rds modify-db-cluster --db-cluster-identifier 'your-instance-name' \
           --db-cluster-parameter-group-name "docs-lab-scram-passwords
   ```

   Para Windows:

   ```
   aws rds modify-db-cluster --db-cluster-identifier "your-instance-name" ^
           --db-cluster-parameter-group-name "docs-lab-scram-passwords
   ```

   Para sincronizar novamente seu cluster de banco de dados do Aurora PostgreSQL com seu grupo de parâmetros de cluster de banco de dados personalizado, reinicie a instância primária e todas as outras instâncias do cluster. 

### Configurar a criptografia de senha para usar o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.configure-password-encryption"></a>

O mecanismo de criptografia de senha usado por um cluster de banco de dados do Aurora PostgreSQL é definido no grupo de parâmetros de cluster de banco de dados no parâmetro `password_encryption`. Os valores permitidos não estão definidos, `md5` ou `scram-sha-256`. O valor padrão depende da versão do Aurora PostgreSQL da seguinte forma:
+ Aurora PostgreSQL 14: o padrão é `scram-sha-256`
+ Aurora PostgreSQL 13: o padrão é `md5`

Com um grupo de parâmetros de cluster de banco de dados personalizado anexado ao cluster de banco de dados do Aurora PostgreSQL, é possível modificar valores do parâmetro de criptografia de senha.

![\[A seguir, o console do RDS mostra os valores padrão para os parâmetros password_encryption do Aurora PostgreSQL.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/AuroraUserGuide/images/apg-pwd-encryption-md5-scram-1.png)


**Como alterar a configuração de criptografia de senha para scram-sha-256**
+ Altere o valor da criptografia de senha para scram-sha-256, conforme mostrado a seguir. A alteração pode ser aplicada imediatamente porque o parâmetro é dinâmico, portanto, não é necessário reiniciar para que a alteração seja implementada. 

  Para Linux, macOS ou Unix:

  ```
  aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name \
    'docs-lab-scram-passwords' --parameters 'ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate'
  ```

  Para Windows:

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name ^
    "docs-lab-scram-passwords" --parameters "ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate"
  ```

### Migrar senhas para funções de usuário para o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.migrating-users"></a>

Você pode migrar senhas de perfis de usuário para o SCRAM conforme descrito a seguir.

**Como migrar senhas de usuário (função) do banco de dados do MD5 para o SCRAM**

1. Faça login como usuário administrador (nome de usuário padrão, `postgres`) conforme mostrado a seguir.

   ```
   psql --host=cluster-name-instance-1.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. Confira a configuração do parâmetro `password_encryption` em sua instância de banco de dados do RDS para PostgreSQL usando o comando a seguir.

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    md5
    (1 row)
   ```

1. Altere o valor desse parâmetro para scram-sha-256. Para obter mais informações, consulte [Configurar a criptografia de senha para usar o SCRAM](#PostgreSQL_Password_Encryption_configuration.configure-password-encryption). 

1.  Confira o valor novamente para garantir que agora ele esteja definido como `scram-sha-256` da seguinte forma. 

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    scram-sha-256
    (1 row)
   ```

1. Avise a todos os usuários do banco de dados para alterar senhas. Altere também sua própria senha para a conta `postgres` (o usuário do banco de dados com privilégios de `rds_superuser`). 

   ```
   labdb=> ALTER ROLE postgres WITH LOGIN PASSWORD 'change_me';
   ALTER ROLE
   ```

1. Repita o processo para todos os bancos de dados no cluster de banco de dados do Aurora PostgreSQL. 

### Alterar o parâmetro para exigir o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.require-scram"></a>

Esta é a etapa final do processo. Depois de fazer a alteração no procedimento a seguir, as contas de usuário (perfis) que ainda usam a criptografia `md5` para senhas não poderão fazer login no cluster de banco de dados do Aurora PostgreSQL. 

O `rds.accepted_password_auth_method` especifica o método de criptografia que o cluster de banco de dados do Aurora PostgreSQL aceita para uma senha de usuário durante o processo de login. O valor padrão é `md5+scram`, o que significa que qualquer método é aceito. Na imagem a seguir, você pode encontrar a configuração padrão para esse parâmetro.

![\[O console do RDS mostrando os valores padrão e permitidos para os parâmetros rds.accepted_password_auth_method.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/AuroraUserGuide/images/pwd-encryption-md5-scram-2.png)


Os valores permitidos para esse parâmetro são `md5+scram` ou `scram`. Alterar esse valor de parâmetro para `scram` torna isso um requisito. 

**Como alterar o valor do parâmetro para exigir autenticação SCRAM para senhas**

1. Verifique se todas as senhas de usuários para todos os bancos de dados no cluster de banco de dados do Aurora PostgreSQL usam `scram-sha-256` para criptografia de senha. Para fazer isso, consulte `rds_tools` para obter o perfil (usuário) e o tipo de criptografia, da seguinte forma. 

   ```
   postgres=> SELECT * FROM rds_tools.role_password_encryption_type();
     rolname        | encryption_type
     ----------------------+-----------------
     pg_monitor           |
     pg_read_all_settings |
     pg_read_all_stats    |
     pg_stat_scan_tables  |
     pg_signal_backend    |
     lab_tester           | scram-sha-256
     user_465             | scram-sha-256
     postgres             | scram-sha-256
     ( rows)
   ```

1. Repita a consulta para todas as instâncias de banco de dados em seu cluster de banco de dados do Aurora PostgreSQL. 

   Se todas as senhas usam scram-sha-256, você pode prosseguir. 

1. Altere o valor da autenticação de senha aceita para scram-sha-256 da seguinte forma.

   Para Linux, macOS ou Unix:

   ```
   aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name 'docs-lab-scram-passwords' \
     --parameters 'ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate'
   ```

   Para Windows:

   ```
   aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name "docs-lab-scram-passwords" ^
     --parameters "ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate"
   ```

## Como proteger dados do Aurora PostgreSQL com SSL/TLS
<a name="AuroraPostgreSQL.Security.SSL"></a>

O Amazon RDS oferece suporte à criptografia de Secure Socket Layer (SSL) e Transport Layer Security (TLS) para clusters de bancos de dados Aurora PostgreSQL. Usando o SSL/TLS, você pode criptografar uma conexão entre as suas aplicações e clusters de banco de dados do PostgreSQL do Aurora. Você também pode forçar todas as conexões do seu cluster de bancos de dados Aurora PostgreSQL a usar SSL/TLS. O Amazon Aurora PostgreSQL oferece suporte ao Transport Layer Security (TLS) versões 1.1 e 1.2. Recomendamos usar o TLS 1.2 para conexões criptografadas. Adicionamos suporte ao TLSv1.3 nas seguintes versões do Aurora PostgreSQL:
+ 15.3 e todas as versões posteriores
+ 14.8 e versões 14 posteriores
+ 13.11 e versões 13 posteriores
+ 12.15 e versões 12 posteriores
+ 11.20 e versões 11 posteriores

Para obter informações gerais sobre o suporte para SSL/TLS e bancos de dados do PostgreSQL, consulte [Suporte para SSL](https://www.postgresql.org/docs/current/libpq-ssl.html) na documentação do PostgreSQL. Para obter informações sobre como usar uma conexão SSL/TLS via JDBC, consulte [Como configurar o cliente](https://jdbc.postgresql.org/documentation/head/ssl-client.html) na documentação do PostgreSQL.

**Topics**
+ [Como exigir uma conexão SSL/TLS de um cluster de bancos de dados Aurora PostgreSQL](#AuroraPostgreSQL.Security.SSL.Requiring)
+ [Como determinar o status de conexão SSL/TLS](#AuroraPostgreSQL.Security.SSL.Status)
+ [Configurar conjuntos de cifras para conexões a clusters de banco de dados PostgreSQL do Aurora](#AuroraPostgreSQL.Security.SSL.ConfiguringCipherSuites)

O suporte a SSL/TLS está disponível em todas as regiões da AWS para o Aurora PostgreSQL. O Amazon RDS criará um certificado SSL/TLS para o seu cluster de bancos de dados Aurora PostgreSQL quando o cluster de banco de dados for criado. Se você habilitar a verificação de certificado SSL/TLS, o certificado SSL/TLS incluirá o endpoint do cluster de banco de dados como o nome comum (CN) do certificado SSL/TLS para se proteger contra ataques de falsificação. 

**Para se conectar a um cluster de bancos de dados Aurora PostgreSQL via SSL/TLS**

1. Baixe o certificado.

   Para obter informações sobre como baixar certificados, consulte [Usar SSL/TLS para criptografar uma conexão com um cluster de banco de dados](UsingWithRDS.SSL.md).

1. Importe o certificado no sistema operacional.

1. Conecte-se ao seu cluster de bancos de dados Aurora PostgreSQL via SSL/TLS.

   Quando você se conectar usando o SSL/TLS, seu cliente poderá optar por verificar ou não a cadeia de certificados. Se os seus parâmetros de conexão especificarem `sslmode=verify-ca` ou `sslmode=verify-full`, seu cliente exigirá que os certificados de CA do RDS estejam no armazenamento confiável ou sejam referenciados no URL da conexão. Esse requisito tem o objetivo de verificar a cadeia de certificados que assina o seu certificado de banco de dados.

   Quando um cliente, como psql ou JDBC, for configurado com o suporte para SSL/TLS, primeiro ele tentará se conectar ao banco de dados via SSL/TLS por padrão. Se esse cliente não puder se conectar via SSL/TLS, ele retomará a conexão sem SSL/TLS. Por padrão, a opção `sslmode` para clientes baseados em JDBC e libpq é definida como `prefer`. 

   Use o parâmetro `sslrootcert` para fazer referência ao certificado, por exemplo `sslrootcert=rds-ssl-ca-cert.pem`.

Veja a seguir um exemplo de como usar psql para se conectar a um cluster de banco de dados PostgreSQL do Aurora.

```
$ psql -h testpg.cdhmuqifdpib.us-east-1.rds.amazonaws.com -p 5432 \
    "dbname=testpg user=testuser sslrootcert=rds-ca-2015-root.pem sslmode=verify-full"
```

### Como exigir uma conexão SSL/TLS de um cluster de bancos de dados Aurora PostgreSQL
<a name="AuroraPostgreSQL.Security.SSL.Requiring"></a>

Para exigir conexões SSL/TLS com o cluster de bancos de dados do Aurora PostgreSQL, use o parâmetro `rds.force_ssl`.
+ Para exigir conexões SSL/TLS, defina o valor do parâmetro `rds.force_ssl` como 1 (ativado).
+ Para desativar as conexões SSL/TLS obrigatórias, defina o valor do parâmetro `rds.force_ssl` como 0 (desativado).

O valor padrão desse parâmetro depende da versão do Aurora PostgreSQL:
+ Para o Aurora PostgreSQL versões 17 e posteriores: o valor padrão é 1 (ativado).
+ Para o Aurora PostgreSQL versões 16 e posteriores: o valor padrão é 0 (desativado).

**nota**  
Quando você realiza uma atualização de versão principal do Aurora PostgreSQL versão 16 ou anterior para a versão 17 ou posterior, o valor padrão do parâmetro muda de 0 (desativado) para 1 (ativado). Essa alteração pode causar falhas de conectividade em aplicações que não estão configuradas para SSL. Você pode reverter para o comportamento padrão anterior definindo esse parâmetro como 0 (desativado).

Para ter mais informações como lidar com parâmetros, consulte [Grupos de parâmetros para Amazon Aurora](USER_WorkingWithParamGroups.md).

Atualizar o parâmetro `rds.force_ssl` também define o parâmetro `ssl` do PostgreSQL para 1 (ativado) e modifica o arquivo `pg_hba.conf` do seu cluster de banco de dados para oferecer suporte à nova configuração de SSL/TLS.

Quando o parâmetro `rds.force_ssl` for definido como 1 para um cluster de banco de dados, você verá um resultado semelhante ao seguinte ao se conectar, indicando a exigência do SSL/TLS:

```
$ psql postgres -h SOMEHOST.amazonaws.com -p 8192 -U someuser
psql (9.3.12, server 9.4.4)
WARNING: psql major version 9.3, server major version 9.4.
Some psql features might not work.
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

postgres=>
```

### Como determinar o status de conexão SSL/TLS
<a name="AuroraPostgreSQL.Security.SSL.Status"></a>

O status criptografado da conexão é mostrado no banner de login quando você se conecta ao cluster de banco de dados:

```
Password for user master: 
psql (9.3.12) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help.   

postgres=>
```

Você também pode carregar a extensão `sslinfo` e, então, chamar a função `ssl_is_used()` para determinar se o SSL/TLS está em uso. A função retornará `t` se a conexão estiver usando o SSL/TLS; caso contrário, retornará `f`.

```
postgres=> create extension sslinfo;
CREATE EXTENSION

postgres=> select ssl_is_used();
 ssl_is_used
---------
t
(1 row)
```

Você pode usar o comando `select ssl_cipher()` para determinar a criptografia de SSL/TLS:

```
postgres=> select ssl_cipher();
ssl_cipher
--------------------
DHE-RSA-AES256-SHA
(1 row)
```

 Se você habilitar `set rds.force_ssl` e reiniciar seu cluster de banco de dados, as conexões sem SSL serão recusadas com a seguinte mensagem:

```
$ export PGSSLMODE=disable
$ psql postgres -h SOMEHOST.amazonaws.com -p 8192 -U someuser
psql: FATAL: no pg_hba.conf entry for host "host.ip", user "someuser", database "postgres", SSL off
$
```

Para obter informações sobre a opção `sslmode`, consulte [Funções de controle de conexão com o banco de dados](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) na documentação do PostgreSQL.

### Configurar conjuntos de cifras para conexões a clusters de banco de dados PostgreSQL do Aurora
<a name="AuroraPostgreSQL.Security.SSL.ConfiguringCipherSuites"></a>

Usando conjuntos de cifras configuráveis, você pode ter mais controle sobre a segurança de suas conexões de banco de dados. Você pode especificar uma lista de conjuntos de cifras que deseja permitir para proteger conexões SSL/TLS do cliente com seu banco de dados. Com conjuntos de cifras configuráveis, você pode controlar a criptografia de conexão aceita pelo servidor de banco de dados. Fazer isso ajuda a evitar o uso de cifras inseguras ou obsoletas.

Os conjuntos de cifras configuráveis são compatíveis com as versões 11.8 e posteriores do Aurora PostgreSQL.

Para especificar a lista de cifras permitidas para criptografia de conexões, modifique o parâmetro de cluster `ssl_ciphers`. Defina o parâmetro `ssl_ciphers` como uma string de valores de criptografia separados por vírgulas em um grupo de parâmetros do cluster usando o Console de gerenciamento da AWS, a AWS CLI ou a API do RDS. Para definir parâmetros de cluster, consulte [Modificar parâmetros em um grupo de parâmetros de cluster de banco de dadosno Amazon Aurora](USER_WorkingWithParamGroups.ModifyingCluster.md).

A tabela a seguir mostra as criptografias compatíveis para as versões do mecanismo do Aurora PostgreSQL


| Versões de mecanismo do Aurora PostgreSQL | Criptografias compatíveis | TLS 1.1 | TLS 1.2 | TLS 1.3 | 
| --- | --- | --- | --- | --- | 
| 9.6, 10.20 e anteriores, 11.15 e anterior, 12.10 e anterior, 13.6 e anterior | DHE-RSA-AES128-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-SHA DHE-RSA-AES256-SHA256 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA ECDHE-RSA-AES256-GCM-SHA384 | Sim Não Não Não Não Não Sim Não Não Sim Não Não Sim Não | Não Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim |  Não Não Não Não Não Não Não Não Não Não Não Não Não Não  | 
| 10.21, 11.16, 12.11, 13.7, 14.3 e 14.4 |  ECDHE-RSA-AES128-SHATLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1CHACHA20\$1POLY1305\$1SHA256 | Sim Não Sim Não Sim Não Sim Não Não Sim Não Sim Não | Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim | Não Não Não Não Não Não Não Não Não Não Não Não Não | 
| 10.22, 11.17, 12.12, 13.8, 14.5 e 15.2 |  TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1CHACHA20\$1POLY1305\$1SHA256 |  Sim Não Não Sim Não Sim Não Não Sim Não Não Sim Não Sim Sim Não  | Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim | Não Não Não Não Não Não Não Não Não Não Não Não Não Não Não Não | 
| 11.20, 12.15, 13.11, 14.8, 15.3, 16.1 e posterior | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 TLS\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA TLS\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA TLS\$1ECDHE\$1RSA\$1WITH\$1CHACHA20\$1POLY1305\$1SHA256 TLS\$1AES\$1128\$1GCM\$1SHA256 TLS\$1AES\$1256\$1GCM\$1SHA384  | Sim Não Não Sim Não Sim Não Não Sim Não Não Sim Não Sim Sim Não Não Não | Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Sim Não Não |  Não Não Não Não Não Não Não Não Não Não Não Não Não Não Não Não Sim Sim  | 

Você também pode usar o comando da CLI [describe-engine-default-cluster-parameters](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-engine-default-cluster-parameters.html) para determinar quais conjuntos de cifras são atualmente compatíveis com uma família de grupos de parâmetros específica. O exemplo a seguir mostra como obter os valores permitidos para o parâmetro de cluster `ssl_cipher` para o Aurora PostgreSQL 11.

```
aws rds describe-engine-default-cluster-parameters --db-parameter-group-family aurora-postgresql11
                
    ...some output truncated...
	{
		"ParameterName": "ssl_ciphers",
		"Description": "Sets the list of allowed TLS ciphers to be used on secure connections.",
		"Source": "engine-default",
		"ApplyType": "dynamic",
		"DataType": "list",
		"AllowedValues": "DHE-RSA-AES128-SHA,DHE-RSA-AES128-SHA256,DHE-RSA-AES128-GCM-SHA256,DHE-RSA-AES256-SHA,DHE-RSA-AES256-SHA256,DHE-RSA-AES256-GCM-SHA384,
		ECDHE-RSA-AES128-SHA,ECDHE-RSA-AES128-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-SHA,ECDHE-RSA-AES256-SHA384,ECDHE-RSA-AES256-GCM-SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,
		TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
		TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
		"IsModifiable": true,
		"MinimumEngineVersion": "11.8",
		"SupportedEngineModes": [
			"provisioned"
		]
	},
    ...some output truncated...
```

O parâmetro `ssl_ciphers` é o padrão para todos os conjuntos de criptografia permitidos. Para ter mais informações sobre cifras, consulte a variável [ssl\$1ciphers](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-SSL-CIPHERS) na documentação do PostgreSQL. 

# Usar o mascaramento dinâmico do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Security.DynamicMasking"></a>

O mascaramento dinâmico de dados é um recurso de segurança que protege dados sensíveis em bancos de dados do Aurora PostgreSQL, controlando como os dados aparecem para os usuários no momento da consulta. O Aurora o implementa por meio da extensão `pg_columnmask`. `pg_columnmask` oferece proteção de dados em nível de coluna que complementa a segurança por linha nativa e os mecanismos granulares de controle de acesso do PostgreSQL.

Com `pg_columnmask`, você cria políticas de mascaramento que determinam a visibilidade dos dados com base em perfis de usuários. Quando os usuários consultam tabelas com políticas de mascaramento, o Aurora PostgreSQL aplica a função de mascaramento apropriada no momento da consulta, com base no perfil do usuário e no peso da política. Os dados subjacentes permanecem inalterados no armazenamento.

`pg_columnmask` comporta os seguintes recursos:
+ **Funções de mascaramento integradas e personalizadas**: use funções pré-integradas para padrões comuns, como mascaramento de e-mail e texto, ou crie suas próprias funções personalizadas para proteger dados sensíveis (PII) por meio de políticas de mascaramento baseadas em SQL.
+ **Várias estratégias de mascaramento**: oculte completamente as informações, substitua valores parciais por curingas ou defina abordagens de mascaramento personalizadas.
+ **Priorização de políticas**: defina várias políticas para uma única coluna. Use pesos para determinar qual política de mascaramento deve ser usada quando várias políticas se aplicam a uma coluna. O Aurora PostgreSQL aplica políticas com base no peso e na associação do perfil do usuário. 

`pg_columnmask` está disponível no Aurora PostgreSQL versão 16.10 e posterior e na versão 17.6 e posterior. As informações estão disponíveis sem custo adicional.

# Conceitos básicos de mascaramento dinâmico
<a name="AuroraPostgreSQL.Security.DynamicMasking.GetStarted"></a>

Para mascarar dados dinamicamente, você deve instalar a extensão `pg_columnmask` em seu banco de dados e cria políticas de mascaramento para suas tabelas. O processo de configuração envolve verificação de pré-requisitos, instalação de extensões, configuração de perfis, criação de políticas e testes de validação.

## Instalação e configuração da extensão
<a name="AuroraPostgreSQL.Security.DynamicMasking.GetStarted.Installation"></a>

Conecte-se ao seu cluster do Aurora PostgreSQL usando o Editor de consultas do console do RDS ou um cliente do PostgreSQL, como psql, com credenciais rds\$1superuser (usuário mestre).

Execute o comando de criação da extensão para habilitar a funcionalidade `pg_columnmask`:

```
CREATE EXTENSION pg_columnmask;
```

Esse comando instala a extensão `pg_columnmask`, cria as tabelas de catálogo necessárias e registra as funções de mascaramento integradas. A instalação da extensão é específica do banco de dados, o que significa que você deve instalá-la separadamente em cada banco de dados em que a funcionalidade é necessária.

**nota**  
As conexões estabelecidas antes da instalação dessa extensão ainda mostrarão dados não mascarados. Feche e restabeleça a conexão para corrigir isso.

Verifique a instalação da extensão conferindo as funções de mascaramento disponíveis:

```
SELECT proname FROM pg_proc
    WHERE pronamespace = 'pgcolumnmask'::regnamespace AND proname LIKE 'mask_%';
    proname     
--------Output --------
 mask_email
 mask_text
 mask_timestamp
(3 rows)
```

# Procedimentos para gerenciar políticas de mascaramento de dados
<a name="AuroraPostgreSQL.Security.DynamicMasking.Procedures"></a>

Você pode gerenciar políticas de mascaramento usando os procedimentos fornecidos pela extensão `pg_columnmask`. Para criar, modificar ou eliminar políticas de mascaramento, é necessário ter um dos seguintes privilégios:
+ Proprietário da tabela na qual você está criando a política `pg_columnmask`.
+ Membro do `rds_superuser`.
+ Membro do perfil de gerente de políticas `pg_columnmask` definido pelo parâmetro `pgcolumnmask.policy_admin_rolname`.

O seguinte comando cria uma tabela que é usada nas seções seguintes:

```
CREATE TABLE public.customers (
    id SERIAL PRIMARY KEY,
    name TEXT,
    phone TEXT,
    address TEXT,
    email TEXT
);
```

## CREATE\$1MASKING\$1POLICY
<a name="AuroraPostgreSQL.Security.DynamicMasking.Procedures.CreateMaskingPolicy"></a>

O seguinte procedimento cria uma política de mascaramento para uma tabela de usuários:

**Sintaxe**

```
create_masking_policy(
    policy_name,
    table_name,
    masking_expressions,
    roles,
    weight)
```

**Argumentos**


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| policy\$1name | NAME |  O nome da política de mascaramento. Deve ser exclusivo por tabela.  | 
| table\$1name | REGCLASS |  O nome ou oid qualificado/não qualificado da tabela à qual aplicar a política de mascaramento.  | 
| masking\$1expressions | JSONB |  Objeto JSON que contém o nome da coluna e pares de funções de mascaramento. Cada chave é um nome de coluna e seu valor é a expressão de mascaramento a ser aplicada nessa coluna.  | 
| roles | NAME[] |  Os perfis aos quais essa política de mascaramento se aplica. O padrão é PUBLIC.  | 
| weight | INT |  Peso da política de mascaramento. Quando várias políticas são aplicáveis à consulta de determinado usuário, a política com o maior peso (maior número inteiro) será aplicada a cada coluna mascarada. O padrão é 0. Não há duas políticas de mascaramento na tabela com o mesmo peso.  | 

**Tipo de retorno**

Nenhum

**Example da criação de uma política de mascaramento que mascare a coluna de e-mail do perfil `test_user`:**  

```
CALL pgcolumnmask.create_masking_policy(
    'customer_mask',
    'public.customers',
    JSON_OBJECT('{
        "email", "pgcolumnmask.mask_email(email)"
    }')::JSONB,
    ARRAY['test_user'],
    100
);
```

## ALTER\$1MASKING\$1POLICY
<a name="AuroraPostgreSQL.Security.DynamicMasking.Procedures.AlterMaskingPolicy"></a>

Esse procedimento modifica uma política de mascaramento existente. `ALTER_MASKING_POLICY` pode modificar as expressões de mascaramento da política, o conjunto de perfis aos quais a política se aplica e o peso da política de mascaramento. Quando um desses parâmetros é omitido, a parte correspondente da política permanece inalterada.

**Sintaxe**

```
alter_masking_policy(
    policy_name,
    table_name,
    masking_expressions,
    roles,
    weight)
```

**Argumentos**


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| policy\$1name | NAME |  Nome da política de mascaramento existente.  | 
| table\$1name | REGCLASS |  O oid do nome qualificado/não qualificado da tabela que contém a política de mascaramento.  | 
| masking\$1expressions | JSONB |  Novo objeto JSON que contém pares de função de mascaramento e nome da coluna ou, caso contrário, NULL.  | 
| roles | NAME[] |  A lista de novos perfis aos quais essa política de mascaramento se aplica ou, caso contrário, NULL.  | 
| weight | INT |  Novo peso para a política de mascaramento ou, caso contrário, NULL.  | 

**Tipo de retorno**

Nenhum

**Example de adicionar o perfil de analista a uma política de mascaramento existente sem alterar outros atributos da política.**  

```
CALL pgcolumnmask.alter_masking_policy(
    'customer_mask',
    'public.customers',
    NULL,
    ARRAY['test_user', 'analyst'],
    NULL 
);

-- Alter the weight of the policy without altering other details
CALL pgcolumnmask.alter_masking_policy(
    'customer_mask',
    'customers',
    NULL,
    NULL,
    4
);
```

## DROP\$1MASKING\$1POLICY
<a name="AuroraPostgreSQL.Security.DynamicMasking.Procedures.DropMaskingPolicy"></a>

Esse procedimento remove uma política de mascaramento existente.

**Sintaxe**

```
drop_masking_policy(
        policy_name,
        table_name)
```

**Argumentos**


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| policy\$1name | NAME |  Nome da política de mascaramento existente.  | 
| table\$1name | REGCLASS |  O oid do nome qualificado/não qualificado da tabela que contém a política de mascaramento.  | 

**Tipo de retorno**

Nenhum

**Example de descartar a política de mascaramento customer\$1mask**  

```
-- Drop a masking policy
    CALL pgcolumnmask.drop_masking_policy(
        'customer_mask',
        'public.customers',
    );
```

# Inserir caractere de escape em identificadores no procedimento DDL da política de mascaramento
<a name="AuroraPostgreSQL.Security.DynamicMasking.EscapeIdentifiers"></a>

Quando você cria políticas de mascaramento de dados com identificadores entre aspas, o escape adequado é necessário para garantir referências de objetos e aplicação de políticas corretas. Para usar identificadores entre aspas nos procedimentos de gerenciamento da política de mascaramento `pg_columnmask`:
+ **Nome da política**: deve ser entre aspas duplas.
+ **Nome da tabela**: tanto o nome do esquema quanto o nome da tabela devem ser colocados entre aspas duplas individualmente quando necessário.
+ **Expressões de mascaramento**: os nomes de colunas e funções nas expressões de mascaramento devem estar entre aspas duplas e as próprias aspas devem ser excluídas usando uma barra invertida.
+ **Funções**: a matriz de nomes de perfil é automaticamente citada. O nome do perfil deve corresponder exatamente ao nome, conforme visto em `pg_roles` incluindo a distinção entre maiúsculas e minúsculas.

**Example da sintaxe de escape e aspas**  
Este exemplo mostra a sintaxe adequada de escape e aspas na criação de políticas de mascaramento para tabelas, colunas, funções e perfis que usam nomes em maiúsculas e minúsculas ou exigem identificadores entre aspas no Aurora PostgreSQL.  

```
-- Create a table and columns with mixed case name 
CREATE TABLE public."Employees" (
    "Name" TEXT,
    "Email" TEXT,
    ssn VARCHAR(20)
);

-- Create a role with mixed case name
CREATE ROLE "Masked_user";

-- Create a function with mixed case name
CREATE OR REPLACE FUNCTION public."MaskEmail"(text)
    RETURNS character varying
    LANGUAGE plpgsql
    IMMUTABLE PARALLEL SAFE
    AS $$ BEGIN
        RETURN 'XXXXXXXX'::text;
    END $$;

-- Now use these objects with mixed case names in
-- masking policy management procedures
CALL pgcolumnmask.create_masking_policy(
    '"Policy1"',  -- policy name should be surrounded with double quotes for quoting
    'public."Employees"', -- table and schema name should be individually 
                          -- surrounded with double quotes for quoting
    JSON_OBJECT('{
        "\"Email\"", "\"MaskEmail\"(\"Email\")"
    }')::JSONB, -- masking expression should have double quotes around function names
                -- and columns names etc when needed. Also the double quotes itself
                -- should be escaped using \ (backslash) since this is a JSON string
    ARRAY['Masked_user'], -- Rolename do not need quoting
                          -- (this behaviour may change in future release)
    100
);

SELECT * FROM pgcolumnmask.pg_columnmask_policies
    WHERE tablename = 'Employees';
-[ RECORD 1 ]-----+-------------------------------------
schemaname        | public
tablename         | Employees
policyname        | Policy1
roles             | {Masked_user}
masked_columns    | {Email}
masking_functions | {"(\"MaskEmail\"(\"Email\"))::text"}
weight            | 100
```

## Visualizações administrativas
<a name="AuroraPostgreSQL.Security.DynamicMasking.AdminViews"></a>

Você pode revisar toda a política `pg_columnmask` usando a visualização administrativa `pgcolumnmask.pg_columnmask_policies` acessível ao público. As informações a seguir estão disponíveis usando essa visualização. A visualização exibe somente as políticas de mascaramento pertencentes ao usuário atual.


| Nome da coluna | Tipo de dados | Descrição | 
| --- | --- | --- | 
|  schemaname  | NAME |  Esquema da relação à qual a política está anexada  | 
|  tablename  | NAME |  Nome da relação à qual a política está anexada  | 
|  policyname  | NAME |  Nome da política de mascaramento, todas as políticas de mascaramento têm nomes exclusivos  | 
|  perfis  | TEXT[] |  Perfil ao qual a política se aplica.  | 
|  masked\$1columns  | TEXT[] |  Colunas mascaradas  | 
|  masking\$1functions  | TEXT[] |  Funções de mascaramento  | 
| weight | INT |  Peso da política anexada  | 

# Funções de mascaramento de dados predefinidas
<a name="AuroraPostgreSQL.Security.DynamicMasking.PredefinedMaskingFunctions"></a>

A extensão `pg_columnmask` fornece funções utilitárias integradas escritas em linguagem C (para execução mais rápida) que podem ser usadas como expressão de mascaramento para políticas `pg_columnmask`.

**mask\$1text**

Uma função para mascarar dados de texto com opções de visibilidade configuráveis.

**Argumentos**


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| input | TEXT |  A string de texto original a ser mascarada.  | 
| mask\$1char | CHAR(1) |  Caractere usado para mascarar (padrão: “X”).  | 
| visible\$1prefix | INT |  Número de caracteres no início do texto de entrada que permanecerão sem máscara (padrão: 0).  | 
| visible\$1suffix | INT |  Número de caracteres no fim do texto de entrada que permanecerão sem máscara (padrão: 0).  | 
| use\$1hash\$1mask | BOOLEAN |  Se TRUE, usa um mascaramento baseado em hash em vez de mask\$1char (padrão: FALSE).  | 

**Example de usar diferentes opções de mascaramento**  
Mascare toda a string de entrada com o caractere “X” padrão.  

```
postgres=> SELECT pgcolumnmask.mask_text('Hello World');
  mask_text  
-------------
 XXXXXXXXXXX
```
Use o argumento `mask_char` para mascarar a entrada de texto usando um caractere diferente.  

```
postgres=> SELECT pgcolumnmask.mask_text('Hello World', '*');
  mask_text  
-------------
 ***********
```
Use os parâmetros `visible_prefix` e `visible_suffix` para controlar quantos caracteres permanecem sem máscara no início e no final do texto.  

```
postgres=> SELECT pgcolumnmask.mask_text('Hello World', '*', 5, 1);
  mask_text  
-------------
 Hello*****d
```
Quando `use_hash_mask` é true, a string de entrada é mascarada usando caracteres aleatórios, o argumento `mask_char` é ignorado, mas `visible_prefix` ainda `visible_suffix` ainda são respeitados  

```
postgres=> SELECT pgcolumnmask.mask_text('Hello World', '*', 2, 2, true);
  mask_text  
-------------
 Hex36dOHild
```

**mask\$1timestamp**


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| ts\$1to\$1mask | TIMESTAMP |  O carimbo de data/hora original a ser mascarado.  | 
| mask\$1part | TEXT |  Especifica qual parte do carimbo de data/hora deve ser mascarada (padrão: “tudo”). Valores válidos: “ano”, “mês”, “dia”, “hora”, “minuto”, “segundo”, “tudo”.  | 
| mask\$1value | TIMESTAMP |  O valor do carimbo de data/hora a ser usado para mascaramento (padrão: “1900-01-01 00:00:00”).  | 

**Example de usar `mask_timestamps`**  
Esses exemplos demonstram o mascaramento completo do carimbo de data/hora em um valor padrão, o mascaramento parcial de componentes específicos do carimbo de data/hora (somente ano) e o mascaramento com um valor de substituição personalizado.  
Mascarar completamente o valor de entrada para o carimbo de data/hora padrão  

```
postgres=> SELECT pgcolumnmask.mask_timestamp('2023-06-15 14:30:00');
   mask_timestamp    
---------------------
 1900-01-01 00:00:00
```
Como mascarar apenas uma parte do carimbo de data/hora, por exemplo, apenas o ano  

```
postgres=> SELECT pgcolumnmask.mask_timestamp('2023-06-15 14:30:00', 'year');
   mask_timestamp    
---------------------
 1900-06-15 14:30:00
```
Para alterar o valor mascarado do carimbo de data/hora, use o argumento `mask_value`.  

```
postgres=> SELECT pgcolumnmask.mask_timestamp('2023-06-15 14:30:00', 'all', '2012-12-12 12:12:12');
   mask_timestamp    
---------------------
 2012-12-12 12:12:12
```

**mask\$1timestamp**

Uma função para mascarar endereços de e-mail, mas preservar a estrutura.


| Parâmetro | DataType | Descrição | 
| --- | --- | --- | 
| input | TEXT |  O endereço de e-mail original a ser mascarado.  | 
| mask\$1char | CHAR(1) |  Caractere usado para mascarar (padrão: “X”).  | 
| mask\$1local | BOOLEAN |  Se TRUE, mascara a parte local do e-mail (antes de @) (padrão: TRUE).  | 
| mask\$1domain | BOOLEAN |  Se TRUE, mascara a parte do domínio do e-mail (após @) (padrão: TRUE).  | 

**Example de usar `mask_email`**  
Esses exemplos demonstram o mascaramento de e-mail completo, os caracteres de máscara personalizados e o mascaramento seletivo da parte local ou da parte do domínio do endereço de e-mail.  
Mascaramento completo  

```
postgres=> SELECT pgcolumnmask.mask_email('user@example.com');
    mask_email    
------------------
 XXXX@XXXXXXX.com
```
Usar `mask_char` para alterar o caractere usado para mascarar  

```
postgres=> SELECT pgcolumnmask.mask_email('user@example.com', '*');
    mask_email    
------------------
 ****@*******.com
```
Usar `mask_local` e `mask_domain` para controlar o mascaramento no local e no domínio  

```
postgres=> SELECT pgcolumnmask.mask_email('user@example.com', '*', true, false);
    mask_email    
------------------
 ****@example.com

postgres=> SELECT pgcolumnmask.mask_email('user@example.com', '*', false, true);
    mask_email    
------------------
 user@*******.com
```

# Implementar pg\$1columnmask em um fluxo de trabalho completo
<a name="AuroraPostgreSQL.Security.DynamicMasking.WorkflowExample"></a>

Esta seção demonstra uma implementação completa do `pg_columnmask` utilizando um exemplo de tabela de funcionários com dados sensíveis. Você vai aprender a criar funções de mascaramento personalizadas, definir várias políticas de mascaramento com diferentes níveis de peso para vários perfis (estagiário, suporte, analista) e observará como usuários com uma ou várias associações de perfil veem diferentes níveis de dados mascarados. Os exemplos também abrangem o comportamento de mascaramento em instruções do DML com cláusulas RETURNING, gatilhos em tabelas em comparação a visualizações e operações de gerenciamento de políticas, incluindo renomeação, alteração de pesos e limpeza.

1. Crie uma tabela de exemplo com alguns dados sensíveis:

   ```
   CREATE SCHEMA hr;
   
   CREATE TABLE hr.employees (
       id INT PRIMARY KEY,
       name TEXT NOT NULL,
       email TEXT,
       ssn TEXT,
       salary NUMERIC(10,2)
    );
   
   INSERT INTO hr.employees VALUES
       (1, 'John Doe', 'john.doe@example.com', '123-45-6789', 50000.00),
       (2, 'Jane Smith', 'jane.smith@example.com', '987-65-4321', 60000.00);
   ```

1. Crie funções de mascaramento personalizadas:

   ```
   CREATE OR REPLACE FUNCTION public.mask_ssn(ssn TEXT)
       RETURNS TEXT AS $$
       BEGIN
           RETURN 'XXX-XX-' || RIGHT(ssn, 4);
       END;
       $$ LANGUAGE plpgsql;
   
   CREATE OR REPLACE FUNCTION public.mask_salary(salary NUMERIC, multiplier NUMERIC DEFAULT 0.0)
       RETURNS NUMERIC AS $$
       BEGIN
           RETURN salary * multiplier;
       END;
       $$ LANGUAGE plpgsql;
   ```

1. Crie várias políticas com diferentes níveis de mascaramento com base em perfis de usuários:

   ```
   -- Create different roles
   CREATE ROLE analyst_role;
   CREATE ROLE support_role;
   CREATE ROLE intern_role;
   
   GRANT USAGE ON SCHEMA hr TO analyst_role, support_role, intern_role;
   GRANT SELECT ON hr.employees TO analyst_role, support_role, intern_role;
   ----------------------------------------------------------------------
   
   -- Low-Weight Policy (Intern)
   CALL pgcolumnmask.create_masking_policy(
       'employee_mask_strict',
       'hr.employees',
       JSON_BUILD_OBJECT('name', 'pgcolumnmask.mask_text(name, ''*'')',
                         'email', 'pgcolumnmask.mask_email(email)',
                         'ssn', 'pgcolumnmask.mask_text(ssn, ''*'')',
                         'salary', 'public.mask_salary(salary)')::JSONB,
       ARRAY['intern_role'],
       10  -- Lowest weight
   );
   
   ----------------------------------------------------------------------
   -- Medium-Weight Policy (Support)
   CALL pgcolumnmask.create_masking_policy(
       'employee_mask_moderate',
       'hr.employees',
       JSON_BUILD_OBJECT('email', 'pgcolumnmask.mask_email(email, ''#'')',
                         'ssn', 'public.mask_ssn(ssn)',
                         'salary', 'public.mask_salary(salary)')::JSONB,
       ARRAY['support_role'],
       50   -- Medium weight
   );
   
   ----------------------------------------------------------------------
   -- High-Weight Policy (Analyst)
   CALL pgcolumnmask.create_masking_policy(
       'employee_mask_light',
       'hr.employees',
       JSON_BUILD_OBJECT('ssn', 'public.mask_ssn(ssn)',
                         'salary', 'public.mask_salary(salary, 0.9)')::JSONB,
       ARRAY['analyst_role'],
       100   -- Highest weight
   );
   ```

1. Os exemplos a seguir demonstram como diferentes usuários veem os dados com base em sua associação de perfil e nos pesos das políticas.

   ```
   -- Create users
   CREATE USER sarah_intern;
   GRANT intern_role TO sarah_intern;
   
   CREATE USER lisa_support;
   GRANT support_role TO lisa_support;
   
   CREATE USER mike_analyst;
   GRANT analyst_role TO mike_analyst;
   
   CREATE USER ethan_support_intern;
   GRANT support_role, intern_role TO ethan_support_intern;
   
   CREATE USER john_analyst_intern;
   GRANT analyst_role, intern_role TO john_analyst_intern;
   ```

   Como estagiário (mascaramento mais rigoroso):

   ```
   SET ROLE sarah_intern;
   
   SELECT * FROM hr.employees;
    id |    name    |         email          |     ssn     | salary 
   ----+------------+------------------------+-------------+--------
     1 | ********   | XXXXXXXX@XXXXXXX.com   | *********** |   0.00
     2 | ********** | XXXXXXXXXX@XXXXXXX.com | *********** |   0.00
   ```

   Como usuário de suporte (mascaramento moderado):

   ```
   SET ROLE lisa_support;
   
   SELECT * FROM hr.employees;
    id |    name    |         email          |     ssn     | salary 
   ----+------------+------------------------+-------------+--------
     1 | John Doe   | ########@#######.com   | XXX-XX-6789 |   0.00
     2 | Jane Smith | ##########@#######.com | XXX-XX-4321 |   0.00
   ```

   Como analista (mascaramento mais leve):

   ```
   SET ROLE mike_analyst;
   
   SELECT * FROM hr.employees;
    id |    name    |         email          |     ssn     |  salary  
   ----+------------+------------------------+-------------+----------
     1 | John Doe   | john.doe@example.com   | XXX-XX-6789 | 45000.00
     2 | Jane Smith | jane.smith@example.com | XXX-XX-4321 | 54000.00
   ```

   Como o usuário ethan\$1support\$1intern, que é estagiário e usuário de suporte:

   ```
   SET ROLE ethan_support_intern;
   
   -- masking policies appliable to this user: employee_mask_strict and employee_mask_moderate
   -- id : unmasked because no masking policy appliable on ethan_support_intern
   --            masks these columns
   -- name : masked because of employee_mask_strict policy
   -- email, ssn, salary : both employee_mask_strict and employee_mask_moderate mask these columns
   --                      but employee_mask_moderate will be use because of higher weight 
   
   SELECT * FROM hr.employees;
    id |    name    |         email          |     ssn     | salary 
   ----+------------+------------------------+-------------+--------
     1 | ********   | ########@#######.com   | XXX-XX-6789 |   0.00
     2 | ********** | ##########@#######.com | XXX-XX-4321 |   0.00
   ```

   Como john\$1analyst\$1intern, que é, ao mesmo tempo, estagiário e analista:

   ```
   SET ROLE john_analyst_intern;
   
   -- masking policies appliable to this user: employee_mask_strict and employee_mask_light
   -- id : unmasked because no masking policy appliable on john_analyst_intern
   --            masks these columns
   -- name, email : masked because of employee_mask_strict
   -- ssn, salary : both employee_mask_strict and employee_mask_light mask these columns
   --               but employee_mask_light will be use because of higher weight 
   
   SELECT * FROM hr.employees;
    id |    name    |         email          |     ssn     |  salary  
   ----+------------+------------------------+-------------+----------
     1 | ********   | XXXXXXXX@XXXXXXX.com   | XXX-XX-6789 | 45000.00
     2 | ********** | XXXXXXXXXX@XXXXXXX.com | XXX-XX-4321 | 54000.00
   ```

# Noções básicas sobre o comportamento de mascaramento em operações de DML
<a name="AuroraPostgreSQL.Security.DynamicMasking.DMLMasking"></a>

`pg_columnmask` é aplicado de modo consistente a todas as operações do DML, incluindo INSERT, UPDATE, DELETE e MERGE. Quando você executa essas operações, o Aurora PostgreSQL mascara os dados de acordo com um princípio fundamental: qualquer dado lido do armazenamento é mascarado de acordo com as políticas aplicáveis do usuário atual.

O mascaramento afeta alguns dos seguintes componentes de consulta, como:
+ Cláusulas WHERE
+ Condições JOIN
+ Subconsultas
+ Cláusulas RETURNING

Todos esses componentes operam com valores mascarados, não com os dados originais. Enquanto os dados são gravados no armazenamento sem máscara, os usuários só acessam a visualização mascarada ao lê-la novamente.

O Aurora PostgreSQL impõe todas as restrições do banco de dados (NOT NULL, UNIQUE, CHECK, FOREIGN KEY) nos valores reais armazenados, não nos valores mascarados. Ocasionalmente, isso poderá criar inconsistências aparentes se as funções de mascaramento não forem cuidadosamente projetadas.

O mascaramento funciona com permissões em nível de coluna:
+ Usuários sem privilégios SELECT não podem ler colunas.
+ Usuários com privilégios SELECT veem valores mascarados de acordo com as políticas aplicáveis.

# Noções básicas sobre o comportamento de mascaramento nas funções de gatilho
<a name="AuroraPostgreSQL.Security.DynamicMasking.TriggerFunctionMasking"></a>

Quando políticas `pg_columnmask` são aplicadas às tabelas, é importante entender como o mascaramento interage com as funções de gatilho. Gatilhos são funções de banco de dados que são executadas automaticamente em resposta a determinados eventos em uma tabela, como as operações INSERT, UPDATE ou DELETE.

Por padrão, o DDM aplica regras de mascaramento diferentes, dependendo do tipo de gatilho:

Gatilhos de tabela  
**Tabelas de transição não são mascaradas**: as funções de gatilho nas tabelas têm acesso aos dados não mascarados em suas tabelas de transição para versões de linha antigas e novas.  
Os proprietários de tabelas criam gatilhos e são proprietários dos dados, para que tenham acesso total para gerenciar suas tabelas de forma eficaz

Visualizar gatilhos (gatilhos INSTEAD OF)  
**As tabelas de transição são mascaradas**: as funções de gatilho nas visualizações veem os dados mascarados de acordo com as permissões do usuário atual.  
Os proprietários das visualizações podem ser diferentes dos proprietários da tabela base e devem respeitar as políticas de mascaramento nas tabelas subjacentes.

Dois parâmetros de configuração em nível de servidor controlam o comportamento do gatilho com tabelas mascaradas. Eles só podem ser definidos por `rds_superuser`:
+ **Restringir gatilhos em tabelas mascaradas**: impede a execução de gatilhos quando um usuário mascarado executa operações do DML em tabelas com políticas de mascaramento aplicáveis.
+ **Restringir gatilhos em visualizações com tabelas mascaradas**: impede a execução de gatilhos em visualizações quando a definição da visualização inclui tabelas com políticas de mascaramento aplicáveis ao usuário atual.

**Example das diferenças entre a aplicação da função à tabela e à visualização**  
O exemplo a seguir cria uma função de gatilho que imprime valores de linha antigos e novos e, depois, demonstra como a mesma função se comporta de forma diferente quando anexada a uma tabela em comparação a uma visualização.  

```
-- Create trigger function
CREATE OR REPLACE FUNCTION print_changes()
    RETURNS TRIGGER AS
    $$
        BEGIN
        RAISE NOTICE 'Old row: name=%, email=%, ssn=%, salary=%',
            OLD.name, OLD.email, OLD.ssn, OLD.salary;
        
        RAISE NOTICE 'New row: name=%, email=%, ssn=%, salary=%',
            NEW.name, NEW.email, NEW.ssn, NEW.salary;
        
        RETURN NEW;
        END;
    $$ LANGUAGE plpgsql;

-- Create trigger
CREATE TRIGGER print_changes_trigger
    BEFORE UPDATE ON hr.employees
    FOR EACH ROW
    EXECUTE FUNCTION print_changes();

-- Grant update to analyst role
GRANT UPDATE ON hr.employees TO analyst_role;

-- Unmasked data must be seen inside trigger even for masked user for the OLD and NEW
-- row passed to trigger function
BEGIN;
SET ROLE mike_analyst;
UPDATE hr.employees SET id = id + 10 RETURNING *;
NOTICE:  Old row: name=John Doe, email=john.doe@example.com, ssn=123-45-6789, salary=50000.00
NOTICE:  New row: name=John Doe, email=john.doe@example.com, ssn=123-45-6789, salary=50000.00
NOTICE:  Old row: name=Jane Smith, email=jane.smith@example.com, ssn=987-65-4321, salary=60000.00
NOTICE:  New row: name=Jane Smith, email=jane.smith@example.com, ssn=987-65-4321, salary=60000.00
 id |    name    |         email          |     ssn     |  salary  
----+------------+------------------------+-------------+----------
 11 | John Doe   | john.doe@example.com   | XXX-XX-6789 | 45000.00
 12 | Jane Smith | jane.smith@example.com | XXX-XX-4321 | 54000.00
(2 rows)

ROLLBACK;


-- Triggers on views (which are supposed to see masked data for new/old row)
CREATE VIEW hr.view_over_employees AS SELECT * FROM hr.employees;
GRANT UPDATE, SELECT ON hr.view_over_employees TO analyst_role;

-- Create trigger for this view
CREATE TRIGGER print_changes_trigger
    INSTEAD OF UPDATE ON hr.view_over_employees
    FOR EACH ROW
    EXECUTE FUNCTION print_changes();

-- Masked new and old rows should be passed to trigger if trigger is on view
BEGIN;
SET ROLE mike_analyst;
UPDATE hr.view_over_employees SET id = id + 10 RETURNING *;
NOTICE:  Old row: name=John Doe, email=john.doe@example.com, ssn=XXX-XX-6789, salary=45000.00
NOTICE:  New row: name=John Doe, email=john.doe@example.com, ssn=XXX-XX-6789, salary=45000.00
NOTICE:  Old row: name=Jane Smith, email=jane.smith@example.com, ssn=XXX-XX-4321, salary=54000.00
NOTICE:  New row: name=Jane Smith, email=jane.smith@example.com, ssn=XXX-XX-4321, salary=54000.00
 id |    name    |         email          |     ssn     |  salary  
----+------------+------------------------+-------------+----------
 11 | John Doe   | john.doe@example.com   | XXX-XX-6789 | 45000.00
 12 | Jane Smith | jane.smith@example.com | XXX-XX-4321 | 54000.00
(2 rows)
ROLLBACK;
```
Recomendamos revisar o comportamento dos gatilhos antes de implementá-los em tabelas mascaradas. Os gatilhos de tabela têm acesso a dados não mascarados em tabelas em transição, enquanto os gatilhos de visualização veem dados mascarados.

**Example de renomear uma política de mascaramento**  
O exemplo a seguir demonstra como renomear políticas existentes usando o procedimento `rename_masking_policy`.  

```
-- Rename the strict policy
CALL pgcolumnmask.rename_masking_policy(
    'employee_mask_strict',
    'hr.employees',
    'intern_protection_policy'
);

-- Verify the rename
SELECT policyname, roles, weight
    FROM pgcolumnmask.pg_columnmask_policies
    WHERE tablename = 'employees'
    ORDER BY weight DESC;

        policyname        |     roles      | weight 
--------------------------+----------------+--------
 employee_mask_light      | {analyst_role} |    100
 employee_mask_moderate   | {support_role} |     50
 intern_protection_policy | {intern_role}  |     10
```

**Example de alterar o peso da política**  
O exemplo a seguir demonstra como alterar o peso da política para alterar seu peso.  

```
-- Change weight of moderate policy
CALL pgcolumnmask.alter_masking_policy(
    'employee_mask_moderate'::NAME,
    'hr.employees'::REGCLASS,
    NULL,    -- Keep existing masking expressions
    NULL,    -- Keep existing roles
    75       -- New weight
);

-- Verify the changes
SELECT policyname, roles, weight
    FROM pgcolumnmask.pg_columnmask_policies
    WHERE tablename = 'employees'
    ORDER BY weight DESC;
        policyname        |     roles      | weight 
--------------------------+----------------+--------
 employee_mask_light      | {analyst_role} |    100
 employee_mask_moderate   | {support_role} |     75
 intern_protection_policy | {intern_role}  |     10
```

**Example de como limpar**  
O exemplo a seguir demonstra como eliminar todas as políticas, tabelas e usuários.  

```
-- Drop policies
CALL pgcolumnmask.drop_masking_policy(
    'intern_protection_policy',
    'hr.employees'
);

CALL pgcolumnmask.drop_masking_policy(
    'employee_mask_moderate',
    'hr.employees'
);

CALL pgcolumnmask.drop_masking_policy(
    'employee_mask_light',
    'hr.employees'
);

-- Drop table and functions
DROP VIEW IF EXISTS hr.view_over_employees;
DROP TABLE IF EXISTS hr.employees;
DROP SCHEMA IF EXISTS hr;
DROP FUNCTION IF EXISTS public.mask_ssn(text);
DROP FUNCTION IF EXISTS public.mask_salary(numeric, numeric);

-- Drop users
DROP USER sarah_intern, lisa_support, mike_analyst,
    ethan_support_intern, john_analyst_intern;
DROP ROLE intern_role, support_role, analyst_role;
```

# Configurar o perfil de gerenciamento de políticas de mascaramento
<a name="AuroraPostgreSQL.Security.DynamicMasking.PolicyManagementRole"></a>

A extensão de mascaramento de colunas do PostgreSQL, `pg_columnmask`, permite delegar o gerenciamento de políticas de mascaramento a um perfil específico, em vez de exigir privilégios de proprietário da tabela ou `rds_superuser`. Isso fornece um controle mais granular sobre quem pode criar, alterar e eliminar políticas de mascaramento.

Para configurar o perfil que terá privilégios de gerenciamento de políticas de mascaramento, siga estas etapas:

1. Crie o perfil de administrador de políticas: como `rds_superuser`, crie um perfil responsável pelo gerenciamento de políticas de mascaramento:

   ```
   CREATE ROLE mask_admin NOLOGIN;
   ```

1. Configure o parâmetro PostgreSQL: em seu grupo de parâmetros de cluster de banco de dados personalizado, defina o parâmetro de configuração do mecanismo `pgcolumnmask.policy_admin_rolname` com o nome do perfil que você criou:

   ```
   pgcolumnmask.policy_admin_rolname = mask_admin
   ```

   Esses parâmetros de configuração do mecanismo podem ser definidos em um grupo de parâmetros do cluster de banco de dados e não exigem a reinicialização da instância. Para acessar detalhes sobre a atualização de parâmetros, consulte [Modificar parâmetros em um grupo de parâmetros de cluster de banco de dadosno Amazon Aurora](USER_WorkingWithParamGroups.ModifyingCluster.md).

1. Conceda o perfil aos usuários como `rds_superuser`, conceda o perfil `mask_admin` aos usuários que devem ser capazes de gerenciar políticas de mascaramento:

   ```
   CREATE USER alice LOGIN;
   CREATE USER bob LOGIN;
   GRANT mask_admin TO alice, bob;
   ```

   Além disso, garanta que os usuários tenham o privilégio USAGE nos esquemas em que gerenciarão as políticas de mascaramento:

   ```
   GRANT USAGE ON SCHEMA hr TO alice, bob;
   ```

Agora, quando os usuários `alice` e `bob` se conectam ao banco de dados, eles podem usar as funções de extensão `pg_columnmask` padrão para criar, alterar e eliminar políticas de mascaramento em todas as tabelas, em todos os esquemas em que eles têm privilégios `USAGE` no esquema.

# Práticas recomendadas para a implementação segura de pg\$1columnmask
<a name="AuroraPostgreSQL.Security.DynamicMasking.BestPractices"></a>

A seção a seguir fornece as práticas recomendadas de segurança para implementação de `pg_columnmask` em seu ambiente Aurora PostgreSQL. Siga estas recomendações para:
+ Estabelecer uma arquitetura de controle de acesso com base em perfil seguro
+ Desenvolver funções de mascaramento que evitem vulnerabilidades de segurança
+ Entender e controlar o comportamento do gatilho com dados mascarados

## Arquitetura de segurança baseada em perfis
<a name="AuroraPostgreSQL.Security.DynamicMasking.BestPractices.architecture"></a>

Defina uma hierarquia de perfis para implementar controles de acesso em seu banco de dados. O Aurora PostgreSQL `pg_columnmask` aumenta esses controles fornecendo uma camada adicional para mascaramento de dados refinado dentro desses perfis.

Criar perfis dedicados que se alinhem às funções organizacionais em vez de conceder permissões a usuários individuais. Essa abordagem fornece melhor capacidade de auditoria e simplifica o gerenciamento de permissões à medida que sua estrutura organizacional evolui.

**Example de criar uma hierarquia de perfis organizacionais**  
O exemplo a seguir cria uma hierarquia de perfis organizacionais com perfis dedicados para diferentes funções e, depois, atribui usuários individuais aos perfis apropriados. Neste exemplo, os perfis organizacionais (analyst\$1role, support\$1role) são criados primeiro e, depois, os usuários individuais recebem a associação a esses perfis. Essa estrutura permite que você gerencie as permissões em nível de perfil, e não de cada usuário individual.  

```
-- Create organizational role hierarchy
CREATE ROLE data_admin_role;
CREATE ROLE security_admin_role;
CREATE ROLE analyst_role;
CREATE ROLE support_role;
CREATE ROLE developer_role;

-- Specify security_admin_role as masking policy manager in the DB cluster parameter
-- group pgcolumnmask.policy_admin_rolname = 'security_admin_role'

-- Create specific users and assign to appropriate roles
CREATE USER security_manager;
CREATE USER data_analyst1, data_analyst2;
CREATE USER support_agent1, support_agent2;

GRANT security_admin_role TO security_manager;
GRANT analyst_role TO data_analyst1, data_analyst2;
GRANT support_role TO support_agent1, support_agent2;
```
Implemente o princípio de privilégio mínimo concedendo apenas o mínimo de permissões necessárias para cada perfil. Evite conceder permissões amplas que poderiam ser exploradas se as credenciais fossem comprometidas.  

```
-- Grant specific table permissions rather than schema-wide access
GRANT SELECT ON sensitive_data.customers TO analyst_role;
GRANT SELECT ON sensitive_data.transactions TO analyst_role;
-- Do not grant: GRANT ALL ON SCHEMA sensitive_data TO analyst_role;
```
Os administradores de políticas exigem privilégios `USAGE` nos esquemas em que gerenciam políticas de mascaramento. Conceda esses privilégios de modo seletivo, seguindo o princípio do privilégio mínimo. Realize análises regulares das permissões de acesso ao esquema para garantir que somente o pessoal autorizado mantenha os recursos de gerenciamento de políticas.  
A configuração dos parâmetros do perfil de administrador da política é restrita somente aos administradores do banco de dados. Esse parâmetro não pode ser modificado em nível de banco de dados ou de sessão, impedindo que usuários sem privilégios substituam as atribuições do administrador da política. Essa restrição garante que o controle da política de mascaramento permaneça centralizado e seguro.  
Atribua o perfil de administrador de políticas a indivíduos específicos em vez de grupos. Essa abordagem direcionada garante acesso seletivo ao gerenciamento de políticas de mascaramento, pois os administradores de políticas têm a capacidade de mascarar todas as tabelas no banco de dados. 

## Desenvolvimento seguro da função de mascaramento
<a name="AuroraPostgreSQL.Security.DynamicMasking.BestPractices.MaskingDevelopment"></a>

Desenvolva funções de mascaramento usando semântica de vinculação antecipada para garantir o monitoramento adequado de dependências e evitar vulnerabilidades de vinculação tardia, como modificação do caminho de pesquisa durante o runtime. É recomendável usar a sintaxe `BEGIN ATOMIC` para funções SQL a fim de permitir a validação em tempo de compilação (ou seja, vinculação antecipada) e o gerenciamento de dependências.

```
-- Example - Secure masking function with early binding
CREATE OR REPLACE FUNCTION secure_mask_ssn(input_ssn TEXT)
    RETURNS TEXT
    LANGUAGE SQL
    IMMUTABLE PARALLEL SAFE STRICT
    BEGIN ATOMIC
        SELECT CASE
            WHEN input_ssn IS NULL THEN NULL
            WHEN length(input_ssn) < 4 THEN repeat('X', length(input_ssn))
            ELSE repeat('X', length(input_ssn) - 4) || right(input_ssn, 4)
        END;
    END;
```

Como alternativa, crie funções imunes às alterações do caminho de pesquisa qualificando explicitamente o esquema de todas as referências de objetos, garantindo um comportamento consistente em diferentes sessões de usuário.

```
-- Function immune to search path changes
CREATE OR REPLACE FUNCTION data_masking.secure_phone_mask(phone_number TEXT)
    RETURNS TEXT
    LANGUAGE SQL
    IMMUTABLE PARALLEL SAFE STRICT
    AS $$
    SELECT CASE
        WHEN phone_number IS NULL THEN NULL
        WHEN public.length(public.regexp_replace(phone_number, '[^0-9]', '', 'g')) < 10 THEN 'XXX-XXX-XXXX'
        ELSE public.regexp_replace(
            phone_number,
            '([0-9]{3})[0-9]{3}([0-9]{4})',
            public.concat('\1-XXX-\2')
        )
    END;
    $$;
```

Implemente a validação de entrada nas funções de mascaramento para lidar com casos de borda e evitar comportamentos inesperados. Sempre inclua o tratamento de NULL e valide os formatos de entrada para garantir um comportamento consistente de mascaramento. 

```
-- Robust masking function with comprehensive input validation
CREATE OR REPLACE FUNCTION secure_mask_phone(phone_number TEXT)
    RETURNS TEXT
    LANGUAGE SQL
    IMMUTABLE PARALLEL SAFE STRICT
    BEGIN ATOMIC
        SELECT CASE
            WHEN phone_number IS NULL THEN NULL
            WHEN length(trim(phone_number)) = 0 THEN phone_number
            WHEN length(regexp_replace(phone_number, '[^0-9]', '', 'g')) < 10 THEN 'XXX-XXX-XXXX'
            ELSE regexp_replace(phone_number, '([0-9]{3})[0-9]{3}([0-9]{4})', '\1-XXX-\2')
        END;
    END;
```

## Comportamento dos gatilhos do DML com pg\$1columnmask
<a name="AuroraPostgreSQL.Security.DynamicMasking.BestPractices.DMLTriggerBehavior"></a>

Para gatilhos de tabela, as tabelas de transição serão totalmente sem máscara. Para gatilhos de visualização (IOT), as tabelas de transição serão mascaradas de acordo com as permissões de visualização do usuário atual.

Gatilhos de tabela com pg\$1columnmask  
Os gatilhos recebem uma tabela de transição que contém a versão antiga e a nova das linhas modificadas pela consulta do DML de acionamento. Dependendo de quando o gatilho é acionado, o Aurora PostgreSQL preenche as linhas antiga e nova. Por exemplo, um gatilho `BEFORE INSERT` só tem novas versões das linhas e versões antigas vazias porque não há uma versão antiga para consultar.  
O `pg_columnmask` não mascara as tabelas de transição dentro dos gatilhos das tabelas. Os gatilhos podem usar colunas mascaradas dentro de seu corpo e ver dados não mascarados. O criador do gatilho deve se certificar de como ele é executado por um usuário. O exemplo a seguir funciona corretamente nesse caso.  

```
-- Example for table trigger uses masked column in its definition
-- Create a table and insert some rows
CREATE TABLE public.credit_card_table (
    name TEXT,
    credit_card_no VARCHAR(16),
    is_fraud BOOL
);

INSERT INTO public.credit_card_table (name, credit_card_no, is_fraud)
    VALUES
    ('John Doe', '4532015112830366', false),
    ('Jane Smith', '5410000000000000', true),
    ('Brad Smith', '1234567891234567', true);

-- Create a role which will see masked data and grant it privileges
CREATE ROLE intern_user;
GRANT SELECT, DELETE ON public.credit_card_table TO intern_user;

-- Trigger which will silenty skip delete of non fraudelent credit cards
CREATE OR REPLACE FUNCTION prevent_non_fraud_delete()
    RETURNS TRIGGER AS
    $$
    BEGIN
        IF OLD.is_fraud = false THEN
            RETURN NULL;
        END IF;
        RETURN OLD;
    END;
    $$ LANGUAGE plpgsql;

CREATE TRIGGER prevent_non_fraud_delete
    BEFORE DELETE ON credit_card_table
    FOR EACH ROW
    EXECUTE FUNCTION prevent_non_fraud_delete();

CREATE OR REPLACE FUNCTION public.return_false()
    RETURNS BOOLEAN
    LANGUAGE SQL
    IMMUTABLE PARALLEL SAFE STRICT
    BEGIN ATOMIC
      SELECT false;
    END;

-- A masking policy that masks both credit card number and is_fraud column.
-- If we apply masking inside trigger then prevent_non_fraud_delete trigger will
-- allow deleting more rows to masked user (even non fraud ones).
CALL pgcolumnmask.create_masking_policy(
    'mask_credit_card_no_&_is_fraud'::NAME,
    'public.credit_card_table'::REGCLASS,
    JSON_BUILD_OBJECT('credit_card_no', 'pgcolumnmask.mask_text(credit_card_no)',
                      'is_fraud', 'public.return_false()')::JSONB,
    ARRAY['intern_user']::NAME[],
    10::INT
);

-- Test trigger behaviour using intern_user
BEGIN;
SET ROLE intern_user;
-- credit card number & is_fraud is completely masked from intern_user
SELECT * FROM public.credit_card_table;
    name    |  credit_card_no  | is_fraud 
------------+------------------+----------
 John Doe   | XXXXXXXXXXXXXXXX | f
 Jane Smith | XXXXXXXXXXXXXXXX | f
 Brad Smith | XXXXXXXXXXXXXXXX | f
(3 rows)

-- The delete trigger lets the intern user delete rows for Jane and Brad even though
-- intern_user sees their is_fraud = false, but the table trigger works with original
-- unmasked value
DELETE FROM public.credit_card_table RETURNING *;
    name    |  credit_card_no  | is_fraud 
------------+------------------+----------
 Jane Smith | XXXXXXXXXXXXXXXX | f
 Brad Smith | XXXXXXXXXXXXXXXX | f
(2 rows)

COMMIT;
```
O criador do gatilho vazará dados não mascarados para o usuário se ele não tiver cuidado com as declarações que usa no corpo do gatilho. Por exemplo, usar `RAISE NOTICE ‘%’, masked_column;` imprime a coluna para o usuário atual.  

```
-- Example showing table trigger leaking column value to current user
CREATE OR REPLACE FUNCTION leaky_trigger_func()
    RETURNS TRIGGER AS
    $$
    BEGIN
        RAISE NOTICE 'Old credit card number was: %', OLD.credit_card_no;
        RAISE NOTICE 'New credit card number is %', NEW.credit_card_no;
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;

CREATE TRIGGER leaky_trigger
    AFTER UPDATE ON public.credit_card_table
    FOR EACH ROW
    EXECUTE FUNCTION leaky_trigger_func();

-- Grant update on column is_fraud to auditor role
-- auditor will NOT HAVE PERMISSION TO READ DATA
CREATE ROLE auditor;
GRANT UPDATE (is_fraud) ON public.credit_card_table TO auditor;

-- Also add auditor role to existing masking policy on credit card table
CALL pgcolumnmask.alter_masking_policy(
    'mask_credit_card_no_&_is_fraud'::NAME,
    'public.credit_card_table'::REGCLASS,
    NULL::JSONB,
    ARRAY['intern_user', 'auditor']::NAME[],
    NULL::INT
);

-- Log in as auditor
-- [auditor]
-- Update will fail if trying to read data from the table
UPDATE public.credit_card_table
    SET is_fraud = true
    WHERE credit_card_no = '4532015112830366';
ERROR:  permission denied for table cc_table

-- [auditor]
-- But leaky update trigger will still print the entire row even though
-- current user does not have permission to select from public.credit_card_table
UPDATE public.credit_card_table SET is_fraud = true;
NOTICE:  Old credit_card_no was: 4532015112830366
NOTICE:  New credit_card_no is 4532015112830366
```

Gatilhos em visualizações com pg\$1columnmask (em vez de gatilhos)  
Os gatilhos só podem ser criados em visualizações no PostgreSQL. Eles são usados para executar instruções do DML em visualizações que não são atualizáveis. As tabelas de trânsito são sempre mascaradas internamente em vez de no gatilho (IOT), porque a visualização e as tabelas base usadas na consulta de visualização podem ter proprietários diferentes. Nesse caso, as tabelas base podem ter algumas políticas de mascaramento aplicáveis ao proprietário da visualização e este deve sempre ver os dados mascarados das tabelas base dentro dos respectivos gatilhos. Isso é diferente dos gatilhos nas tabelas porque, nesse caso, o criador do gatilho e os dados dentro das tabelas pertencem ao mesmo usuário, o que não é o caso aqui.  

```
-- Create a view over credit card table
CREATE OR REPLACE VIEW public.credit_card_view
    AS
    SELECT * FROM public.credit_card_table;

-- Truncate credit card table and insert fresh data
TRUNCATE TABLE public.credit_card_table;
INSERT INTO public.credit_card_table (name, credit_card_no, is_fraud)
    VALUES
    ('John Doe', '4532015112830366', false),
    ('Jane Smith', '5410000000000000', true),
    ('Brad Smith', '1234567891234567', true);

CREATE OR REPLACE FUNCTION public.print_changes()
    RETURNS TRIGGER AS
    $$
    BEGIN
        RAISE NOTICE 'Old row: name=%, credit card number=%, is fraud=%',
            OLD.name, OLD.credit_card_no, OLD.is_fraud;
    
        RAISE NOTICE 'New row: name=%, credit card number=%, is fraud=%',
            NEW.name, NEW.credit_card_no, NEW.is_fraud;
    
    RETURN NEW;
   END;
   $$ LANGUAGE plpgsql;

CREATE TRIGGER print_changes_trigger
    INSTEAD OF UPDATE ON public.credit_card_view
    FOR EACH ROW
    EXECUTE FUNCTION public.print_changes();

GRANT SELECT, UPDATE ON public.credit_card_view TO auditor;

-- [auditor]
-- Login as auditor role
BEGIN;

-- Any data coming out from the table will be masked in instead of triggers
-- according to masking policies applicable to current user
UPDATE public.credit_card_view
    SET name = CONCAT(name, '_new_name')
    RETURNING *;
NOTICE:  Old row: name=John Doe, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=John Doe_new_name, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  Old row: name=Jane Smith, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=Jane Smith_new_name, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  Old row: name=Brad Smith, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=Brad Smith_new_name, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
        name         |  credit_card_no  | is_fraud 
---------------------+------------------+----------
 John Doe_new_name   | XXXXXXXXXXXXXXXX | f
 Jane Smith_new_name | XXXXXXXXXXXXXXXX | f
 Brad Smith_new_name | XXXXXXXXXXXXXXXX | f
 
 -- Any new data going into the table using INSERT or UPDATE command will be unmasked
 UPDATE public.credit_card_view
    SET credit_card_no = '9876987698769876'
    RETURNING *;
NOTICE:  Old row: name=John Doe, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=John Doe, credit card number=9876987698769876, is fraud=f
NOTICE:  Old row: name=Jane Smith, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=Jane Smith, credit card number=9876987698769876, is fraud=f
NOTICE:  Old row: name=Brad Smith, credit card number=XXXXXXXXXXXXXXXX, is fraud=f
NOTICE:  New row: name=Brad Smith, credit card number=9876987698769876, is fraud=f
    name    |  credit_card_no  | is_fraud 
------------+------------------+----------
 John Doe   | 9876987698769876 | f
 Jane Smith | 9876987698769876 | f
 Brad Smith | 9876987698769876 | f
 
 COMMIT;
```

GuCs em nível de banco de dados/usuário para controlar o comportamento dos gatilhos  
Dois parâmetros de configuração controlam o comportamento de execução do gatilho para usuários com políticas de mascaramento aplicáveis. Use esses parâmetros para evitar que os gatilhos sejam executados em tabelas ou visualizações mascaradas quando restrições de segurança adicionais forem necessárias. Ambos os parâmetros são desabilitados por padrão, permitindo que os gatilhos sejam executados normalmente.  
**Primeiro GUC: restrição de disparo de gatilho em tabelas mascaradas**.  
Especificações:  
+ Nome: : `pgcolumnmask.restrict_dml_triggers_for_masked_users`
+ Tipo:: `boolean`
+ Padrão: `false` (os gatilhos podem ser executados).
Impede a execução do gatilho em tabelas mascaradas para usuários mascarados quando definido como TRUE. `pg_columnmask` é executado ocasionando um erro.  
**Segundo GUC: restrição de acionamento do gatilho em visualizações com tabelas mascaradas**.  
Especificações:  
+ Nome: : `pgcolumnmask.restrict_iot_triggers_for_masked_users`
+ Tipo:: `boolean`
+ Padrão: `false` (os gatilhos podem ser executados).
Impede a execução de gatilhos em visualizações que incluem tabelas mascaradas em sua definição para usuários mascarados quando definidas como TRUE.

Esses parâmetros funcionam de forma independente e são configuráveis, como os parâmetros padrão de configuração do banco de dados.

# Cenários de movimentação de dados do pg\$1columnmask do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement"></a>

O comportamento de `pg_columnmask` varia nas diferentes operações de movimentação de dados, dependendo se a operação ocorre na camada de armazenamento, lógica ou de aplicação. As operações em nível de armazenamento (como clonagem) se comportam de maneira diferente das operações lógicas (como `pg_dump`) e das operações em nível de aplicação (como consultas FDW). Esta seção descreve o comportamento de mascaramento em cenários comuns, incluindo replicação, backups, exportações e migrações, e explica as implicações de segurança de cada um.

**Topics**
+ [Aurora Global Database e réplicas de leitura](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.RR)
+ [Clone de banco de dados e restauração de snapshot](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.Clones)
+ [Replicação lógica](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.LogRep)
+ [Implantações azuis/verdes](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.BlueGreen)
+ [Fluxos ETL zero e CDC](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.ZETL)
+ [AWS Database Migration Service](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DMS)
+ [Exportações de dados](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DataExport)
+ [Visualizações e visões materializadas](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.Views)
+ [Despejo e restauração de dados](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DDR)
+ [Wrapper de dados externos](#AuroraPostgreSQL.Security.DynamicMasking.DataMovement.FDQ)

## Aurora Global Database e réplicas de leitura
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.RR"></a>

As políticas `pg_columnmask` do Aurora são armazenadas em tabelas do sistema de banco de dados dentro do volume do cluster. Todas as réplicas acessam as mesmas políticas e exibem resultados consistentemente mascarados. Para implantações do Aurora Global Database, as políticas `pg_columnmask` são replicadas para as Regiões da AWS secundárias junto com outras tabelas do sistema de banco de dados, garantindo proteção de dados consistente em todas as regiões. Durante os cenários de failover, todas as políticas `pg_columnmask` permanecem intactas e funcionais.

## Clone de banco de dados e restauração de snapshot
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.Clones"></a>

As operações de clone rápido e restauração de snapshot do Aurora preservam todas as políticas `pg_columnmask`, perfis e configurações como parte das tabelas do sistema de banco de dados. O banco de dados clonado ou restaurado herda todas as políticas existentes do cluster de origem. Após a clonagem ou a restauração, cada cluster de banco de dados mantém políticas `pg_columnmask` independentes.

## Replicação lógica
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.LogRep"></a>

Durante a sincronização inicial, a replicação lógica usa operações SQL COPY padrão e as políticas `pg_columnmask` são aplicadas com base nas permissões do usuário de replicação. Durante o CDC (captura de dados de alteração) em andamento, as políticas de mascaramento não são aplicadas e os dados não mascarados são replicados por meio de registros do WAL. Usuários com privilégios `pg_create_subscription` podem exfiltrar dados não mascarados configurando a replicação em um sistema que eles controlem.

## Implantações azuis/verdes
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.BlueGreen"></a>

Durante a restauração do snapshot, as políticas `pg_columnmask` são incluídas automaticamente. O ambiente verde começa com uma cópia idêntica de todas as políticas do ambiente azul. Durante a replicação do azul para o verde, os dados não são mascarados. Alterações subsequentes da política de mascaramento (comandos DDL) no cluster azul não são replicadas para o cluster verde e invalidam as implantações azul/verde do RDS.

## Fluxos ETL zero e CDC
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.ZETL"></a>

A replicação de dados não é afetada pelas políticas `pg_columnmask`. O ETL zero comporta a replicação de DDL, mas não replica as políticas de RLS nem `pg_columnmask`. Nenhuma política de mascaramento é aplicada aos dados replicados em ETL zero.

## AWS Database Migration Service
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DMS"></a>

A sincronização inicial de dados é mascarada ou não mascarada com base no usuário selecionado para a tarefa do DMS. Os dados do CDC nunca são mascarados. Embora as políticas de RLS internas relacionadas a `pg_columnmask` possam ser migradas, elas não funcionarão em destinos não habilitados para pg\$1columnmask.

## Exportações de dados
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DataExport"></a>

A `pg_columnmask` trata as exportações como qualquer outra operação de consulta: o mascaramento é aplicado com base nas permissões do usuário em execução. Isso se aplica a comandos SQL, como COPY, SELECT INTO, CREATE TABLE AS e à funcionalidade de exportação do S3 do Aurora PostgreSQL. 

**nota**  
Quando usuários mascarados exportam dados, os arquivos resultantes contêm valores mascarados que podem violar as restrições do banco de dados quando restaurados.

## Visualizações e visões materializadas
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.Views"></a>

Lembre-se das seguintes considerações ao utilizar visualizações:
+ **Visualizações regulares**: sempre usam a semântica `INVOKER`. As políticas de mascaramento do usuário atual se aplicam ao consultar a visualização, independentemente de quem a criou.
+ **Visões materializadas**: quando atualizadas, as políticas de mascaramento do proprietário da visão materializada se aplicam, não as políticas do usuário que realiza a atualização. Se o proprietário tiver políticas de mascaramento, a visão materializada sempre conterá dados mascarados.

## Despejo e restauração de dados
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.DDR"></a>

`pg_dump` funciona como um usuário regular do banco de dados e aplica políticas de mascaramento com base nas permissões do usuário conectado. Se um usuário mascarado realizar um despejo, o arquivo de backup conterá dados mascarados. As politicas `pg_columnmask` são incluídas no despejo como parte do esquema do banco de dados. A restauração bem-sucedida exige que todos os perfis referidos existam no banco de dados de destino e que o destino tenha a extensão `pg_columnmask` instalada.

**nota**  
A partir do PostgreSQL 18, `pg_dump` comporta a opção `—no-policies` que exclui tanto a segurança por linha (RLS) e as políticas de mascaramento `pg_columnmask` dos despejos do banco de dados. Para acessar mais informações, consulte [pg\$1dump](https://www.postgresql.org/docs/current/app-pgdump.html).

## Wrapper de dados externos
<a name="AuroraPostgreSQL.Security.DynamicMasking.DataMovement.FDQ"></a>

Ao usar wrappers de dados externos, as políticas de mascaramento em tabelas remotas são aplicadas com base nas permissões do usuário associado no servidor de origem, não nas permissões do usuário de consulta local. Embora você possa acessar dados remotos mascarados por meio do FDW, não pode criar políticas de DDM ou RLS diretamente em tabelas externas em seu banco de dados local.