Estratégias de privacidade dos dados

A privacidade dos dados consiste em proteger dados, como informações de identificação pessoal (IIP), de pessoas que não devem ter acesso a eles. Esta página descreve várias abordagens à privacidade dos dados que pode usar para proteger as suas PII no Cloud SQL.

Pode usar o Cloud SQL para armazenar as suas PII de forma segura. Quer garantir que estas informações são processadas com a máxima proteção de privacidade para que não sejam disponibilizadas inadvertidamente. Por exemplo, se armazenar informações de cartões de crédito ou dados de cuidados de saúde nas suas bases de dados, pode usar o Cloud SQL para ocultar ou mascarar PII de utilizadores sem privilégios.

Use as seguintes estratégias para ajudar a proteger as PII no Cloud SQL:

Segurança ao nível da coluna

A segurança ao nível da coluna permite-lhe restringir quem pode ver o conteúdo em colunas específicas de tabelas de base de dados. Os privilégios ao nível da coluna são aplicáveis às declarações INSERT, UPDATE, SELECT e REFERENCES.

Por exemplo, considere um Website de retalho onde quer reger as IPIs de dois utilizadores: o João e a Alice.

--User: "admin"

CREATE SCHEMA secure_schema;

CREATE TABLE secure_schema.user_details(id bigint, name text, age smallint, email_id text, password text);

--For this example, passwords are stored in plain text for demonstration
--purposes only. In production, never store passwords in plain text.

INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com','testpass');
INSERT INTO secure_schema.user_details VALUES(2,'alice',37,'alice@example.com','testpass');

GRANT USAGE ON SCHEMA secure_schema TO analyst_ro;

--Grant read permissions on specific columns only.

GRANT SELECT (id, name, age) ON secure_schema.user_details TO analyst_ro;

--User: "analyst_ro"

SELECT * FROM secure_schema.user_details;
ERROR:  permission denied for table user_details

SELECT name, age, password FROM secure_schema.user_details;
ERROR:  permission denied for table user_details

SELECT id, name,age FROM secure_schema.user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

Se incluir as colunas restritas na declaração SELECT ou introduzir SELECT *, é apresentada uma mensagem de erro. O Cloud SQL protege as PII de João e Alice nestas colunas.

Também pode usar uma única declaração GRANT para combinar diferentes privilégios.

GRANT SELECT (id,name,age), UPDATE (name) ON secure_schema.user_details TO analyst_ro;

Abordagem baseada em visualizações

Também pode alcançar a segurança ao nível da coluna criando uma vista numa tabela, excluindo ou ocultando colunas que quer ocultar de outros utilizadores e concedendo acesso à vista em vez de à tabela.

O exemplo seguinte mostra como usar uma abordagem baseada em visualizações para o Website de retalho para proteger as PII de João e Alice:

--User: "admin"

CREATE SCHEMA analyst_ro;
CREATE VIEW analyst_ro.user_details AS SELECT id, name, age FROM secure_schema.user_details;
GRANT USAGE ON SCHEMA analyst_ro TO analyst_ro;
GRANT SELECT ON analyst_ro.user_details TO analyst_ro;

--User: "analyst_ro"

SELECT id,name,age FROM user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

SELECT * FROM user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

Neste exemplo, é criado um esquema separado para a vista manter o mesmo nome da tabela. Com a abordagem baseada em visualizações, pode usar o SELECT *.

Também pode criar uma vista e mascarar as colunas da tabela da base de dados para que os utilizadores sem privilégios não possam ver as PII mascaradas.

CREATE VIEW analyst_ro.user_details AS SELECT id, name, age, 'redacted@example.com' as email_id,'*****'::text as password FROM secure_schema.user_details;

SELECT * FROM user_details;
 id | name  | age |     email_id         | password
----+-------+-----+----------------------+---------
  1 | jack  |  34 | redacted@example.com | *****
  2 | alice |  37 | redacted@example.com | *****

Segurança ao nível da linha

A segurança ao nível da coluna e uma abordagem baseada em visualizações permitem-lhe ocultar IIP em colunas de tabelas de bases de dados de utilizadores específicos. No entanto, por vezes, quer filtrar estes dados e conceder acesso a linhas específicas de uma tabela. Esta tabela contém as PII a que apenas determinados utilizadores podem aceder, com base nas condições de utilizador elegíveis. Isto é conhecido como segurança ao nível da linha.

A segurança ao nível da linha é útil para aplicações multi-inquilinos em que os utilizadores têm privilégios de acesso de leitura e acesso de escrita apenas às suas próprias IINs. No Cloud SQL, as tabelas podem ter políticas de segurança ao nível da linha que restringem, por utilizador, as linhas que os utilizadores podem ver através da criação de consultas ou as linhas que os utilizadores podem inserir, atualizar ou eliminar através da execução de comandos de modificação de dados.

No exemplo do Website de retalho, pode implementar a segurança ao nível da linha para o João e a Alice, de modo que possam ver as respetivas IPIs, mas não as possam modificar nem eliminar.

--User: "admin"
--Create and enable a policy for row-level security

CREATE POLICY user_details_rls_pol ON secure_schema.user_details FOR ALL TO PUBLIC USING (name=current_user);
ALTER TABLE secure_schema.user_details ENABLE ROW LEVEL SECURITY;

SELECT * FROM secure_schema.user_details;
 id | name  | age |     email_id      | password
----+-------+-----+-------------------+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--User: "jack"

SELECT * FROM secure_schema.user_details;
 id | name | age |    email_id      | password
----+------+-----+------------------+---------
  1 | jack |  34 | jack@example.com | testpass

--User: "alice"

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+-------------------+---------
  2 | alice |  37 | alice@example.com | testpass

Os utilizadores atribuídos a funções com o atributo BYPASSRLS podem ignorar a segurança ao nível da linha quando acedem a uma tabela. Os proprietários das tabelas também podem ignorar a segurança ao nível das linhas. Se quiser sujeitar um proprietário da tabela à segurança ao nível da linha, use o comando ALTER TABLE ... FORCE ROW LEVEL SECURITY.

Por vezes, não quer aplicar a segurança ao nível da linha a linhas de uma tabela de base de dados. Por exemplo, se usar o comando pg_dump para fazer uma cópia de segurança da tabela, não quer que nenhuma linha seja omitida da cópia de segurança. Para evitar que isto ocorra, para o utilizador que faz a cópia de segurança, defina o parâmetro de configuração row_security como OFF. Se alguma linha for filtrada com base na segurança ao nível da linha, é apresentada uma mensagem de erro.

Mascare e anonimize dados

Além de mascarar dados através de uma abordagem baseada na visualização, pode mascarar dados através da extensão postgresql_anonymizer. Esta extensão oculta ou substitui PII ou dados comercialmente confidenciais de uma base de dados PostgreSQL.

A utilização da extensão em vez de uma abordagem baseada em visualizações oferece-lhe as seguintes vantagens:

  • Tem várias funções de ocultação, como substituição, aleatorização, simulação, pseudonimização, codificação parcial, baralhamento, adição de ruído e generalização.

  • Pode gerar dados ocultados significativos que pode usar para testes funcionais e processamento de dados.

  • Pode usar a linguagem de definição de dados (LDD) do PostgreSQL para declarar regras de ocultação e especificar a estratégia de anonimização na definição da tabela.

Instale e configure a extensão postgresql_anonymizer

Para usar esta extensão numa instância do Cloud SQL, conclua os seguintes passos:

  1. Edite a instância e, de seguida, defina cloudsql.enable_anon flag como on. Para ver informações sobre a definição de flags e rever as flags suportadas para a extensão, consulte o artigo Configure flags de base de dados.

  2. Crie a extensão na base de dados executando o seguinte comando:

    --Connect to the PostgreSQL database
    
    CREATE EXTENSION IF NOT EXISTS anon CASCADE;
    SELECT anon.init();
    

Depois de instalar e configurar a extensão, use-a na instância para implementar estratégias de anonimização de máscara dinâmica, máscara estática e descarga anónima.

Máscara dinâmica

Use máscaras dinâmicas para definir regras de ocultação para utilizadores específicos. Estes utilizadores não podem ver PII. Em vez disso, veem dados ocultados. Todos os outros utilizadores veem os dados sem ocultação. Isto é útil em ambientes de produção quando não quer alterar as IIP, mas apenas ocultá-las de determinados utilizadores.

No exemplo do Website de retalho, pode implementar máscaras dinâmicas para que o administrador possa ver os endereços de email e as palavras-passe não ocultados do João e da Alice, mas o analista só possa ver os dados ocultados.

--Activate the dynamic masking engine

SELECT anon.start_dynamic_masking();

--Declare the masking user and masking rules
--analyst_ro is the masked user with select privileges on the
--user_details table

SECURITY LABEL FOR anon ON ROLE analyst_ro IS 'MASKED';

SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.email_id IS 'MASKED WITH FUNCTION anon.fake_email()';
SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.password  IS 'MASKED WITH FUNCTION anon.hash(password)';

--User: "admin" (can see all unmasked data)

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+------------  -----+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--User:"analyst_ro" (note that the "email_id" and "password" columns are
--replaced with masked data,)
--Data in the password column is truncated for better formatting.

SELECT * FROM secure_schema.user_details;
 id | name  | age |       email_id         | password
----+-------+-----+-----------------  -----+----------------
  1 | jack  |  34 | alisontodd@example.com | 13d249f2cb4127b
  2 | alice |  37 | amanda35@example.com   | 13d249f2cb4127b

Máscara estática

Use máscaras estáticas para remover as PII numa tabela, de acordo com os critérios definidos nas regras de ocultação, e substitua estas informações por dados ocultados. Os utilizadores não podem obter os dados não ocultados. Isto é útil em ambientes de teste quando quer alterar as IPIs e não quer que nenhum utilizador veja estas informações.

No exemplo do Website de retalho, pode implementar máscaras estáticas para que nenhum utilizador possa ver os endereços de email e as palavras-passe não ocultados de João e Alice. Em vez disso, só veem dados ocultados.

--User: "admin"

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+--------------  ---+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--Apply earlier defined masking rules to the table permanently.
--Now all users see masked data only.

SELECT anon.anonymize_table('secure_schema.user_details');
 anonymize_table
-----------------
 t

--User: "analyst_ro"
--Data in the password column is truncated for better formatting.

select * from secure_schema.user_details;
 id | name  | age |           email_id              |  password
----+-------+-----+-------------------------  ------+---------------
  1 | jack  |  34 | christophercampbell@example.com | 13d249f2cb412c
  2 | alice |  37 | annebenitez@example.com         | 13d249f2cb4127

Despejo anónimo

Use despejos anónimos para exportar dados ocultados para um ficheiro SQL. Para o exemplo do Website de retalho, pode criar um ficheiro de despejo para os dados ocultados contidos na tabela user_details.

--Launch pg_dump_anon with the masked user to apply earlier defined --masking rules

pg_dump_anon -h HOSTIP -p 5432 -d DATABASE_NAME -U analyst_ro --table=secure_schema.user_details --file=user_details_anonysms.sql

Encripte dados

Embora possa ocultar PII, as informações são armazenadas na base de dados como texto simples. Um administrador pode ver estas informações.

Use a extensão pgcrypto para encriptar as PII antes de as armazenar. Desta forma, apenas os utilizadores que tenham uma chave de encriptação válida podem desencriptar as informações e vê-las como texto simples.

A extensão pgcrypto tem várias funções de hash e encriptação.

Hash

Um hash é uma função criptográfica unidirecional em que só se preocupa em encriptar as IIP. Isto é útil para armazenar palavras-passe num formato com hash e fazer corresponder as palavras-passe introduzidas pelo utilizador às palavras-passe com hash. As palavras-passe com hash nunca são desencriptadas em texto simples.

No exemplo do Website de retalho, pode usar a extensão pgcrypto para aplicar hash à palavra-passe do João antes de a armazenar na tabela user_details.

--Hash passwords before storing them in the user_details table.

TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com',crypt('testpassword', gen_salt('bf')));

--Match the hashed data with user entered password

SELECT id, name FROM secure_schema.user_details WHERE email_id = 'jack@example.com' AND password = crypt('testpassword', password);
 id | name
----+-----
  1 | jack

Encriptar

Use uma função criptográfica de encriptação para encriptar PII com uma chave. Em seguida, os utilizadores precisam desta chave para desencriptar as informações em texto simples. Isto é útil para armazenar informações de cartões de crédito e detalhes bancários quando as aplicações querem obter as IIP num formato legível.

No exemplo do Website de retalho, a palavra-passe e o endereço de email do João estão encriptados. Os utilizadores que têm a chave de encriptação podem desencriptar estas informações e vê-las como texto simples. Para todos os outros utilizadores, é apresentada uma mensagem de erro.

--"user_acc_key" is the encryption key

TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,pgp_sym_encrypt('jack@example.com','user_acc_key'),pgp_sym_encrypt('testpassword','user_acc_key'));

--User: "admin" (queries without an encryption key)
--Data in the email_id and password columns are truncated for better
--formatting.

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id     | password
----+-------+-----+-----------------+-------------------
  1 | jack |  34 | \xc30d0407030209 | \xc30d040703028962

--User: "app_user" (queries with a valid encryption key)

SELECT name,pgp_sym_decrypt(email_id::bytea,'user_acc_key'),pgp_sym_decrypt(password::bytea,'user_acc_key') FROM secure_schema.user_details;
 name | pgp_sym_decrypt   | pgp_sym_decrypt
------+-------------------+----------------
 jack | jack@example.com  | testpassword

--If a user uses the wrong encryption key, then the following error message appears:

SELECT name,pgp_sym_decrypt(email_id::bytea,'user_bad_key'),
pgp_sym_decrypt(password::bytea,'user_bad_key') FROM secure_schema.user_details;
ERROR:  Wrong key or corrupt data

O que se segue?

Saiba mais sobre os seguintes controlos adicionais que pode usar para proteger as PII de acesso injustificado: