Strategie per la privacy dei dati

La privacy dei dati consiste nel proteggere dati come le informazioni che consentono l'identificazione personale (PII) da chi non dovrebbe avervi accesso. Questa pagina descrive diversi approcci alla privacy dei dati che puoi utilizzare per proteggere le tue PII in Cloud SQL.

Puoi utilizzare Cloud SQL per archiviare in modo sicuro le tue PII personali. Vuoi assicurarti che queste informazioni vengano trattate con la massima protezione della privacy, in modo che non vengano rese accessibili inavvertitamente. Ad esempio, se memorizzi informazioni sulla carta di credito o dati sanitari nei tuoi database, puoi utilizzare Cloud SQL per nascondere o mascherare le PII agli utenti senza privilegi.

Utilizza le seguenti strategie per proteggere le PII in Cloud SQL:

Sicurezza a livello di colonna

La sicurezza a livello di colonna ti consente di limitare le persone che possono visualizzare i contenuti in colonne specifiche delle tabelle del database. I privilegi a livello di colonna sono applicabili alle istruzioni INSERT, UPDATE, SELECT e REFERENCES.

Ad esempio, considera un sito web di vendita al dettaglio in cui vuoi gestire PII di due utenti: Jack e 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 includi le colonne con limitazioni nell'istruzione SELECT o inserisci SELECT *, viene visualizzato un messaggio di errore. Cloud SQL protegge le informazioni PII di Jack e Alice in queste colonne.

Puoi anche utilizzare una singola istruzione GRANT per combinare diversi privilegi.

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

Approccio basato sulle visualizzazioni

Puoi anche ottenere la sicurezza a livello di colonna creando una vista di una tabella, escludendo o mascherando le colonne che vuoi nascondere ad altri utenti e fornendo l'accesso alla vista anziché alla tabella.

L'esempio seguente mostra come utilizzare un approccio basato sulla visualizzazione per il sito web di vendita al dettaglio per proteggere i dati PII di Jack 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

In questo esempio, viene creato uno schema separato per la visualizzazione in modo che il nome rimanga uguale a quello della tabella. Con l'approccio basato sulla visualizzazione, puoi utilizzare SELECT *.

Puoi anche creare una vista e mascherare le colonne della tabella del database in modo che gli utenti senza privilegi non possano vedere le PII mascherate.

CREATE OR REPLACE 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 | *****

Sicurezza a livello di riga

La sicurezza a livello di colonna e un approccio basato sulle viste consentono di nascondere le PII nelle colonne delle tabelle del database a utenti specifici. Tuttavia, a volte vuoi filtrare questi dati e concedere l'accesso a righe specifiche di una tabella. Questa tabella contiene le PII a cui possono accedere solo determinati utenti, in base alle condizioni di idoneità degli utenti. Questa operazione è nota come sicurezza a livello di riga.

La sicurezza a livello di riga è utile per le applicazioni multi-tenant in cui gli utenti dispongono di privilegi di accesso in lettura e scrittura solo per le proprie PII. In Cloud SQL, le tabelle possono avere policy di sicurezza a livello di riga che limitano, in base all'utente, le righe che gli utenti possono visualizzare creando query o le righe che gli utenti possono inserire, aggiornare o eliminare eseguendo comandi di modifica dei dati.

Per l'esempio del sito web di vendita al dettaglio, puoi implementare la sicurezza a livello di riga per Jack e Alice in modo che ogni utente possa accedere solo alle proprie informazioni personali.

--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

Gli utenti assegnati a ruoli con l'attributo BYPASSRLS possono ignorare la sicurezza a livello di riga quando accedono a una tabella. I proprietari delle tabelle possono anche ignorare la sicurezza a livello di riga. Se vuoi sottoporre un proprietario di una tabella alla sicurezza a livello di riga, utilizza il comando ALTER TABLE ... FORCE ROW LEVEL SECURITY.

A volte non vuoi applicare la sicurezza a livello di riga alle righe di una tabella del database. Ad esempio, se utilizzi pg_dump per eseguire un backup della tabella, non vuoi che vengano omesse righe dal backup. Per evitare che ciò accada, per l'utente che esegue il backup, imposta il parametro di configurazione row_security su OFF. Se alcune righe vengono filtrate in base alla sicurezza a livello di riga, viene visualizzato un messaggio di errore.

Mascherare e anonimizzare i dati

Oltre a mascherare i dati utilizzando un approccio basato sulla visualizzazione, puoi mascherarli utilizzando l'estensione postgresql_anonymizer. Questa estensione maschera o sostituisce i dati PII o sensibili dal punto di vista commerciale di un database PostgreSQL.

L'utilizzo dell'estensione rispetto a un approccio basato sulla visualizzazione offre i seguenti vantaggi:

  • Hai a disposizione varie funzioni di mascheramento, come sostituzione, randomizzazione, simulazione, pseudonimizzazione, offuscamento parziale, rimescolamento, aggiunta di rumore e generalizzazione.

  • Puoi generare dati mascherati significativi che puoi utilizzare per i test funzionali e il trattamento dati.

  • Puoi utilizzare il Data Definition Language (DDL) di PostgreSQL per dichiarare le regole di mascheramento e specificare la strategia di anonimizzazione all'interno della definizione della tabella.

Installare e configurare l'estensione postgresql_anonymizer

Per utilizzare questa estensione su un'istanza Cloud SQL, completa i seguenti passaggi:

  1. Modifica l'istanza e imposta il flag cloudsql.enable_anon su on. Per informazioni sull'impostazione dei flag e per esaminare i flag supportati per l'estensione, vedi Configurare i flag di database.

  2. Se prevedi di utilizzare le maschere dinamiche e le tabelle che vuoi mascherare non si trovano nello schema public, imposta il flag anon.sourceschema sul nome dello schema che contiene queste tabelle. Per gli esempi in questa pagina, imposta il flag su secure_schema.

  3. Crea l'estensione nel database eseguendo il seguente comando:

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

Dopo aver installato e configurato l'estensione, utilizzala nell'istanza per implementare le strategie di anonimizzazione maschera dinamica, maschera statica e dump anonimo.

Maschera dinamica

Utilizza le maschere dinamiche per definire le regole di mascheramento per utenti specifici. Questi utenti non possono visualizzare i PII. Visualizzano invece dati mascherati. Tutti gli altri utenti vedono i dati non mascherati. Questa opzione è utile negli ambienti di produzione quando non vuoi modificare le informazioni che consentono l'identificazione personale, ma solo nasconderle a determinati utenti.

Per l'esempio del sito web di vendita al dettaglio, puoi implementare maschere dinamiche in modo che l'amministratore possa visualizzare gli indirizzi email e le password non mascherati per Jack e Alice, mentre l'analista possa visualizzare solo i dati mascherati.

--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)';

--Verify that the masked user is configured. The search_path must include
--the mask schema followed by the schema set in the anon.sourceschema flag.

SELECT rolconfig FROM pg_roles WHERE rolname = 'analyst_ro';
              rolconfig
--------------------------------------
 {"search_path=mask, secure_schema"}

--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" (open a new connection; 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 user_details;
 id | name  | age |       email_id         |    password
----+-------+-----+------------------------+-----------------
  1 | jack  |  34 | alisontodd@example.com | 13d249f2cb4127b
  2 | alice |  37 | amanda35@example.com   | 13d249f2cb4127b

--The masked user can't query the source table directly.

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

Quando avvii la maschera dinamica, l'estensione crea una visualizzazione nello schema mask per ogni tabella dello schema impostata dal flag anon.sourceschema. Quando etichetti un ruolo come MASKED, l'estensione esegue le seguenti operazioni:

  • Revoca i privilegi concessi direttamente al ruolo nello schema di origine.
  • Concede al ruolo il privilegio USAGE sullo schema mask e il privilegio SELECT su ogni vista al suo interno, incluse le viste delle tabelle che il ruolo non poteva interrogare in precedenza.
  • Imposta search_path del ruolo sullo schema mask, seguito dallo schema di origine.

L'utente mascherato vede i dati mascherati solo quando esegue una query su una tabella senza specificare il nome dello schema, in modo che il nome venga risolto nella vista nello schema mask. Le query che specificano il nome dello schema, ad esempio SELECT * FROM secure_schema.user_details, ignorano lo schema mask e non vanno a buon fine a causa di un errore di autorizzazione. L'impostazione search_path viene applicata quando l'utente si connette, quindi gli utenti mascherati devono aprire una nuova connessione dopo che hai etichettato il ruolo.

Maschera statica

Utilizza maschere statiche per rimuovere le PII in una tabella, in base ai criteri definiti nelle regole di mascheramento, e sostituire queste informazioni con dati mascherati. Gli utenti non possono recuperare i dati non mascherati. Questa opzione è utile negli ambienti di test quando vuoi modificare i dati PII e non vuoi che nessun utente visualizzi queste informazioni.

Per l'esempio del sito web di vendita al dettaglio, puoi implementare maschere statiche in modo che nessun utente possa visualizzare gli indirizzi email e le password non mascherati di Jack e Alice. Visualizzano invece solo i dati mascherati.

--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 | 13d249f2cb4127b
  2 | alice |  37 | annebenitez@example.com         | 13d249f2cb4127b

Dump anonimo

Utilizza i dump anonimi per esportare i dati mascherati in un file SQL. Per l'esempio di sito web di vendita al dettaglio, puoi creare un file di dump per i dati mascherati contenuti nella tabella user_details.

--Launch pg_dump_anon to apply earlier defined masking rules. pg_dump_anon
--reads the source table directly, so connect as a user that has the SELECT
--privilege on the table and that isn't labeled as MASKED.

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

Criptare i dati

Anche se puoi mascherare le PII, le informazioni vengono archiviate nel database come testo normale. Un amministratore può visualizzare queste informazioni.

Utilizza l'estensione pgcrypto per criptare le PII prima di archiviarle. In questo modo, solo gli utenti che dispongono di una chiave di crittografia valida possono decriptare le informazioni e visualizzarle come testo normale.

L'estensione pgcrypto ha una serie di funzioni hash e encrypt.

Hash

Un hash è una funzione di crittografia unidirezionale in cui ti interessa solo criptare i dati PII. Ciò è utile per memorizzare le password in un formato sottoposto ad hashing e abbinare le password inserite dall'utente a quelle sottoposte ad hashing. Le password sottoposte ad hashing non vengono mai decriptate in testo normale.

Per l'esempio del sito web di vendita al dettaglio, puoi utilizzare l'estensione pgcrypto per eseguire l'hashing della password di Jack prima di memorizzarla nella tabella 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

Cripta

Utilizza una funzione crittografica di crittografia per criptare i dati PII con una chiave. Gli utenti hanno bisogno di questa chiave per decrittografare le informazioni in testo normale. È utile per memorizzare i dati della carta di credito e i dati bancari quando le applicazioni vogliono recuperare i PII in un formato leggibile.

Nell'esempio del sito web di vendita al dettaglio, la password e l'indirizzo email di Jack sono criptati. Gli utenti che dispongono della chiave di crittografia possono decriptare queste informazioni e visualizzarle come testo normale. Per tutti gli altri utenti, viene visualizzato un messaggio di errore.

--"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

Passaggi successivi

Scopri i seguenti controlli aggiuntivi che puoi utilizzare per proteggere le PII da accessi non autorizzati: