Amazon Redshift は、SUPER タイプ列のパスへの動的データマスキングポリシーのアタッチをサポートしています。SUPER データ型の詳細については、Amazon Redshift の半構造化データを参照してください。
SUPER タイプ列のパスにマスキングポリシーをアタッチするときは、次の点を考慮します。
-
マスキングポリシーを列のパスにアタッチする場合、その列を SUPER データタイプとして定義する必要があります。マスキングポリシーは SUPER パスのスカラー値にのみ適用できます。複雑な構造や配列にはマスキングポリシーを適用できません。
-
SUPER パスが競合しない限り、1 つの SUPER 列の複数のスカラー値に異なるマスキングポリシーを適用できます。例えば、スーパーパス
a.b
とa.b.c
が競合するのは、それらが同じパス上にあるときに、a.b
がa.b.c
の親になっているためです。スーパーパスa.b.c
とa.b.d
は競合しません。 -
Amazon Redshift で、マスキングポリシーがアタッチするパスがデータに存在して、想定されるタイプであることを確認するには、ユーザーのクエリランタイム時にポリシーが適用される必要があります。例えば、INT 値を含む SUPER パスに TEXT 値をマスキングするマスキングポリシーをアタッチすると、Amazon Redshift はパスで値のタイプをキャストしようとします。
このような状況では、ランタイム時の Amazon Redshift の動作は、SUPER オブジェクトをクエリするための設定によって異なってきます。デフォルトでは、Amazon Redshift は lax モードになっており、指定した SUPER パスに関して欠落したパスや無効なキャストを
NULL
として解決します。SUPER 関連の設定の詳細については、「SUPER 設定」を参照してください。 -
SUPER はスキーマレスタイプです。つまり、Amazon Redshift は特定の SUPER パスに値が存在することを確認できません。存在しない SUPER パスにマスキングポリシーをアタッチし、Amazon Redshift が lax モードの場合、Amazon Redshift はパスを
NULL
値に解決します。SUPER 列のパスにマスキングポリシーをアタッチするときは、SUPER オブジェクトの予想される形式と、それらに予期しない属性が含まれる可能性を考慮することをお勧めします。SUPER 列に予期しないスキーマがあると思われる場合は、マスキングポリシーを SUPER 列に直接アタッチすることを検討します。SUPER タイプ情報関数を使用して属性とタイプをチェックしたり、OBJECT_TRANSFORM
を使用して値をマスクしたりできます。SUPER タイプ情報関数の詳細については、「SUPER 型の情報関数」を参照してください。
例
SUPER パスにマスキングポリシーをアタッチする
次の例では、1 列の複数の SUPER タイプパスに複数のマスキングポリシーをアタッチします。
CREATE TABLE employees (
col_person SUPER
);
INSERT INTO employees
VALUES
(
json_parse('
{
"name": {
"first": "John",
"last": "Doe"
},
"age": 25,
"ssn": "111-22-3333",
"company": "Company Inc."
}
')
),
(
json_parse('
{
"name": {
"first": "Jane",
"last": "Appleseed"
},
"age": 34,
"ssn": "444-55-7777",
"company": "Organization Org."
}
')
)
;
GRANT ALL ON ALL TABLES IN SCHEMA "public" TO PUBLIC;
-- Create the masking policies.
-- This policy converts the given name to all uppercase letters.
CREATE MASKING POLICY mask_first_name
WITH(first_name TEXT)
USING ( UPPER(first_name) );
-- This policy replaces the given name with the fixed string 'XXXX'.
CREATE MASKING POLICY mask_last_name
WITH(last_name TEXT)
USING ( 'XXXX'::TEXT );
-- This policy rounds down the given age to the nearest 10.
CREATE MASKING POLICY mask_age
WITH(age INT)
USING ( (FLOOR(age::FLOAT / 10) * 10)::INT );
-- This policy converts the first five digits of the given SSN to 'XXX-XX'.
CREATE MASKING POLICY mask_ssn
WITH(ssn TEXT)
USING ( 'XXX-XX-'::TEXT || SUBSTRING(ssn::TEXT FROM 8 FOR 4) );
-- Attach the masking policies to the employees table.
ATTACH MASKING POLICY mask_first_name
ON employees(col_person.name.first)
TO PUBLIC;
ATTACH MASKING POLICY mask_last_name
ON employees(col_person.name.last)
TO PUBLIC;
ATTACH MASKING POLICY mask_age
ON employees(col_person.age)
TO PUBLIC;
ATTACH MASKING POLICY mask_ssn
ON employees(col_person.ssn)
TO PUBLIC;
-- Verify that your masking policies are attached.
SELECT
policy_name,
TABLE_NAME,
priority,
input_columns,
output_columns
FROM
svv_attached_masking_policy;
policy_name | table_name | priority | input_columns | output_columns
-----------------+------------+----------+-----------------------------------+-----------------------------------
mask_age | employees | 0 | ["col_person.\"age\""] | ["col_person.\"age\""]
mask_first_name | employees | 0 | ["col_person.\"name\".\"first\""] | ["col_person.\"name\".\"first\""]
mask_last_name | employees | 0 | ["col_person.\"name\".\"last\""] | ["col_person.\"name\".\"last\""]
mask_ssn | employees | 0 | ["col_person.\"ssn\""] | ["col_person.\"ssn\""]
(4 rows)
-- Observe the masking policies taking effect.
SELECT col_person FROM employees ORDER BY col_person.age;
-- This result is formatted for ease of reading.
col_person
--------------------------------
{
"name": {
"first": "JOHN",
"last": "XXXX"
},
"age": 20,
"ssn": "XXX-XX-3333",
"company": "Company Inc."
}
{
"name": {
"first": "JANE",
"last": "XXXX"
},
"age": 30,
"ssn": "XXX-XX-7777",
"company": "Organization Org."
}
SUPER パスに無効なマスキングポリシーをアタッチする例を以下に示します。
-- This attachment fails because there is already a policy
-- with equal priority attached to employees.name.last, which is
-- on the same SUPER path as employees.name.
ATTACH MASKING POLICY mask_ssn
ON employees(col_person.name)
TO PUBLIC;
ERROR: DDM policy "mask_last_name" is already attached on relation "employees" column "col_person."name"."last"" with same priority
-- Create a masking policy that masks DATETIME objects.
CREATE MASKING POLICY mask_date
WITH(INPUT DATETIME)
USING ( INPUT );
-- This attachment fails because SUPER type columns can't contain DATETIME objects.
ATTACH MASKING POLICY mask_date
ON employees(col_person.company)
TO PUBLIC;
ERROR: cannot attach masking policy for output of type "timestamp without time zone" to column "col_person."company"" of type "super
次に示すのは、存在しないスーパーパスにマスキングポリシーをアタッチする例です。デフォルトでは、Amazon Redshift は NULL
へのパスを解決します。
ATTACH MASKING POLICY mask_first_name
ON employees(col_person.not_exists)
TO PUBLIC;
SELECT col_person FROM employees LIMIT 1;
-- This result is formatted for ease of reading.
col_person
-----------------------------------
{
"name": {
"first": "JOHN",
"last": "XXXX"
},
"age": 20,
"ssn": "XXX-XX-3333",
"company": "Company Inc.",
"not_exists": null
}