⛷️

TerraformでSnowflakeタグベースのマスキングを実装する

2024/02/29に公開

こんにちは! @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"] 
}

https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/tag

②マスキングポリシー作成

マスキングポリシーで許可するロールも変数化しておくと、データ型ごとにマスキングポリシー定義する際に再利用できるのでおすすめです。

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

https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/masking_policy

③マスキングポリシーとタグの紐付け

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
}

https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/tag_masking_policy_association

④カラムにタグを付与

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

カラム以外に付与する場合は以下のドキュメント参考にしてください!
https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/tag_association

適用チェック

タグベースのマスキングポリシー設定が完了すること、Snowsight上でもアタッチされたタグとポリシーが見えるようになります!

最後に

TerraformでSnowflakeタグベースのマスキングポリシーの設定をやってみましたが、かなり簡単に設定できるのでぜひ試してみてください。セキュリティに配慮しながら、安心して分析できる環境を作っていけると思います!

余談

カラムにタグをつけるやり方がドキュメントに書いてなくて、コード見ないとわからなかったので、試しにPR出してみたらapprovedされて嬉しい..!
https://github.com/Snowflake-Labs/terraform-provider-snowflake/pull/2565

スタフェステックブログ

Discussion