Datenschutzstrategien

Der Datenschutz schützt Daten wie personenidentifizierbare Informationen vor denjenigen, die keinen Zugriff darauf haben sollten. Auf dieser Seite werden verschiedene Ansätze zum Datenschutz beschrieben, mit denen Sie Ihre personenidentifizierbaren informationen in Cloud SQL schützen können.

Sie können Ihre personenidentifizierbaren Informationen mit Cloud SQL sicher speichern. Die Informationen müssen mit höchstem Datenschutz verarbeitet werden, damit sie nicht versehentlich zugänglich gemacht werden. Wenn Sie beispielsweise Kreditkartendaten oder Gesundheitsdaten in Ihren Datenbanken speichern, können Sie personenidentifizierbarer Informationen mit Cloud SQL für nicht privilegierte Nutzer ausblenden oder maskieren.

Verwenden Sie die folgenden Strategien, um Ihre personenidentifizierbaren Informationen in Cloud SQL zu schützen:

Sicherheit auf Spaltenebene

Mit der Sicherheit auf Spaltenebene können Sie einschränken, wer den Inhalt in bestimmten Spalten von Datenbanktabellen sehen kann. Berechtigungen auf Spaltenebene gelten für die Anweisungen INSERT, UPDATE, SELECT und REFERENCES.

Nehmen wir als Beispiel eine Einzelhandels-Website, auf der Sie personenidentifizierbare Informationen für zwei Nutzer verwalten möchten: Jack und 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

Wenn Sie die eingeschränkten Spalten in die SELECT-Anweisung aufnehmen oder SELECT * eingeben, wird eine Fehlermeldung angezeigt. Cloud SQL schützt die personenidentifizierbaren Informationen für Jack und Alice in diesen Spalten.

Sie können auch eine einzelne GRANT-Anweisung verwenden, um verschiedene Berechtigungen zu kombinieren.

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

Ansichtsbasierter Ansatz

Sie können auch die Sicherheit auf Spaltenebene erreichen. Erstellen Sie dazu eine Ansicht für eine Tabelle, schließen Sie Spalten aus, die Sie für andere Nutzer ausblenden möchten, oder maskieren Sie den Zugriff auf die Ansicht anstelle der Tabelle.

Das folgende Beispiel zeigt, wie ein auf Ansichten basierender Ansatz für die Einzelhandelswebsite verwendet wird, um die personenidentifizierbaren Informationen für Jack und Alice zu sichern:

--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 diesem Beispiel wird ein separates Schema für die Ansicht erstellt, um den Namen der Tabelle beizubehalten. Beim Ansichtsbasierten Ansatz können Sie SELECT * verwenden.

Außerdem haben Sie die Möglichkeit, eine Ansicht zu erstellen und die Spalten der Datenbanktabelle zu maskieren, damit nicht privilegierte Nutzer die maskierten personenidentifizierbaren Informationen nicht sehen.

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

Sicherheit auf Zeilenebene

Mit der Sicherheit auf Spaltenebene und einem auf Ansichten basierenden Ansatz können Sie personenidentifizierbare Informationen in Spalten von Datenbanktabellen für bestimmte Nutzer ausblenden. Manchmal möchten Sie diese Daten jedoch filtern und Zugriff auf bestimmte Zeilen einer Tabelle gewähren. Die Tabelle enthält die personenidentifizierbaren Informationen, auf die nur bestimmte Nutzer zugreifen können, basierend auf bestimmten Nutzerbedingungen. Dies wird als Sicherheit auf Zeilenebene bezeichnet.

Die Sicherheit auf Zeilenebene ist nützlich für mehrmandantenfähige Anwendungen, bei denen Nutzer nur Lese- und Schreibzugriff auf ihre eigenen personenidentifizierbaren Informationen haben. In Cloud SQL können Tabellen Sicherheitsrichtlinien auf Zeilenebene haben, die auf einer nutzerspezifischen Basis einschränken, welche Zeilen Nutzer durch Erstellen von Abfragen anzeigen können, oder durch die Zeilen, die Nutzer einfügen, aktualisieren oder löschen können, indem sie Befehle zur Datenänderung ausführen.

Für das Beispiel auf der Einzelhandelswebsite können Sie die Sicherheit auf Zeilenebene für Jack und Alice implementieren, damit sie ihre eigenen personenidentifizierbaren Informationen sehen, aber nicht ändern oder löschen können.

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

Nutzer, denen Rollen mit dem Attribut BYPASSRLS zugewiesen sind, können die Sicherheit auf Zeilenebene umgehen, wenn sie auf eine Tabelle zugreifen. Tabelleninhaber können die Sicherheit auf Zeilenebene auch umgehen. Wenn Sie einem Tabelleninhaber die Sicherheit auf Zeilenebene gewähren möchten, verwenden Sie den Befehl ALTER TABLE ... FORCE ROW LEVEL SECURITY.

Manchmal möchten Sie die Sicherheit auf Zeilenebene nicht auf die Zeilen einer Datenbanktabelle anwenden. Wenn Sie beispielsweise pg_dump verwenden, um eine Sicherung der Tabelle zu erstellen, möchten Sie nicht, dass Zeilen aus der Sicherung ausgelassen werden. Um dies zu verhindern, setzen Sie für den Nutzer, der die Sicherung erstellt, den Konfigurationsparameter row_security auf OFF. Wenn Zeilen basierend auf der Sicherheit auf Zeilenebene gefiltert werden, wird eine Fehlermeldung angezeigt.

Daten maskieren und anonymisieren

Neben dem Maskieren von Daten mithilfe eines ansichtsbasierten Ansatzes können Sie Daten mit der Erweiterung postgresql_anonymizer maskieren. Mit dieser Erweiterung werden personenidentifizierbare Informationen oder sensible kommerzielle Daten aus einer PostgreSQL-Datenbank maskiert oder ersetzt.

Die Verwendung der Erweiterung gegenüber einem ansichtsbasierten Ansatz bietet folgende Vorteile:

  • Sie haben verschiedene Maskierungsfunktionen wie Substitution, Zufallsgenerierung, Pseudonymisierung, Teil-Scrambling, Shuffling, Rauschen-Hinzufügen und Generalisierung.

  • Sie können aussagekräftige maskierte Daten generieren, die Sie für Funktionstests und die Datenverarbeitung verwenden können.

  • Sie können mit der PostgreSQL-Datendefinitionssprache (DDL) Maskierungsregeln deklarieren und die Anonymisierungsstrategie in der Tabellendefinition angeben.

postgresql_anonymizer-Erweiterung installieren und konfigurieren

Führen Sie die folgenden Schritte aus, um diese Erweiterung für eine Cloud SQL-Instanz zu verwenden:

  1. Bearbeiten Sie die Instanz und legen Sie dann cloudsql.enable_anon flag auf on fest. Informationen zum Festlegen von Flags und zum Prüfen der für die Erweiterung unterstützten Flags finden Sie unter Datenbank-Flags konfigurieren.

  2. Erstellen Sie die Erweiterung in der Datenbank, indem Sie den folgenden Befehl ausführen:

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

Nachdem Sie die Erweiterung installiert und konfiguriert haben, können Sie sie auf der Instanz verwenden, um Strategien für die dynamische Maskierung, die statische Maske und die anonyme Dumpdatei zu implementieren.

Dynamische Maske

Verwenden Sie dynamische Masken, um Maskierungsregeln für bestimmte Nutzer zu definieren. Diese Nutzer können keine personenidentifizierbaren Informationen sehen. Stattdessen sehen sie maskierte Daten. Alle anderen Nutzer sehen die nicht maskierten Daten. Dies ist in Produktionsumgebungen nützlich, wenn Sie die personenidentifizierbaren Informationen nicht ändern, sondern nur für bestimmte Nutzer ausblenden möchten.

Für das Beispiel der Einzelhandelswebsite können Sie dynamische Masken implementieren, damit der Administrator die nicht maskierten E-Mail-Adressen und Passwörter für Jack und Alice sehen kann, aber der Analyst nur maskierte Daten anzeigt.

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

Statische Maske

Verwenden Sie statische Masken, um die personenidentifizierbaren Informationen gemäß den in den Maskierungsregeln definierten Kriterien aus einer Tabelle zu entfernen, und ersetzen Sie diese Informationen durch maskierte Daten. Nutzer können die nicht maskierten Daten nicht abrufen. Dies ist in Testumgebungen nützlich, wenn Sie die personenidentifizierbaren Informationen ändern und Nutzern die Informationen nicht ansehen möchten.

Für das Beispiel der Einzelhandelswebsite können Sie statische Masken implementieren, damit keine Nutzer die maskierten E-Mail-Adressen und Passwörter für Jack und Alice sehen können. Stattdessen werden nur maskierte Daten angezeigt.

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

Anonymer Dump

Anonyme Dumps verwenden, um maskierte Daten in eine SQL-Datei zu exportieren. Für das Beispiel auf der Retail-Website können Sie eine Dumpdatei für die maskierten Daten erstellen, die in der Tabelle user_details enthalten sind.

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

Daten verschlüsseln

Sie können personenidentifizierbare Informationen maskieren. Die Informationen werden jedoch als Nur-Text in der Datenbank gespeichert. Ein Administrator kann diese Informationen sehen.

Verwenden Sie die Erweiterung pgcrypto, um die personenidentifizierbaren Informationen zu verschlüsseln, bevor Sie sie speichern. Dadurch können nur Nutzer mit einem gültigen Verschlüsselungsschlüssel die Informationen entschlüsseln und als Nur-Text ansehen.

Die pgcrypto-Erweiterung bietet mehrere Hash- und Verschlüsselungsfunktionen.

Hash

Ein Hash ist eine kryptografische Funktion, die nur für die Verschlüsselung personenidentifizierbarer Informationen relevant ist. Dies ist nützlich, um Passwörter in einem gehashten Format zu speichern und die vom Nutzer eingegebenen Passwörter mit den gehashten Passwörtern zu vergleichen. Hash-Passwörter werden niemals im Nur-Text-Format entschlüsselt.

Für das Beispiel für die Einzelhandelswebsite können Sie das Passwort von Jack mit der Erweiterung pgcrypto hashen, bevor Sie es in der Tabelle user_details speichern.

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

Verschlüsseln

Verwenden Sie eine kryptografische Verschlüsselungsfunktion, um personenidentifizierbare Informationen mit einem Schlüssel zu verschlüsseln. Nutzer benötigen diesen Schlüssel dann, um die Informationen in Klartext zu entschlüsseln. Dies ist nützlich, um Kreditkartendaten und Bankdaten zu speichern, in denen Anwendungen personenidentifizierbare Informationen in lesbarer Form abrufen möchten.

Für das Beispiel der Einzelhandelswebsite sind Jass Passwort und die E-Mail-Adresse verschlüsselt. Nutzer, die den Verschlüsselungsschlüssel haben, können diese Informationen entschlüsseln und als reinen Text ansehen. Für alle anderen Nutzer wird eine Fehlermeldung angezeigt.

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

Wie geht es weiter?

Informieren Sie sich über die folgenden zusätzlichen Funktionen, mit denen Sie personenidentifizierbare Informationen vor unbefugtem Zugriff schützen können: