Snowfake セキュリティ概要とベストプラクティス
Snowfake セキュリティ概要とベストプラクティス
はじめに
このページでは、Snowflake のデータを保護するためのセキュリティ機能の概要とベストプラクティスのガイドラインを示します。
Snowflakeは裏側で、3つのセキュリティレイヤーによる防御を使用して顧客データを保護しています。
ネットワークセキュリティ
IAM
データ暗号化
画像引用:Snowflake Security Overview and Best Practices
セキュリティコントロールの設定後、「モニタリング」の章に記載されているガイドラインを使用して、セキュリティコントロールをモニタリングすることができます。
ネットワークセキュリティ
ネットワークセキュリティあるいはIsolation(分離)は防御の第一線になります。
ネットワークセキュリティのベストプラクティスは以下の通りになります:
ネットワークポリシーを使用する
Snowflakeとのプライベート接続を使用する
ファイアウォールによるクライアントアプリケーションとSnowflakeの接続を許可する
データのロード/アンロードのために、Snowflakeがクラウドストレージにアクセスすることを許可する
ネットワークポリシーを使用する
ネットワークポリシーを使用して、"既知の"IPアドレス範囲にはSnowflakeアカウントへの接続を許可し、それ以外はブロックします。
さらに、クライアントアプリケーション、SCIM、またはSnowflake OAuth統合から接続するために
サービスアカウントユーザー[1](人間以外のユーザー)を使用している場合は、アカウントレベルのネットワークポリシーを上書きする別のネットワークポリシー(SCIMネットワークポリシー、OAuthネットワークポリシー)を設定する必要があるかどうかを確認してください。
Snowflakeとのプライベート接続を使用する
AWS PrivateLinkやAzure Private Linkなどのクラウドサービスプロバイダーのプライベート接続を使用して、プライベートIPアドレス経由でSnowflakeに接続することで、Snowflakeでプライベート接続を使用します。
この機能を使用すると、Snowflakeアカウントはネットワーク内のリソースとして表示されます。この機能を使用する際に考慮すべきベストプラクティスをいくつか紹介します。
- SnowflakeのプライベートURLを解決するためにDNSを設定する必要があります。クラウドプロバイダネットワーク内でプライベートDNSを使用することは、クラウドプロバイダネットワークおよびオンプレミスで実行されているクライアントからSnowflakeアカウントを解決できるようにするためのベストプラクティスです。その後、オンプレミスDNSでSnowflakeアカウントのためのDNS転送ルールを作成できます。
- プライベート接続を設定した後、パブリックエンドポイントへのアクセスをブロックしたい場合、アカウントレベルのネットワークポリシーを作成して、ネットワークのプライベートIP範囲のみがSnowflakeに接続できるようにすることができます。
- ネットワーク外で実行されているクライアントアプリケーションがSnowflakeに接続することを許可したい場合、パブリックエンドポイントを介してアカウントに接続します。ユースケースに基づいてアクセスを許可するには、クライアントアプリケーションの IP 範囲を、アカウントレベル、ユーザーレベル、または OAuth 統合ネットワークポリシーの許可リストに追加します。
ファイアウォールによるクライアントアプリケーションとSnowflakeの接続を許可する
ネットワークに出口トラフィックのためのファイアウォールがある場合、ファイアウォールを介してクライアントアプリケーションがSnowflakeに接続できるように許可してください。
- パブリックエンドポイント、プライベートエンドポイント、または両方をSnowflakeアカウントでアクセス可能にするかに基づいて、SYSTEM$ALLOWLISTそして/またはSYSTEM$ALLOWLIST_PRIVATELINKを実行してください。
- 適切な接続がSnowflakeに設定されていることを確認するために、SnowCDを使用してください。
- 出口トラフィックを検査するためにネットワークプロキシを使用している場合、SSLパススルーを設定してください。SnowflakeはSSL終端プロキシをサポートしていません。
データのロード/アンロードのために、Snowflakeがクラウドストレージにアクセスすることを許可する
AWSの場合はSnowflake VPC IDを、Azureの場合はVNet Subnet IDを、ストレージポリシーまたはファイアウォールルールに追加することで、COPYを使用してデータを一括ロード/アンロードするために、Snowflakeがクラウドストレージにアクセスできるようになります。
アイデンティティとアクセス管理
Snowflakeアカウントにアクセスできるようになったら、Snowflakeにアクセスするための次のステップはユーザーを認証することです。ユーザーは、アクセスする前に Snowflake で作成する必要があります。ユーザが認証されると、Snowflakeでのアクセス認可に使用されるロールを持つセッションが作成されます。
この章では、以下のベストプラクティスについて説明します:
ユーザとロールの管理
認証とシングルサインオン
セッション
オブジェクトレベルのアクセス制御(権限付与)
列レベルのアクセス制御
行レベルのアクセス制御
ユーザーとロールの管理
Snowflakeでは、Snowflakeのユーザーとロールをプロビジョニングおよび外部で管理する際に、IDプロバイダがサポートしているSCIMを使用することを推奨しています。
IDプロバイダは、ユーザとロールを Active Directoryのユーザとグループと同期するように設定できます。
これらのプロバイダと統合する前に、Okta SCIMのFAQとAzure AD SCIMのFAQを確認してください。
何らかの理由でSCIMを使用できない場合は、Snowflakeドライバを使用して、こちらと同様の独自のAD同期ツールを構築してください。
注:コミュニティが開発したツールであり、Snowflakeがメンテナンスしているわけではないので、自己責任で使用してください。Snowflakeのロールは階層構造になっており、ロール階層を定義するためのベストプラクティスは、以下の「オブジェクトレベルのアクセス制御(権限付与)」の章で説明します。
パスワード管理:
Snowflakeでは、サービスアカウントやSnowflake ACCOUNTADMINシステム定義ロールを持つユーザーなど、特定のユースケースにのみパスワードを使用する一方で、シングルサインオン・フェデレーション(SSO)を使用することを推奨しています。
このような場合のパスワード管理のベストプラクティスは以下のとおりです:
- セキュリティを強化するために、内蔵のDuo多要素認証を有効にする。
- 複雑で長いパスワードを使用し、できれば秘密管理または特権アクセス管理(PAM)プラットフォームで管理する。(Hashicorp VaultをSnowflakeと併用する方法の例を参照)
- パスワードは定期的にローテーションする。
パスワードの有効期限は現在Snowflakeではサポートされていません[2]が、秘密管理または特権アクセス管理(PAM)プラットフォームを使用して、定期的にパスワードを強制的に変更することができます。
Snowflakeアカウントのパスワード使用を監視する:
- has_passwordカラムが設定されているユーザへのクエリ。
- first_authentication_factorカラムが設定されているlogin_historyへクエリ。
-
現在、トライアルアカウントを除き、セルフサービスによるパスワードリセットはサポートされていないため、パスワードリセットのために ACCOUNTADMIN ロールを持つユーザーを特定します。ACCOUNTADMINがパスワードを忘れた場合は、Snowflakeサポートに連絡してパスワードをリセットしてください。[3] - ユーザーがSnowflakeにアクセスするためにパスワードを必要としない場合は、 ALTER USER コマンドを実行して password プロパティを NULL に設定します。
- このFAQを参照してください。
認証とシングルサインオン(SSO)
Snowflakeはドライバ、UI、またはSnowpipeを使用するクライアントアプリケーションなど、使用するインターフェースに応じて複数の認証方法をサポートしています。
画像引用:Snowflake Security Overview and Best Practices
- Snowflake クライアント(ドライバおよび SnowSQL)は、ユーザ名/パスワード、OAuth、キーペア、外部ブラウザ、およびOktaを介したネイティブSSOをサポートしています。
- Snowflakeは2種類のOAuthをサポートしています:
- ビルトインOAuthサーバーからトークンを受け入れるSnowflake OAuth
- サードパーティのOAuthサーバーからトークンを受け入れる外部OAuth
- 外部ブラウザ認証は、ユーザーのマシン上で動作するクライアントアプリケーションに対してのみ機能します。ドライバがシステムブラウザを開き、ユーザーを認証用のSnowflakeログインページにリダイレクトするため、ブラウザアクセスが必要です。
- OktaネイティブSSOは、その名前が示すように Oktaでのみ動作し、MFAなどの制限があります。これはレガシーな方法であり、クライアントアプリケーションがこの方法をサポートしており、OAuthのサポートがまだ追加されていない場合にのみ使用することが推奨されます。
- Snowflake UIは、SAMLを使用したパスワード認証とフェデレーション認証をサポートしています。
- データの取り込みに Snowpipeを使用している場合は、キーペア認証をサポートしています。
- クライアントアプリからのシングルサインオン(SSO)は、SAML、OAuth、外部ブラウザ、OktaネイティブSSOを使用して実現されます。
Snowflakeでは、ユーザは複数の認証方法を使用できます。たとえば、ユーザはパスワードとSAMLの両方で認証できます。Snowflakeへの接続に使用するクライアントアプリケーションとその機能に基づいて、アカウントで複数の認証方法を許可する必要がある場合があります。
認証のベストプラクティス
Snowflakeでは、Snowflakeに接続するすべてのクライアントアプリケーションとその認証機能をリストアップしたスプレッドシートを作成することを推奨しています。アプリが複数の認証方法をサポートしている場合は、以下の優先順位で使用します。
- OAuth (Snowflake OAuth または 外部 OAuth)
- 外部ブラウザ (OAuthをサポートしないデスクトップアプリケーションの場合)
- OktaネイティブSSO (Oktaを使用していて、アプリがこの方法をサポートしており、OAuthや外部ブラウザ認証をまだサポートしていない場合)
- キーペア認証 (主にサービス・アカウント・ユーザーに使用される。この場合、クライアント・アプリケーションが秘密鍵を管理する必要があるため、内部鍵管理ソフトウェアで補完する。)
- パスワード (上記のどのオプションにも対応していないアプリケーションの最後のオプション。サードパーティのETLアプリケーションから接続するサービスアカウントユーザーによく使用される。)
その他のベストプラクティスをいくつか紹介します:
- 独自のアプリケーションの場合、開発者にSnowflake OAuthまたは外部 OAuthをサポートするよう依頼します。ブラウザにアクセスできないプログラマティックなクライアントアプリケーションであれば、Snowflake OAuthにはブラウザのリダイレクト機能が必要なので、外部 OAuthしか使えません。
- SnowSQLやその他のデスクトップツールについては、外部ブラウザ認証を使用するようにユーザーに依頼してください。
- エンドユーザとしてクエリを実行する場合と、サービスアカウントユーザとしてクエリを実行する場合:
クライアントアプリケーションの機能またはその他の理由により、サービスアカウントを使用してSnowflakeに接続している場合でも、クエリを送信するエンドユーザを追跡したい場合は、セッションのquery_tagを通してエンドユーザの詳細を渡すことができます。これは簡単になりすますことができるので、実装する前にセキュリティチームに確認してください。
Multi-factor authentication (MFA)
Snowflakeでは、ユーザーアクセスに追加のセキュリティレイヤーを提供するMFAを常に使用することを推奨しています。
SnowflakeアカウントでMFAを有効にするには、2つの方法があります。
- IDプロバイダで有効にする:Snowflakeが認証のためにユーザーをIDプロバイダーにリダイレクトするときに、ユーザーはMFAを要求されます。これは、独自の(BYO)MFAを持ち込むことができるため、MFAを使用するための好ましいメカニズムです。これは、SAML、OAuth、および外部ブラウザ認証で動作します。さらに、Snowflakeやその他の企業リソースにアクセスするために管理するMFAアプリケーションを1つにする必要があるため、エンドユーザーにとって使いやすくなります。
- 組み込みのDuo MFA: Snowflakeは、Duo Securityによる組み込みのMFAを提供します。アイデンティティプロバイダと統合していない場合にのみ使用してください。
セッション
ユーザが認証されると、Snowflakeはユーザのデータベースセッションを作成します。クライアントアプリケーションは、このセッションを使用して Snowflake にクエリを送信できます。各セッションには4時間のアイドル(非アクティブ)タイムアウトがあります。セッションを使用して、新しい子セッションを作成することができます。例えば、Snowflake classic UIはワークシートごとに子セッションを作成します。
セッション管理のベストプラクティスは以下の通りです:
- セッションの再利用
クライアント・アプリケーションから既存のセッションを再利用することで、最高のパフォーマンスを得ることができ、新しいセッションの作成による遅延を避けることができます。 - 不要になったら接続を閉じる
不要になったら、クライアント・アプリケーションの接続を閉じてください(例えば、pythonドライバのcon.close()を呼び出します)。 - CLIENT_SESSION_KEEP_ALIVEの使用を避ける
必要な場合を除き、セッションパラメータ CLIENT_SESSION_KEEP_ALIVE を true にすることは避けてください。デフォルトでは、Snowflake はアイドルタイムアウト後にセッションを閉じます。しかし、このパラメータを TRUE に設定すると、接続がアクティブである限り、セッションは無期限にアクティブなままになります。このパラメータをTRUEに設定して作成したセッションが多すぎると、リソースに負荷がかかり、パフォーマンスが低下する可能性があります。 - セッションの使用状況を監視する
account_usage.sessionsビューでセッションの使用状況を監視してください。
オブジェクトレベルのアクセス制御(権限付与)
※この章はオリジナルのページから多く加筆修正削除をしています。
Snowflakeのテーブル、ビュー、関数などのオブジェクトへのアクセスを認可するためにロールが使用されます。
ロールに別のロールを割り当てて階層化でき、階層化されたロール間では権限が継承されます。
ユーザに対してデータベースセッションが作成されると、プライマリロール[4](現在のロール)がセッションに関連付けられます。
プライマリロールの階層下にあるすべてのロールは、認可を実行するためにセッション内でアクティベートされます。
時間をかけて、適切なロール階層モデルを確立してください。
Snowflakeでは、Snowflakeドキュメントの「アクセス制御の考慮事項」を確認することに加え、
アクセス制御のベストプラクティスに従うことを推奨しています:
- 論理的なロールとして職能ロール(functional roles)とアクセス制御ロール(access roles)を定義する
- 将来の権限付与(future grants)を使用する
- ユーザーにdefault_roleプロパティを設定する
- 権限(privileges)の一元管理のために管理アクセススキーマ(managed access schemas)を使用する
順に解説します。
論理上のロールとして職能ロール(functional roles)とアクセス制御ロール(access roles)を定義する
一言で説明しますと、これは職能ロールをユーザグループ、アクセス制御ロールを権限のセットのように捉え、権限のセットをユーザグループにあてるイメージでオブジェクトへのアクセス制御を行うことを指します。
ただしドキュメントにある通り[5]職能ロールとアクセス制御ロールに技術的な違いはなく、実態はカスタムロールであり、あくまで論理上区別、定義されるものです。
アクセス制御ロールは権限のみを付与すると良いとされます。
このアクセス制御ロールは職能ロールに継承させます。
職能ロールは他の職能ロールに継承したり、ユーザに割り当てます。
このベストプラクティスにより、職能ロールの階層がADグループの階層を模倣することができ、
上記の「ユーザーとロールの管理」で説明したように、SCIM等を使用してプロビジョニングおよび外部で管理することができます。
ここまでベストプラクティスを踏まえ、次のようなイメージの掛け合わせでロール階層モデルを構築しアクセス制御を行います。
- 誰(どの役職やシステム)が: 職能ロール
- 何(どのオブジェクト)を: アクセス制御ロール
- どう操作(SELECTなど)できるか: 権限
以下はここまでの内容に沿ったロール階層モデルの例です。
画像引用:Snowflake Role-Based Access Control (RBAC) Approach
将来の権限付与(future grants)を使用する
アクセス制御ロールに対しデータベースやスキーマレベルでの将来の権限付与を使用して、権限管理を簡素化できます。
これにより新しいオブジェクトが作成されると、適切な権限が自動的に割り当てられるようにできます。
ユーザーにdefault_roleプロパティを設定する
CREATE USERする際にdefault_roleプロパティを使用し適切な職能ロールを設定します。
権限(privileges)の一元管理のために管理アクセススキーマ(managed access schemas)を使用する
通常のスキーマでは、スキーマ内のテーブルやビューなどのオブジェクトの権限操作をそのオブジェクトの所有者(オブジェクトに対するOWNERSHIP権限を持つロール)が可能ですが、
管理アクセススキーマでは、スキーマ内のテーブルやビューなどのオブジェクトの権限操作をスキーマの所有者だけが可能となります。(将来の権限を含みます。)
そのため、テーブルやビューなどのオブジェクトの所有者が個人の裁量で他のロールにアクセス権を与えることを防ぐには、管理アクセススキーマを使用します。
管理者以外がテーブルやビュー作成をできる場合に考慮を推奨します。
列レベルのアクセス制御
個人情報、PHI、財務データなど、特定の列に存在する機密情報へのアクセスを制限したい場合、
権限のないユーザの列へのアクセスを制限できる以下のようなデータガバナンス機能を提供しています。
- ダイナミックデータマスキング:誰がクエリーを行うかに基づいて列のデータを動的にマスキングできます。
-
外部トークン化:パートナーソリューションと統合し、許可されたユーザーに対してクエリ時にデータをデトークナイズします。
データをSnowflakeにロードする前にトークン化し、クエリ実行時にデータをトークン解除できます。トークン化とは、機密データを解読不能なトークンに置き換えて機密データを削除するプロセスです。 - セキュアビュー:権限のないユーザーに列を隠すことができます。
ダイナミックデータマスキングと外部トークン化のどちらも、マスキングポリシーを使用して機密データへのアクセスを許可されたユーザーに制限します。
公式ドキュメントの考慮事項を確認することに加えて、次のマスキングポリシーのベストプラクティスを確認してください:
- マスキングポリシーの管理において、集中型、ハイブリッド、または分散型のアプローチを検討します。
- マスキングポリシーの条件において、権限のないユーザが集計データを見ることができ、個々のデータを見ることはできないようにする。
- マスキングポリシーでSHA2関数を使用して、権限のないユーザーに対して保護された列への結合を許可することは、意図しないクエリ結果につながる可能性があるため避けてください。
マスキングポリシーの管理において、集中型、ハイブリッド、または分散型のアプローチを検討します。
アクション | 集中管理 | ハイブリッド管理 | 分散管理 |
---|---|---|---|
ポリシーの作成 | セキュリティ責任者 | セキュリティ責任者 | 個別チーム |
ポリシーを列にアタッチ | セキュリティ責任者 | 個別チーム | 個別チーム |
マスキングポリシーの条件において、権限のないユーザが集計データを見ることができ、個々のデータを見ることはできないようにする。
権限のないユーザが保護された列の集約情報(合計やカウントなど)を表示することは許可するが、個々のデータへのアクセスは禁止したい場合は、集約データを列として表現したビュー等を作成し、マスキングポリシー条件にコンテキスト関数であるinvoker_role()を使用して、基礎となるテーブルカラムにマスキングポリシーを適用します。[6]
権限のないユーザがクエリ内の保護された列に対して結合を実行できるようにしたい場合は、ダイナミックデータマスキングの代わりに外部トークン化を使用してください。
マスキングポリシーでSHA2関数を使用して、権限のないユーザーに対して保護された列への結合を許可することは、意図しないクエリ結果につながる可能性があるため避けてください。
マスキングポリシーで暗号化ハッシュにSHA2を使用しないでください。[7]
代わりに、SHA2衝突の問題がないSnowflakeの組み込み暗号化関数(encrypt / decryptおよびencrypt_raw / decrypt_raw)を使用することができます。
行レベルのアクセス制御
特定の行へのアクセスを特定のユーザのみに制限したい場合があります。
例えば、ユーザの国に基づいて行レベルのアクセス制御したい場合があるとします。
この場合、CURRENT_ROLE()やCURRENT_USER()のようなコンテキスト関数を使用した行アクセスポリシーを作成しセキュアなビューを作成し、ビューに問い合わせるユーザの行を動的にフィルタリングできます。
これはSnowflakeが内部的にセキュアビューを作成するので、セキュアビューと同じ様にパフォーマンスについて考慮する必要があります。
詳しくはドキュメントのポリシーパフォーマンスガイドラインを確認してください。
データ暗号化
Snowflakeに保存されるすべてのデータはデフォルトで暗号化される仕様となっています。
AES-256などの業界標準技術を使用した暗号化をし、暗号化キーはハードウェアセキュリティモジュール (HSM) をルートとして階層的に管理されています。
Tri-Secret Secureと呼ばれる機能により、この暗号化プロセスでカスタマーマスターキー(CMK)を使用することもできます。
Tri-Secret Secureとは別に、Snowflakeは30日ごとに鍵をローテーションし、30日後に取り込まれる新しいデータが新しい鍵階層を使用して暗号化されるようにしています。
詳しく知る場合、ドキュメントのエンドツーエンド暗号化と暗号化キー管理と
ブログData Encryption with Customer-Managed Keysを確認してください。
モニタリング
組織の監査およびコンプライアンス要件を満たすために、Snowflakeの使用状況を監視することができます。
すべてのSnowflakeアカウントには、SNOWFLAKEという名前のシステム定義の読み取り専用共有データベースが付属しています。
ACCOUNT_USAGEという名前のスキーマがあり、1年分の監査ログにアクセスできるビューが含まれています。監査目的で例えば以下のビューを使用できます。
LOGIN_HISTORY:Snowflakeで確立されたすべての接続のログが含まれています。誰がどこから、どのような認証方法でログインしたかを確認することができます。
QUERY_HISTORY:Snowflakeで実行されたすべてのクエリのログが含まれます。これには、ユーザー、ロール、権限に関するデータとメタデータに対するクエリが含まれます。
監査ログを1年以上保持する必要がある場合は次の内容を検討します:
- Snowflakeアカウントのカスタムテーブルにデータを移動する(SnowAlertを参照)
- Snowflake以外のSIEMやその他のセキュリティソリューションにデータを移動する
ユーザーの詳細情報を確認する
USERS:現在のユーザーの詳細情報を取得できます。
このビューでは、例えば以下の情報をクエリできます:
Snowflakeにパスワードを持っているユーザー (where HAS_PASSWORD = true)
キーペア認証を使用するユーザー (where HAS_RSA_PUBLIC_KEY = true)
SSOを使用してSnowflakeに接続するユーザー (where HAS_PASSWORD != true and HAS_RSA_PUBLIC_KEY != true)
過去30日間に作成されたユーザー (where CREATED_ON > dateadd(day, -30, CURRENT_TIMESTAMP())
非アクティブユーザー (where LAST_SUCCESS_LOGIN > dateadd(day, -30, CURRENT_TIMESTAMP() -- haven’t used Snowflake in the last 30 days)
無効なユーザー (where DISABLED = true)
誰が何にアクセスできるのかを確認する
Snowflakeで誰がどのオブジェクト(テーブル、ビューなど)にアクセスできるかを調べるには、
GRANTS_TO_ROLESビューとGRANTS_TO_USERSビューを結合します。
ロールは階層的な性質を持っているため、この情報を取得するには再帰的なクエリを作成する必要があります。
このブログの投稿を参考に、ロールの階層を視覚化することもできます。
以下のような情報を知りたい場合、SESSION_IDでQUERY_HISTORYビューとSESSIONSビューを結合することができます。
ROLESビューをクエリして、それらの情報がいつ作成または削除されたか
あるクエリを実行する際、ユーザーはどのように認証されたのか
指定されたクエリで、ユーザがどのように認証されたか
-
サービスアカウントは次の記事で「Service accounts are nonhuman identities used by software such as applications, automation processes, operating systems, and more. 」と説明されています。
Snowflake Service Account Security, Part 1 ↩︎ -
現在はパスワードの変更が必要になるまでの最大日数を設定できます。PASSWORD_MAX_AGE_DAYSのパラメータにより設定可能です。
CREATE PASSWORD POLICY ↩︎ -
現在はパスワードリセットできます。詳しくはドキュメントを参照してください。
ユーザーのパスワードのリセット ↩︎ -
プライマリロールは公式ドキュメント内で「現在のロール」と説明されています。
施行モデル: プライマリロールおよびセカンダリロール ↩︎ -
公式ドキュメントに次の記載があります。「Snowflakeのオブジェクトアクセスロールと機能ロールの間に技術的な相違はありません。相違は、それらを論理的に使用して、権限のセットを集めてユーザーのグループに割り当てる方法にあります。」
オブジェクトのアクセスとビジネス機能の整合 ↩︎ -
INVOKER_ROLE()を使用する詳細は、以下のドキュメントページを参照してください。
高度な列レベルセキュリティのトピック ↩︎
Discussion