La privacy dei dati consiste nel proteggere i 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 le tue PII in modo sicuro. Vuoi assicurarti che queste informazioni vengano elaborate con la massima protezione della privacy, in modo che non siano accessibili inavvertitamente. Ad esempio, se nei tuoi database memorizzi dati di carte di credito o dati sanitari, puoi utilizzare Cloud SQL per nascondere o mascherare le PII agli utenti non privilegiati.
Utilizza le seguenti strategie per proteggere le PII in Cloud SQL:
- Sicurezza a livello di colonna
- Approccio basato sulle visualizzazioni
- Sicurezza a livello di riga
- Maschera e anonimizza i dati
- Cripta i dati
Sicurezza a livello di colonna
La sicurezza a livello di colonna ti consente di limitare chi può 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 le PII per 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 se inserisci SELECT *, viene visualizzato un messaggio di errore. Cloud SQL protegge le PII di Jack e Alice in queste colonne.
Puoi anche utilizzare una singola istruzione GRANT per combinare privilegi diversi.
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 su una tabella, escludendo o mascherando le colonne che vuoi nascondere agli altri utenti e fornendo l'accesso alla vista anziché alla tabella.
L'esempio seguente mostra come utilizzare un approccio basato sulle visualizzazioni per il sito web di vendita al dettaglio per proteggere le 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 vista in modo che il nome rimanga lo stesso della tabella. Con l'approccio basato sulle visualizzazioni, 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 visualizzare 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 visualizzazioni ti consentono di nascondere le PII nelle colonne delle tabelle del database a utenti specifici. Tuttavia, a volte potresti voler 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 degli utenti idonei. Questo procedimento è noto 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 alle 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 PII.
--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 a cui sono assegnati ruoli con l'attributo BYPASSRLS possono bypassare la sicurezza a livello di riga quando accedono a una tabella. I proprietari delle tabelle possono anche bypassare la sicurezza a livello di riga. Se vuoi sottoporre un proprietario della 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 di database. Ad esempio, se utilizzi pg_dump per eseguire il backup della tabella, non vuoi che vengano omesse righe dal backup. Per evitare che ciò accada, imposta il parametro di configurazione row_security su OFF per l'utente che esegue il backup. Se alcune righe vengono filtrate in base alla sicurezza a livello di riga, viene visualizzato un messaggio di errore.
Maschera e anonimizza i dati
Oltre a mascherare i dati utilizzando un approccio basato sulle visualizzazioni, puoi mascherarli utilizzando l'estensione postgresql_anonymizer. Questa estensione maschera o sostituisce le PII o i dati commercialmente sensibili di un database PostgreSQL.
L'utilizzo dell'estensione rispetto a un approccio basato sulle visualizzazioni offre i seguenti vantaggi:
Hai a disposizione varie funzioni di mascheramento, come sostituzione, randomizzazione, falsificazione, pseudonimizzazione, scrambling parziale, shuffling, 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.
Installa e configura l'estensione postgresql_anonymizer
Per utilizzare questa estensione su un'istanza Cloud SQL, segui questi passaggi:
Modifica l'istanza e imposta il flag
cloudsql.enable_anonsuon. Per informazioni sull'impostazione dei flag e per esaminare i flag supportati per l'estensione, consulta Configura i flag di database.Se prevedi di utilizzare le maschere dinamiche e le tabelle che vuoi mascherare non si trovano nello schema
public, imposta il flaganon.sourceschemasul nome dello schema che contiene queste tabelle. Per gli esempi in questa pagina, imposta il flag susecure_schema.Crea l'estensione nel database eseguendo questo 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 le PII. Vedono invece i dati mascherati. Tutti gli altri utenti vedono i dati in chiaro. Questa opzione è utile negli ambienti di produzione quando non vuoi alterare le PII, 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 in chiaro di Jack e Alice, mentre l'analista può 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 il mascheramento dinamico, l'estensione crea una vista nello schema mask per ogni tabella nello schema impostato 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
USAGEsullo schemamaske il privilegioSELECTsu ogni vista al suo interno, incluse le viste delle tabelle su cui il ruolo non poteva eseguire query in precedenza. - Imposta il
search_pathdel ruolo sullo schemamask, 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 con un errore di autorizzazione. L'impostazione search_path viene applicata quando l'utente si connette, pertanto gli utenti mascherati devono aprire una nuova connessione dopo che hai etichettato il ruolo.
Maschera statica
Utilizza le maschere statiche per rimuovere le PII in una tabella, in base ai criteri definiti nelle regole di mascheramento, e sostituisci queste informazioni con dati mascherati. Gli utenti non possono recuperare i dati in chiaro. Questa opzione è utile negli ambienti di test quando vuoi modificare le PII e non vuoi che gli utenti visualizzino 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 in chiaro 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 del 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
Cripta 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 di hashing e crittografia.
Hash
Un hash è una funzione di crittografia unidirezionale in cui l'unico obiettivo è criptare le PII. Questo è utile per archiviare le password in un formato sottoposto ad hashing e abbinare le password inserite dall'utente con 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 di crittografia per criptare le PII con una chiave. Gli utenti hanno quindi bisogno di questa chiave per decrittografare le informazioni in testo normale. Questo è utile per archiviare i dati della carta di credito e i dati bancari quando le applicazioni vogliono recuperare le PII in un formato leggibile.
Nell'esempio del sito web di vendita al dettaglio, la password e l'indirizzo email di Jack sono crittografati. 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 ingiustificati: