資料隱私權策略

資料隱私權是指保護個人識別資訊 (PII) 等資料,避免不應存取這些資料的人員存取。本頁面說明幾種資料隱私權方法,可用於保護 Cloud SQL 中的 PII。

您可以使用 Cloud SQL 安全地儲存 PII。您希望確保這項資訊受到最高等級的隱私權保護,以免在無意間遭到存取。舉例來說,如果您在資料庫中儲存信用卡資訊或健康照護資料,可以使用 Cloud SQL 對沒有權限的使用者隱藏或遮蓋 PII。

請使用下列策略,協助保護 Cloud SQL 中的 PII:

資料欄層級的安全防護機制

資料欄層級安全性可限制哪些使用者能查看資料庫表格中特定資料欄的內容。資料欄層級的權限適用於 INSERTUPDATESELECTREFERENCES 陳述式。

舉例來說,假設您要控管零售網站上兩位使用者 (Jack 和 Alice) 的 PII。

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

如果您在 SELECT 陳述式中加入受限的資料欄,或輸入 SELECT *,系統就會顯示錯誤訊息。Cloud SQL 會保護這些資料欄中 Jack 和 Alice 的 PII。

您也可以使用單一 GRANT 陳述式合併不同權限。

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

以檢視畫面為基礎的方法

您也可以在資料表上建立檢視區塊,排除或遮蓋要對其他使用者隱藏的資料欄,並提供檢視區塊的存取權,而非資料表的存取權,藉此達成資料欄層級的安全性。

以下範例說明如何使用以檢視區塊為基礎的方法,保護 Jack 和 Alice 的零售網站 PII:

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

在本例中,系統會為檢視區塊建立個別的結構定義,讓檢視區塊的名稱與資料表相同。採用以 View 為基礎的方法時,您可以使用 SELECT *

您也可以建立檢視區塊並遮蓋資料庫表格的資料欄,讓沒有權限的使用者無法查看遮蓋的 PII。

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

資料列層級安全性

透過資料欄層級安全防護措施和以檢視畫面為基礎的方法,您可以對特定使用者隱藏資料庫表格資料欄中的 PII。不過,有時您會想篩選這項資料,並授予特定資料列的存取權。這個表格包含 PII,只有符合使用者條件的特定使用者才能存取。這就是所謂的資料列層級安全性

對於多租戶應用程式而言,列層級安全性非常實用,因為使用者只能讀取和寫入自己的 PII。在 Cloud SQL 中,資料表可以設有資料列層級的安全防護政策,根據使用者限制可透過建立查詢檢視的資料列,或可透過執行資料修改指令插入、更新或刪除的資料列。

以零售網站為例,您可以為 Jack 和 Alice 實作資料列層級安全性,讓他們可以查看自己的 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

如果使用者獲派的角色具有 BYPASSRLS 屬性,存取資料表時即可略過資料列層級安全防護機制。資料表擁有者也可以略過資料列層級安全防護機制。如要對表格擁有者套用資料列層級安全性,請使用 ALTER TABLE ... FORCE ROW LEVEL SECURITY 指令。

有時您可能不想對資料庫表格的資料列套用資料列層級安全防護機制,舉例來說,如果您使用 pg_dump 備份資料表,就不希望備份作業省略任何資料列。如要避免發生這種情況,請為執行備份的使用者將 row_security 設定參數設為 OFF。如果系統根據資料列層級安全性篩選任何資料列,就會顯示錯誤訊息。

遮蓋及去識別化資料

除了使用以檢視畫面為基礎的方法遮蓋資料,您也可以使用 postgresql_anonymizer 擴充功能遮蓋資料。這項擴充功能會遮蓋或取代 PostgreSQL 資料庫中的 PII 或商業機密資料。

相較於以檢視區塊為基礎的方法,使用擴充功能可享有下列優點:

  • 您可以使用各種遮蓋函式,例如替代、隨機化、偽造、假名化、部分擾亂、隨機排序、加入雜訊和一般化。

  • 您可以產生有意義的遮蓋資料,用於功能測試和資料處理。

  • 您可以使用 PostgreSQL 資料定義語言 (DDL) 宣告遮蓋規則,並在資料表定義中指定匿名化策略。

安裝及設定 postgresql_anonymizer 擴充功能

如要在 Cloud SQL 執行個體上使用這項擴充功能,請完成下列步驟:

  1. 編輯執行個體,然後將 cloudsql.enable_anon flag 設為 on。如要瞭解如何設定旗標,以及查看擴充功能支援的旗標,請參閱「設定資料庫旗標」。

  2. 執行下列指令,在資料庫中建立擴充功能:

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

安裝及設定擴充功能後,即可在執行個體上使用,實作動態遮罩靜態遮罩匿名傾印匿名化策略。

動態遮罩

使用動態遮罩,為特定使用者定義遮罩規則。這些使用者無法查看 PII。而是看到經過遮蓋的資料。其他使用者則會看到未遮蓋的資料。在實際工作環境中,如果您不想變更 PII,但只想對特定使用者隱藏 PII,這項功能就非常實用。

以零售網站為例,您可以導入動態遮蓋,讓管理員查看 Jack 和 Alice 未遮蓋的電子郵件地址和密碼,但分析師只能查看遮蓋的資料。

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

靜態遮罩

根據遮蓋規則中定義的條件,使用靜態遮蓋移除表格中的 PII,並以遮蓋資料取代這項資訊。使用者無法擷取未遮蓋的資料。如果您想在測試環境中變更 PII,且不希望任何使用者查看這項資訊,這項功能就非常實用。

以零售網站為例,您可以實作靜態遮蓋,這樣一來,任何使用者都無法查看 Jack 和 Alice 未遮蓋的電子郵件地址和密碼。而是只會看到遮蓋的資料。

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

匿名傾印

使用匿名傾印將遮蓋的資料匯出至 SQL 檔案。以零售網站為例,您可以為 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

加密資料

雖然您可以遮蓋 PII,但資訊會以純文字形式儲存在資料庫中。管理員可以查看這項資訊。

使用 pgcrypto 擴充功能加密 PII,再儲存。這樣一來,只有擁有有效加密金鑰的使用者才能解密資訊,並以純文字格式查看。

pgcrypto 擴充功能具有多個 hashencrypt 函式。

雜湊

雜湊是一種單向密碼編譯函式,您只需要加密 PII。這項功能可將密碼儲存為雜湊格式,並比對使用者輸入的密碼與雜湊密碼。系統絕不會以純文字解密雜湊密碼。

以零售網站為例,您可以使用 pgcrypto 擴充功能,在將 Jack 的密碼儲存在 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

加密

使用加密加密編譯函式,以金鑰加密 PII。使用者必須有這個金鑰,才能將資訊解密為純文字。如果應用程式要以可讀取的格式擷取 PII,這項功能就非常實用,可儲存信用卡資訊和銀行詳細資料。

以零售網站為例,Jack 的密碼和電子郵件地址會經過加密。擁有加密金鑰的使用者可以解密這項資訊,並以純文字形式查看。其他使用者則會看到錯誤訊息。

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

後續步驟

瞭解下列額外控制項,保護 PII 免於未經授權的存取: