🔑

Snowflake の SAML 認証を AWS IAM Identity Center で構築する

2024/07/25に公開
2

AWS IAM Identity Center (旧 AWS SSO) を使用して、Snowflake 環境へのアクセスに SAML 認証オプションを追加する方法について検証してみたので、備忘も兼ねてその設定手順について記してみたいと思います。

前提

  • 管理アカウントにて IAM Identity Center が有効化され、組織インスタンスが存在すること
  • AWS 環境・Snowflake 環境とも、実施に必要な権限を有していること

IAM Identity Center アプリケーションの構築

ID プロバイダ (IdP) となる IAM Identity Center アプリケーションを構築していきます。

アプリケーションの作成

IAM Identity Center のサービス画面を開き、左メニューから Application assignments - Applications に遷移して [Add application] ボタンを押下します。

"Select application type" 画面にて「カタログから選択」を選択し、Snowflake アプリケーションを検索・選択して [Next] を押下します。

次の "Configure application" 画面にて、下記の項目を入力します。

Configure application

設定項目 設定値
Display name (例) Snowflake - demo_standard
Description (例) Snowflake Application for the account "demo_standard"

Application properties

設定項目 設定値
Application start URL -
Relay state -

Application metadata

設定項目 設定値
Application ACS URL https://myorg-demo_standard.snowflakecomputing.com/fed/login
Application SAML audience https://myorg-demo_standard.snowflakecomputing.com

IdP 証明書ファイルのダウンロード (a)

後述する Snowflake 側の SAML 統合設定で必要となる証明書ファイルをダウンロードしておきます。IAM Identity Center Certificate[Download] ボタンよりダウンロードできます。

SAML アサーション URL の確認 (b)

同様に、SAML 統合設定で必要となる SAML アサーション URL について確認します。メタデータセクションの以下に記載されている URL を確認します。

  • IAM Identity Center sign-in URL
  • IAM Identity Center SAML issuer URL

URL はいずれも以下のような形式になっています。

https://portal.sso.ap-northeast-1.amazonaws.com/saml/assertion/XXXX...XXXX

属性マッピングの確認

カタログからアプリケーションを作成した場合、属性マッピングの情報は事前に設定されています。アプリケーション詳細画面の [Actions] - [Edit attribute mappings] で内容を確認することができます。

デフォルトで、ログイン名としてメールアドレス形式を想定した設定になっています。ID がメールアドレスであれば特に変更する必要はありません。

ユーザー・グループへのアクセス権限の割り当て

アプリケーション詳細画面の [Assign users and groups] ボタンより、Snowflake アカウントへのアクセスを許可する IAM Identity Center ユーザー、またはグループを割り当てます。

Snowflake SAML 統合の設定

続いて、サービスプロバイダ (SP) である Snowflake 側にて、SAML 統合の設定をしていきます。
公式ドキュメント [1] には SQL で設定する方法が記載されていますが、本記事では Terraform で作成していきたいと思います。

Terraform モジュールの呼び出しには、以前の記事でご紹介した Terragrunt を使用します。

https://zenn.dev/simpleform_blog/articles/20240701-multi-account-snowflake-with-terragrunt

Terraform モジュール

Terraform モジュールを以下のように定義します。

variables.tf
variable "account_identifier" {
  type = string
}
variable "saml2_x509_cert" {
  type      = string
  sensitive = true
}
variable "config" {
  type = object({
    saml2_issuer  = string
    saml2_sso_url = string
    # Optional Fields
    saml2_enable_sp_initiated = optional(bool, null)
    saml2_force_authn         = optional(bool, null)
  })
}
main.tf
resource "snowflake_saml2_integration" "default" {
  name = upper("saml2_integration")

  saml2_provider  = "CUSTOM"
  saml2_issuer    = var.config.saml2_issuer
  saml2_sso_url   = var.config.saml2_sso_url
  saml2_x509_cert = var.saml2_x509_cert

  # Optional Fields
  enabled                       = true
  saml2_enable_sp_initiated     = var.config.saml2_enable_sp_initiated
  saml2_force_authn             = var.config.saml2_force_authn
  saml2_requested_nameid_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
  saml2_snowflake_acs_url       = "https://${var.account_identifier}.snowflakecomputing.com/fed/login"
  saml2_snowflake_issuer_url    = "https://${var.account_identifier}.snowflakecomputing.com"
}

モジュール呼び出し用 terragrunt.hcl

モジュール呼び出し用の terragrunt.hcl ファイルは以下の通りです。

  • saml2_x509_cert には、(a) で確認した証明書ファイルの内容を設定します。ヘッダー行・フッター行を除く全ての文字列を、改行を除いた1行の文字列として渡す必要があるため、locals ブロックでそのような変換処理を行なっています。
  • config.saml2_sso_url, config.saml2_issuer には、(b) で確認した SAML アサーション URL を設定します。
terragrunt.hcl
include "root" {
  path = find_in_parent_folders()
}

locals {
  common_vars  = yamldecode(file(find_in_parent_folders("common_vars.yaml")))
  account_vars = yamldecode(file(find_in_parent_folders("account_vars.yaml")))

  org     = local.common_vars.org
  account = local.account_vars.account
  usage   = "default"

  # create cert_body_single_line
  cert_content          = file("./saml2_x509_certs/snowflake-${local.account.name}.pem")
  cert_lines            = split("\n", local.cert_content)
  cert_body_lines       = slice(local.cert_lines, 1, length(local.cert_lines) - 1)
  cert_body_string      = join("", local.cert_body_lines)
  cert_body_single_line = replace(local.cert_body_string, "\n", "")
}

terraform {
  source = "${dirname(find_in_parent_folders())}/modules/${local.account.type}/saml_integration//${local.usage}/"
}

inputs = {
  account_identifier = "${local.org}-${local.account.name}"
  saml2_x509_cert    = local.cert_body_single_line

  config = {
    saml2_force_authn         = true
    saml2_enable_sp_initiated = true
    # SAML Assertion URL
    saml2_sso_url = "https://portal.sso.ap-northeast-1.amazonaws.com/saml/assertion/XXXX...XXXX"
    saml2_issuer  = "https://portal.sso.ap-northeast-1.amazonaws.com/saml/assertion/XXXX...XXXX"
  }
}

Apply が完了すると、Snowflake 上で SAML 統合設定の内容を確認することができます。

動作確認

SAML 統合が設定されるとログイン画面に「シングルサインオン」が表示されるます。
正しく設定されていれば、IdP 側での認証後に Snowflake 環境にアクセスできます。

さいごに

IdP が AWS IAM Identity Center である場合を想定した、Snowflake 環境へのアクセスに SAML 認証オプションを追加する方法について書いてみました。

SAML 統合を設定するだけでは、パスワード認証が引き続き利用可能な状態になっているため、これを禁止する場合には 認証ポリシー を設定する必要があるようです。以下の記事などを参考にさせて頂きつつ、当社でも早めにポリシー要件を定めて実装していければと考えています。

https://tech.layerx.co.jp/entry/dont-use-passwords-in-your-snowflake-account

最後まで読んで頂き、ありがとうございました。

脚注
  1. フェデレーション認証を使用するための Snowflake の構成 - Snowflake Documentation ↩︎

SimpleForm Tech Blog

Discussion

jimatomojimatomo

参考になりました!ありがとうございます。
2点ほど参考までに私の環境で試してみたところの共有です。

  • snowflake_saml2_integration版でも同じ設定で動きましたので、これから作る新しく作る人はsnowflake_saml2_integrationに書き換えるだけで問題なさそうです(Provider 0.94.1 で検証)
  • AWS IAM Identity Centerのポータル側からログインする場合には「Application start URL」を未入力のままにしておかないとエラー(Error Method Not Allowed)になったので、空欄にしておいたままの方がいいかもしれないです。(私の環境だけかもしれないですが...)
Hiroki Yamagishi / 山岸 裕樹Hiroki Yamagishi / 山岸 裕樹

@jimatomo さん、コメントありがとうございます!

  • 筆者環境でもこれを機に 0.94.1 にアップグレードし、snowflake_saml2_integration のリソースに置き換えてみました。動作確認できましたので、記事の方も更新いたしました。
  • Application start URL についても、確かに元記事のように入力していると AWS Identity Center 側からのログインができず、空にしたところログインできるようになりました。(Snowflake URL からの直接ログインしか試していなかったので気付きませんでした。ご指摘頂きありがとうございます 🙇‍♂️)