TerraformでSnowflakeタグベースのマスキングを実装する
こんにちは! @koonagiです。
いきなりですが、Snowflakeのマスキング機能とても便利ですよね
個人情報を保護しながら、安全に分析業務を行うことができるので最近弊社でも導入を始めました。
導入に当たってTerraformを使ってマスキング機能に必要なリソースを作成してみたので、今回はそのことについて書いていこうと思います。
マスキングポリシー
Snowflakeの列レベルのマスキング機能がダイナミックマスキングになります。ダイナミックマスキングをどのオブジェクトに適用するかどうかのポリシーがマスキングポリシーです。
マスキングポリシーは、 特定のロールに対して、カラムの中身を見せる/見せないの制御ができます。
例えば以下の例だと、
・カラムの閲覧権限がある SUPPORTロール: PHONEとSSNカラムの中身が見える
・カラムの閲覧権限がない ANALYSTロール: PHONEとSSNカラムの中身がフィルタされる
みたいな制御ができます。
マスキングポリシーの実態はこんな感じ。マスキングは任意の文字にすることもできますし、ハッシュ関数を使ってハッシュ化もできます。
CREATE MASKING POLICY employee_ssn_mask AS (val string) RETURNS string ->
CASE
WHEN CURRENT_ROLE() IN ('SUPPORT') THEN val
ELSE '******'
END;
ちなみに、マスキングポリシーは、Enterprise以上のエディションでないと利用できないので注意してください。
機能/エディションのマトリックス
サポートから申請したら数時間で変更してくれました。
タグベースのマスキングポリシー
マスキングポリシーは主にテーブルやカラム、タグに適用することができます。その中でタグに適用しているものをタグベースのマスキングポリシーと良います。
タグもテーブルや列につけることができるのですが、特定のタグがついていると合わせてマスキングポリシーも適用されるようになります。
■ カラムにタグベースのマスキングポリシーを適用した例
マスキングポリシーを直接テーブルやカラムにアタッチするのと比べて、タグベースの利点
- 新規にテーブルやカラムを増やした場合でもタグを付与するだけでマスキングポリシーを適用できる
- テーブルにタグを付与している場合は、マスキングポリシーのデータ型が一致している全てのカラムに自動でタグ付けとマスキングポリシーが適用される
運用が楽になりますね!
テーブルにタグベースのマスキングポリシーをアタッチする際は意図しないカラムにマスキングポリシーができようされないか注意は必要です。弊社ではカラムに対してタグをアタッチするようにしています。
Terraformでのタグベースのマスキングを実装
実装に必要な対応は以下の4項目です。各項目をTerraformを使って実装していきます。
① マスキングポリシー用のタグ作成
② マスキングポリシー作成
③ マスキングポリシーとタグの紐付け
④ カラムにタグ付与
①マスキングポリシー用のタグ作成
タグ名は任意ですが、システムタグにはマスキングポリシーがアタッチできないので注意してください。
resource "snowflake_tag" "tag_privacy_info" {
provider = snowflake.sys_admin
name = "privacy_info" //任意のタグ名
database = snowflake_database.db_name.name
schema = snowflake_schema.schema_name.name
allowed_values = ["true","false"]
}
②マスキングポリシー作成
マスキングポリシーで許可するロールも変数化しておくと、データ型ごとにマスキングポリシー定義する際に再利用できるのでおすすめです。
resource "snowflake_masking_policy" "common_varchar_sha_masking_policy" {
provider = snowflake.sys_admin
name = "COMMON_MASKING_POLICY"
database = snowflake_database.db_name.name
schema = snowflake_schema.schema_name.name
signature {
column {
name = "val"
type = "VARCHAR"
}
}
masking_expression = <<-EOF
case
when current_role() in (${join(",", formatlist("'%s'", var.privacy_info_default_allowed_roles))}) then
val
else
sha2(val)
end
EOF
return_data_type = "VARCHAR"
}
variable "privacy_info_default_allowed_roles" {
description = "デフォルトで個人情報にアクセスできるロール一覧"
type = list(string)
default = ["SYSADMIN", "SECURITYADMIN","XXXXROLE"]
}
③マスキングポリシーとタグの紐付け
resource "snowflake_tag_masking_policy_association" "common_varchar_sha_masking_policy" {
provider = snowflake.sys_admin
tag_id = snowflake_tag.tag_privacy_info.id
masking_policy_id = snowflake_masking_policy.common_varchar_sha_masking_policy.id
}
④カラムにタグを付与
for_each使うことで、複数カラムへのタグの適用を一つの宣言でできるようにしています。
resource "snowflake_tag_association" "table_association" {
for_each = toset(
["NAME", "EMAIL"],
)
provider = snowflake.sys_admin
object_identifier {
name = "${snowflake_table.table_name.name}.${each.value}"
database = snowflake_database.db_name.name
schema = snowflake_schema.schema_name.name
}
object_type = "COLUMN"
tag_id = snowflake_tag.tag_privacy_info.id
tag_value = "true"
}
カラム以外に付与する場合は以下のドキュメント参考にしてください!
適用チェック
タグベースのマスキングポリシー設定が完了すること、Snowsight上でもアタッチされたタグとポリシーが見えるようになります!
最後に
TerraformでSnowflakeタグベースのマスキングポリシーの設定をやってみましたが、かなり簡単に設定できるのでぜひ試してみてください。セキュリティに配慮しながら、安心して分析できる環境を作っていけると思います!
余談
カラムにタグをつけるやり方がドキュメントに書いてなくて、コード見ないとわからなかったので、試しにPR出してみたらapprovedされて嬉しい..!
Discussion