Snowflake SAML2.0 Security Integrationを使用したSP/IdP Initiated SAML Federationと構成の詳細

AWS IAM Identity Center を IdP として使用し、Snowflake SAML2.0 Security Integration を構成する。
構成の際に多くのパラメタの設定が必要だが、設定可能なパラメタの意味について深掘りしてみる。
この記事は自分の学び用なので、事実の確認、説明用画像作成のために生成AIを使用するが、
記事の作成、校正には使用しない。

SP起点(SP initiated) flow

SP側にSSOボタンなどを配置して、SSOボタン押下でSSO認証とSPログインを開始するフロー。
SP,User,IdP間の呼び出しシーケンスは下図の通り。


Saml sp initiated

Saml login screenshots flow

IdP起点(IdP initiated) flow

IdP側にログインボタンを配置して、ログインボタン押下でIdP認証とSPログインを開始するフロー。
SP,User,IdP間の呼び出しシーケンスは下図の通り。

Saml idp initiated

Saml idp initiated screenshots flow

ログアウト

SP側のセッションと、IdP側のセッションは独立している。SP起点、IdP起点のいずれにおいても、
基本的には、片方をログアウトしたからといってもう片方が勝手にログアウトしたりしない。
ChromeでSP起点でフェデレーションログインした後、ChromeでSPのセッションをログアウトした場合、
IdP側のセッションはまだ生きているので、Chromeで再度フェデレーションを開始したとき、
IdP側の認証は走らず、SPにログインできる。

ChromeでSP起点でフェデレーションした後、SafariでSP起点でフェデレーションしたとき、
Chromeでログアウトしたとしても、Safariのセッションはログアウトしないため操作を続行できる。

ただし、EntraIDのみ、IdP起点で開始したとき、「グローバルログアウト,シングルログアウト,SLO」が
サポートされており、IdPからログアウトすると、全てのセッションからログアウトする。
たしかに、EntraIDが気持ち悪い動作するな、と言う時、これが動いている時がありそう。

セッションタイムアウト

SP(Snowflake)のセッションがタイムアウトした場合、ユーザはIdPを介して再度認証が必要。
IdPでCancel操作をすると、そこでセッションを終了できる。

IdPのセッションがタイムアウトした場合、Snowflakeセッションに影響しない。
その時点でアクティブなSP(Snowflake)セッションは生きたままとなる。

識別子優先ログイン

組織ごとにそれぞれのIdPとSAML連携したいといった場合がある。複数のintegrationを持てる。
また、ユーザによってはフェデレーション連携させずに、Snowflake認証だけにしたいケースもある。
ユーザによって認証に必要な入力が異なるため、全てのユーザに対して最小公倍数的に入力項目を
出してしまうと、ユーザによって不要な項目が並んでいるように見える。

識別子優先ログインをONにすると、SP(Snowflake)側の認証入力が多段階となる。
つまり、1段階目で識別子(ユーザ名、またはメールアドレス) を入力させ、
入力された識別子がどの認証方式に紐づいているかを判定したのち、
ユーザに適した2段階目の認証入力画面(PW入力、SSOボタン)を表示する。

画面遷移が増えるが、不要な入力項目が現れなくなる。

SAML2.0 Security Integration

これを作るだけでSnowflakeにSAML2.0 Federationを追加できる。


CREATE [ OR REPLACE ] SECURITY INTEGRATION [ IF NOT EXISTS ]
    <name>
    TYPE = SAML2
    ENABLED = { TRUE | FALSE }
    { METADATA_URL = '<string_literal>' | <idp_parameters> }
    [ ALLOWED_USER_DOMAINS = ( '<string_literal>' [ , '<string_literal>' , ... ] ) ]
    [ ALLOWED_EMAIL_PATTERNS = ( '<string_literal>' [ , '<string_literal>' , ... ] ) ]
    [ SAML2_SP_INITIATED_LOGIN_PAGE_LABEL = '<string_literal>' ]
    [ SAML2_ENABLE_SP_INITIATED = TRUE | FALSE ]
    [ SAML2_SNOWFLAKE_X509_CERT = '<string_literal>' ]
    [ SAML2_SIGN_REQUEST = TRUE | FALSE ]
    [ SAML2_REQUESTED_NAMEID_FORMAT = '<string_literal>' ]
    [ SAML2_POST_LOGOUT_REDIRECT_URL = '<string_literal>' ]
    [ SAML2_FORCE_AUTHN = TRUE | FALSE ]
    [ SAML2_SNOWFLAKE_ISSUER_URL = '<string_literal>' ]
    [ SAML2_SNOWFLAKE_ACS_URL = '<string_literal>' ]
    [ COMMENT = '<string_literal>' ]

パラメタの意味を1つずつ解釈していく。

METADATA_URLとidp_parameters

まず、METADATA_URL について、IdPが証明書の更新などのIdP構成設定を動的に
取得・同期できるように、URLを公開している場合がある。
その場合、METADATA_URL に指定することができる。ない場合は idp_parameters を手動で設定する。

idp_parameters として設定できる項目は以下の通り。
SAML2_ISSUER
IdPメタデータの entityID(IdP Entity ID)。IdP(AWS IAM Identity Center)を一意に識別する文字列。Snowflakeはこの値をIdPからの応答(SAML Response)の Issuer と照合し、正規のIdPからの応答かを検証する。
SAML2_SSO_URL
IdPメタデータの SingleSignOnService Location。SP-initiatedログイン時、SnowflakeがブラウザをリダイレクトさせるIdPのログインエンドポイント。
SAML2_PROVIDER
IdPの種別。OKTA、ADFS、Customのいずれか。専用値がないIdP(AWS IAM Identity Centerを含む)はすべて Custom を指定する。
SAML2_X509_CERT
IdPメタデータの X509Certificate。IdPがSAML Responseに付与する署名を検証するための公開鍵証明書。ヘッダー(—–BEGIN CERTIFICATE—–)・フッター・改行を除いたBase64本文のみを指定する。

多層防御

ALLOWED_USER_DOMAINS
SAML2セキュリティ統合で認証できるメールドメインの許可リスト。IdPから返ってきた識別子(login_name/emailとして扱われる値)の @ 以降がこのリストに含まれていないと、SAMLレスポンス自体は正当でも認証を拒否する。IdP設定ミスや、共有IdPで意図しないドメインのユーザーがログインできてしまう事故を防ぐための追加防御層。ただし、NameIDにメールアドレスではなくusernameを使う場合、@domain部分が存在せず、このパラメータで意味のある制限をかけることができない。メールアドレス形式のNameIDに切り替える場合は設定を検討する。
ALLOWED_EMAIL_PATTERNS
SAML2セキュリティ統合で認証するメールアドレスが一致すべき正規表現のリスト。ALLOWED_USER_DOMAINS のドメイン単位の許可リストより柔軟な条件(例: .*@example\.com$ や特定のローカルパートのみ許可など)を指定したい場合に使う。こちらも同様に、NameID(メールアドレス形式ではない)には適用できない。

SP_INITIATED flowの設定

SAML2_SP_INITIATED_LOGIN_PAGE_LABEL
Snowflakeのログイン画面の「Log In With」ボタンの後に表示するラベル文字列。任意の名称でよい。
SAML2_ENABLE_SP_INITIATED
ログインページに「Log In With」ボタンを表示するかどうか。TRUEでSP-initiatedログインが有効になる。FALSEの場合はIdP-initiatedのみ許可。

SAMLメッセージの署名

SAML2_SIGN_REQUEST
SnowflakeがIdPに送るSAMLリクエスト(AuthnRequest)に署名するかどうか。署名させたい場合は TRUE にし、AWS側アプリ設定でリクエスト署名検証を有効化する必要がある。TRUEにするメリット: IdPからSPへの応答(SAMLレスポンス)はSAML2_X509_CERTによる署名検証で既に真正性が保証されているが、逆方向(SPからIdPへのAuthnRequest)は署名なしだと改ざん・なりすましを検知できない。TRUEにすることでIdP側がリクエストの送信元(Snowflake)と内容の完全性を検証できるようになり、偽装されたAuthnRequestでユーザーを不正なフローに誘導される攻撃への耐性が上がる。特にセキュリティ要件が厳しい環境や監査対応が必要な場合はTRUEを推奨。

SAML2_SNOWFLAKE_X509_CERT
指定しない場合Snowflakeが自己署名した証明書が使われるが、SAML2_SNOWFLAKE_X509_CERT により、第三者(CA)による証明書を設定できる。これにより、SPからIdPへのAuthnRequestを第三者(CA)による証明書(の秘密鍵)で署名するようになる。

SPからIdPへのAuthnRequestを署名する限界と価値
そもそも「証明書」とは「公開鍵」+「(誰かの)秘密鍵による発行者の署名」という構造となっている。第三者が署名するといっても、その第三者が何者か、についてはより上位の第三者が署名することで証明される。最終的には、ルートCAと呼ばれるトラストストアに登録されている事前登録済みの発行者に突き当たり、ルートCAは自己署名を行っている。ルートCAは特権的に自己署名が信頼される様子。WebサイトのSSL/TLS証明書と検証は、まさにこの証明書チェーンの検証を行なっている。

SAML連携において、SPとIdPはこうしたチェーン検証を行わず「指定された証明書を信頼する」という形で個別に相手の証明書を事前登録するだけなので、CA発行か自己署名かどうかは実質的にセキュリティ上の差を生まない。例えば次のようなシナリオでCA発行証明書が意味を持つ。

既に証明書の発行・更新・監査の仕組みが既にある場合、Snowflake固有の自己署名証明書を個別管理する対象として放置せず、他のシステムと同じ棚卸し、アラート、更新プロセスに組み込める。「Snowflakeだけの特殊な例外」として管理外になるリスクを排除できる。

ISO27001/SOC2などの監査で「証明書は組織の承認されたCAから発行されたものであること」という統制が求められている場合、自己署名証明書だと指摘対象になり得る。CA発行にしておけば、発行記録・Subject検証済みという裏付けを監査人に示せる。

NameID規格化

SAML2_REQUESTED_NAMEID_FORMAT
SPからIdP方向の AuthnRequest 送信時、「私(SP)はこの形式のNameIDが欲しい」というIdPへのリクエストを送る。このフォーマットを SAML2_REQUESTED_NAMEID_FORMAT で指定する。
一方、IdPからSP方向の SAML Response受信時、Snowflakeが受け取ったNameIDの値をLOGIN_NAMEと文字列比較する処理において、単に文字列として比較されるだけなので、SAML2_REQUESTED_NAMEID_FORMAT に一致していなくて良い。

ログイン・ログアウト時の挙動

SAML2_POST_LOGOUT_REDIRECT_URL
Snowflake Webインターフェースの「Log Out」ボタンをクリックした後にSnowflakeがユーザーをリダイレクトするエンドポイント。未設定の場合はSnowflakeの標準ログイン画面に戻る。IdPのログアウトページや社内ポータルなど任意のURLへ誘導したい場合に使う。ただしこれはSAML Single Logout(SLO、IdP側セッションも含めた一括ログアウト)ではなく、あくまでSnowflake側のログアウト完了後にブラウザを1回リダイレクトさせるだけの機能の様子。

SAML2_FORCE_AUTHN
ユーザーが最初の認証フロー中に、Snowflakeへアクセスするための再認証を強制されるかどうか。TRUEにすると、ユーザーがAWSアクセスポータルに既にログイン済み(SSOセッションが生きている)でも、Snowflakeへのログインのたびに毎回IdPでの認証をやり直させる。NameIDの形式に関係なく設定可能。特に理由がなければデフォルトのままでよい。

SAML2_SNOWFLAKE_ISSUER_URL
SnowflakeサービスプロバイダーのEntityID/Issuerを明示的に指定するパラメータ。省略時はSnowflakeが https://<アカウント識別子>.snowflakecomputing.com をデフォルトとして自動生成する。DESC SECURITY INTEGRATION では、明示指定の有無にかかわらず現在の値が確認できる。

SAML2_SNOWFLAKE_ACS_URL
IdPがSAML認証応答を送り返すSnowflakeのAssertion Consumer Service URLを明示的に指定するパラメータ。省略時はSnowflakeが https://<アカウント識別子>.snowflakecomputing.com/fed/login をデフォルトとして自動生成する。DESC SECURITY INTEGRATION では、明示指定の有無にかかわらず現在の値が確認できる。

おわりに

Snowflake SAML2.0 Security Integrationを使用したSP/IdP Initiated SAML Federationと構成について
ドキュメントをまとめてみた。諸々煩雑な構成が必要だが、Snowflakeが綺麗にラップしていて、パラメタを理解して
設定するだけで、うまくSAML2.0フェデレーションを構成できることがわかった。