Snowflake のアカウント保護に関するセキュリティ ポリシーについてまとめてみる
はじめに
Snowflake のアカウント保護に使用できる代表者なセキュリティ ポリシーについて、概要や注意点、管理方法案について考えてみたので、本記事で内容をまとめてみます。
前提
Snowflake で設定できるポリシーはいくつかありますが、ここではセキュリティに関する以下のポリシーを扱います。
- ネットワークポリシー
- ネットワークルール
 
 - 認証ポリシー
 - パスワードポリシー
 - セッションポリシー
 
Snowflake における接続およびセッションのライフサイクル
前提として、Snowflake における接続およびセッションのライフサイクルについて知っておくとここで扱う各ポリシーの役割が理解しやすいと思います。
以下は Best Practices to Mitigate the Risk of Credential_Compromise 記載の図をもとに作成、日本語にしたものです。

図の通り Snowflake への接続からセッション終了までの間に、左から順に各ポリシーが適用されます。各ポリシーは、その名称のとおり、各ポイントにおけるアカウントやユーザーの設定を制御する役割を持っています。
セキュリティに関するオブジェクト
Snowflake における各種セキュリティ設定は、オブジェクトを定義することで行います。
つまり、各ポリシーは通常のデータベースやテーブルのように CREATE 文で定義し、オプションでどのような設定のポリシーとするかをコントロールします。
前提として、Snowflake におけるオブジェクトにはレベル(階層)が存在します。代表者なオブジェクトのレベルは以下の通りです。
- アカウント レベルのオブジェクト
- アカウント内で一意の名称で作成する必要がある
 - 例:データベース、仮想ウェアハウス、ユーザー など
 
 - データベース レベルのオブジェクト
- 任意のデータベース内に作成
 - データベース内で一意の名称で作成する必要がある
 - 例:データベースロール、スキーマ
 
 - スキーマ レベルのオブジェクト
- 任意のデータベース、スキーマ内に作成
 - スキーマ内で一意の名称で作成する必要がある
 - 例:テーブル、ビュー など
 
 
この上で、ここで扱うセキュリティに関するオブジェクトは以下の通り各階層に位置付けられます。
| レベル | オブジェクト | 概要 | 
|---|---|---|
| アカウントレベル | ネットワークポリシー | アカウントへのネットワークトラフィックを制御する | 
| スキーマレベル | ネットワークルール | ネットワークポリシーで指定できるオブジェクト ネットワーク識別子を格納するオブジェクト  | 
| スキーマレベル | 認証ポリシー | Snowflake に認証するクライアントや認証方式を設定できる | 
| スキーマレベル | セッションポリシー | アイドルセッションのタイムアウト期間を設定できる | 
| スキーマレベル | パスワードポリシー | パスワード要件や試行回数を設定できる | 
特徴は以下です。
- ネットワークポリシー
- アカウントレベルのオブジェクト
 - 後述する作成権限としてもアカウントレベルの権限が必要
 
 - その他のオブジェクト
- スキーマレベルのオブジェクト
 - スキーマに対する各オブジェクトの作成権限を与えることで作成できる
 - スキーマレベルのオブジェクトなので、何らかのデータベース スキーマに作成する
 
 
ポリシーの優先順位
アカウント保護に関するポリシーは指定のレベルで設定することが可能です。代表者なレベルは以下です。
- Snowflake アカウントレベルで設定
- この場合、そのポリシーの設定アカウント全体に適用されます
 
 
--アカウントレベルでネットワークポリシーを有効化
ALTER ACCOUNT SET NETWORK_POLICY = my_policy;
- 任意のユーザーレベルで設定
- この場合、そのユーザーにのみポリシー設定が適用されます
 - アカウントとユーザーの両方にポリシーを設定した場合、ユーザーレベルのポリシーがアカウントレベルのポリシーより優先されます
 
 
--ユーザーレベルでネットワークポリシーを有効化
ALTER USER joe SET NETWORK_POLICY = admin_policy;
ポリシーの管理
上記の通り、スキーマレベルのオブジェクトに位置付けられるポリシーが多いので、ここでは以下のようにポリシーを管理するとし、後述する手順でもポリシー定義を行います。
- スキーマレベルのポリシーオブジェクトを管理する専用のデータベースを作成
- ポリシー単位でスキーマを作成
 - データベース・スキーマは ACCOUNTADMIN で作成
 
 - スキーマレベルのポリシーオブジェクトは、各ポリシー専用のカスタムロール(Policy Admin)で作成
- 対応するスキーマに対するポリシー作成権限を与える
 - このカスタムロールは SECURITYADMIN の子ロールとする
 
 - ポリシーの適用は SECURITYADMIN で行う
 - アカウントレベルのポリシーであるネットワークポリシーは、SECURITYADMIN で作成
- ※デフォルトで SECURITYADMIN 以上で作成可能
 
 
カスタムロールは SYSADMIN の子ロールとする場合もあるかと思います。ここは悩ましい部分ですが、今回ポリシーの適用は SECURITYADMIN で行う設定としたので、アカウントレベルのポリシーの適用権限がデフォルトで付与される SECURITYADMIN の子ロールとしました。(SYSADMIN の子ロールとするとデフォルトでポリシー適用権限の無い SYSADMIN にも継承されるため)
なので、SYSADMIN と SECURITYADMIN で明確に操作範囲を分ける設定です。
また、この場合以下の特徴もあります。
- ネットワークポリシーの作成時はネットワークルールの USAGE 権限が必要だが、継承により SECURITYADMIN も自動的に操作権限を持つ
 - ポリシーをユーザーに適用する際は、ユーザーに対する ALTER 操作が必要だが SECURITYADMIN はデフォルトでユーザーの作成権限を持つ USERADMIN を継承するので、ポリシー管理者ロールを継承していることもあわせて、ユーザーへのポリシー適用権限を自動的に SECURITYADMIN に集約できる
 
上記の設定に基づくオブジェクトは、以下のコマンドで作成できます。
--ポリシー管理用データベースを作成
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE DATABASE policies_db;
--ポリシーごとのスキーマを作成
----ネットワークルール
CREATE OR REPLACE SCHEMA policies_db.network_rules;
----認証ポリシー
CREATE OR REPLACE SCHEMA policies_db.authentication_policies;
----パスワードポリシー
CREATE OR REPLACE SCHEMA policies_db.password_policies;
----セッションポリシー
CREATE OR REPLACE SCHEMA policies_db.session_policies;
--各ポリシー作成ロールを作成
USE ROLE USERADMIN;
----ネットワークルール
CREATE OR REPLACE ROLE network_rule_admin;
----認証ポリシー
CREATE OR REPLACE ROLE authentication_policy_admin;
----パスワードポリシー
CREATE OR REPLACE ROLE password_policy_admin;
----セッションポリシー
CREATE OR REPLACE ROLE session_policy_admin;
--ロール階層を設定
USE ROLE SECURITYADMIN;
GRANT ROLE network_rule_admin TO ROLE SECURITYADMIN;
GRANT ROLE authentication_policy_admin TO ROLE SECURITYADMIN;
GRANT ROLE password_policy_admin TO ROLE SECURITYADMIN;
GRANT ROLE session_policy_admin TO ROLE SECURITYADMIN;
--権限付与
----ネットワークルール
GRANT USAGE ON DATABASE policies_db TO ROLE network_rule_admin;
GRANT USAGE ON SCHEMA policies_db.network_rules TO ROLE network_rule_admin;
GRANT CREATE NETWORK RULE ON SCHEMA policies_db.network_rules TO ROLE network_rule_admin;
SHOW GRANTS TO ROLE network_rule_admin;
----認証ポリシー
GRANT USAGE ON DATABASE policies_db TO ROLE authentication_policy_admin;
GRANT USAGE ON SCHEMA policies_db.authentication_policies TO ROLE authentication_policy_admin;
GRANT CREATE AUTHENTICATION POLICY ON SCHEMA policies_db.authentication_policies TO ROLE authentication_policy_admin;
SHOW GRANTS TO ROLE authentication_policy_admin;
----パスワードポリシー
GRANT USAGE ON DATABASE policies_db TO ROLE password_policy_admin;
GRANT USAGE ON SCHEMA policies_db.password_policies TO ROLE password_policy_admin;
GRANT CREATE PASSWORD POLICY ON SCHEMA policies_db.password_policies TO ROLE password_policy_admin;
SHOW GRANTS TO ROLE password_policy_admin;
----セッションポリシー
GRANT USAGE ON DATABASE policies_db TO ROLE session_policy_admin;
GRANT USAGE ON SCHEMA policies_db.session_policies TO ROLE session_policy_admin;
GRANT CREATE SESSION POLICY ON SCHEMA policies_db.session_policies TO ROLE session_policy_admin;
SHOW GRANTS TO ROLE session_policy_admin;
この時点で下図のようなロール階層となります。

以降で各ポリシーを設定していきます。
ネットワークポリシー
Snowflake アカウントに対して、接続元の制御を行う際はネットワークポリシーを使用します。
接続元の IPv4 アドレスや PrivateLink を使用する際は、VPC エンドポイント ID を指定することで、指定の接続元からのアクセスを許可するように構成できます。
ネットワークポリシーはアカウントレベルのオブジェクトですが、作成時に接続元として許可またはブロックする識別子(IPv4アドレスや VPCE ID)をネットワークルールを通して指定できます。
IPv4 アドレスを直接指定することもできますが、ネットワークルールとして定義して使用することで、接続元/先となる識別子を管理しやすくなります。
ここでは、以下のネットワークポリシーを設定してみます。
- 自身のネットワークからの接続を許可
 - 外部ツール(Tableau Cloud)からの接続を許可
 
ネットワークルールの作成
はじめに、ネットワークルールの管理者ロールでネットワークルールを作成します。
USE ROLE network_rule_admin;
USE SCHEMA policies_db.network_rules;
--特定の IP アドレスから Snowflake サービストラフィックを許可またはブロックするために使用されるネットワークルールを作成
CREATE NETWORK RULE myip_access
  TYPE = IPV4
  VALUE_LIST = ('xxx.xxx.xxx.xxx/32')
  MODE = INGRESS
  COMMENT ='myip';
CREATE NETWORK RULE tableau_access
  TYPE = IPV4
  VALUE_LIST = ('141.163.208.0/23')
  MODE = INGRESS
  COMMENT ='Tableau Cloud';
 --確認
 SHOW NETWORK RULES;
ネットワークポリシーの作成
今回の設定では SECURITYADMIN でネットワークポリシーを作成するので、以下のコマンドを使用します。
--ネットワークポリシーを作成
USE ROLE SECURITYADMIN;
----ユーザーアクセス用
CREATE NETWORK POLICY person_user_net_policy
    ALLOWED_NETWORK_RULE_LIST = ('myip_access')
 ;
----外部ツールからのアクセス用
CREATE NETWORK POLICY service_net_policy
    ALLOWED_NETWORK_RULE_LIST = ('tableau_access')
 ;
--確認
SHOW NETWORK POLICIES;
ネットワークルールは複数指定することも可能です。
ネットワークポリシーの適用:アカウントレベル
ネットワークポリシーをアカウントに適用します。この際、必要な権限は以下です。
- ATTACH POLICY:デフォルトでは SECURITYADMIN 以上に付与
 
ここでは SECURITYADMIN でそのまま以下を実行し、ユーザーアクセス用のネットワークポリシーを有効化します。
--アカウントでネットワークポリシーを有効化
ALTER ACCOUNT SET NETWORK_POLICY = person_user_net_policy;
ポリシーの適用は以下で確認できます。
SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT;
この状態で異なる許可リストに無い接続元からアクセスすると下図の表示になります。

解除は以下で可能です。
ALTER ACCOUNT UNSET NETWORK_POLICY;
ネットワークポリシーの適用:ユーザーレベル
ネットワークポリシーは、個別のユーザーに対して適用することも可能です。この際、アカウントレベルでも設定していた場合、ユーザーレベルの設定が優先されます。
個々のユーザーにネットワークポリシーを設定するには、以下の権限が必要です。
- ユーザーおよび ネットワークポリシーの両方に対する OWNERSHIP 権限
 
ここではSECURITYADMINでポリシーを作成しているので、そのまま以下でユーザーに対してもアクティブ化できます。
ALTER USER user1 SET NETWORk_POLICY = service_net_policy;
このユーザーで Tableau Cloud から接続を行うと、ポリシーのアクティブ化前は自身のネットワークからのみ接続を許可するネットワークポリシーが適用され、接続時にエラーとなります。

ユーザーに対して上記のポリシーを適用後、ユーザーの設定が優先され接続できるようになります。
内部ステージの保護
ネットワークポリシー適用時の注意点として、デフォルトでは内部ステージへのアクセスは制御されません。
このためには ENFORCE_NETWORK_RULES_FOR_INTERNAL_STAGES パラメータを有効にします。これは現在 GET_PRESIGNED_URL 関数によって生成される署名付き URLs に対しても有効です。
例えば、アカウントでのネットワークポリシーを有効にした状態であっても、以下で出力される URL からデータを取得できます。
SELECT GET_PRESIGNED_URL(@my_int_stg, 'sample_data.csv');
パラメータを有効化後に、再度署名付き URL を発行します。
--ENFORCE_NETWORK_RULES_FOR_INTERNAL_STAGES パラメータを有効化
USE ROLE ACCOUNTADMIN;
ALTER ACCOUNT SET ENFORCE_NETWORK_RULES_FOR_INTERNAL_STAGES = true;
SHOW PARAMETERS LIKE 'ENFORCE_NETWORK_RULES_FOR_INTERNAL_STAGES' IN ACCOUNT;
この場合、URL にセキュリティトークンが含まれ、許可リストにない接続元からアクセスすると下図のような表示になりブロックされます。

認証ポリシー
認証ポリシーを適用することでネットワークポリシーの次の段階として特定のクライアントや特定の認証方式でのアクセスを許可する、MFA を強制するなどの制御が可能となります。
ユーザーの TYPE プロパティ
認証ポリシーの動作は Snowflake 上のユーザーに設定される TYPE プロパティに影響される場面があります。TYPE プロパティは、2024年7月に追加された Snowflake 上のユーザーのタイプを識別するためのプロパティです。
大きく人間が操作することを意図するユーザーと定期的なジョブ実行など、何らかのツールからの接続を意図するユーザーに分けられます。タイプごとにパスワードの設定可否や GUI(Snowsight)にログインできるかなどが異なります。主な特徴は以下の通りです。
| タイプ | 概要 | 用途 | 
|---|---|---|
| PERSON | 実際にユーザーが使用することを想定 認証ポリシーの MFA 強制の対象となる  | 
ユーザーが普段 Snowflake にログインし対話的な操作を行う際に使用 | 
| NULL | PERSON と同義 | |
| SERVICE | 他システムからのログイン操作を想定 パスワードを持つことができない SSO を使用してログインすることができない MFA に登録できない 認証ポリシーによる MFA 強制の対象にはならない Snowsight にサインインできない  | 
ETL/ELT ツール、BI ツールなど外部システムからの操作用を想定(システムユーザー、サービスユーザー) | 
| LEGACY_SERVICE | 段階的に廃止予定 パスワードを設定できる SSO を使用してログインできる 認証ポリシーによる MFA 強制の対象にはならない  | 
外部システムの内、Snowflake へのログインにパスワード認証のみしか利用できない場合に使用 | 
認証ポリシー関連の特徴として、サービスユーザー(SERVICE, LEGACY_SERVICE)は MFA を強制するポリシーが設定されていても、適用対象外となります。
詳細は以下をご参照ください。
ユーザータイプは以下で確認・設定できます。
--ユーザータイプを確認
SHOW USERS;
SELECT "name","type" FROM TABLE(RESULT_SCAN(-1));
--ユーザータイプを変更
ALTER USER <ユーザー名> SET TYPE = [PERSON | SERVICE | LEGACY_SERVICE | NULL];
TYPE プロパティについては以下でも紹介されていますので、あわせてご参照ください。
認証ポリシーの作成
ここでは、以下の設定で認証ポリシーを設定してみます。
- ユーザー
- 人間が操作することを想定した PERSON ユーザー
 - コマンドラインツールからの接続を想定したユーザー
- パスワードを持たせるために LEGACY_SERVICE として作成
 
 
 - アカウント全体に適用する認証ポリシー
- すべての認証方式を許可(パスワード・キーペア など)
 - MFA の登録・使用を強制
 
 - コマンドラインツールからの接続を想定した認証ポリシー
- 認証方式としてキーペアのみを許可
 - クライアントとして SnowSQL のみを許可
 
 
今回の設定では、認証ポリシーの作成はポリシー管理者ロール(authentication_policy_admin)で作成するので、以下のコマンドで認証ポリシーを作成します。
USE ROLE authentication_policy_admin;
USE SCHEMA policies_db.authentication_policies;
--アカウント全体に適用する認証ポリシー
CREATE AUTHENTICATION POLICY require_mfa_authentication_policy
  AUTHENTICATION_METHODS = ('ALL') --デフォルト
  MFA_AUTHENTICATION_METHODS = ('PASSWORD') --デフォルト
  MFA_ENROLLMENT = REQUIRED  --デフォルト
  CLIENT_TYPES = ('ALL')  --デフォルト
;
--SnowSQLからの接続を想定した認証ポリシー
CREATE AUTHENTICATION POLICY snowsql_authentication_policy
  AUTHENTICATION_METHODS = ('KEYPAIR') 
  CLIENT_TYPES = ('SNOWSQL') 
;
認証ポリシーの適用:アカウントレベル
認証ポリシーをアカウントに適用します。この際、必要な権限は以下です。
- アカウントに対する APPLY AUTHENTICATION POLICY :デフォルトでは SECURITYADMIN 以上に付与
 
ポリシーの適用には SECURITYADMIN を使用する設定なので、以下のコマンドでアカウント全体に対する認証ポリシーを有効化します。
--アカウントで認証ポリシーを有効化
USE ROLE SECURITYADMIN;
ALTER ACCOUNT SET AUTHENTICATION POLICY require_mfa_authentication_policy;
ポリシーの適用は以下で確認できます。
--アクティブな認証ポリシーを一覧
----POLICY_STATUS カラムでステータスが見れる
USE ROLE ACCOUNTADMIN;
SELECT *
FROM TABLE(
    policies_db.INFORMATION_SCHEMA.POLICY_REFERENCES(
    POLICY_NAME => 'policies_db.authentication_policies.require_mfa_authentication_policy'
  ));
ポリシー適用後、PERSON ユーザーで再度 Snowflake にログインしようとするとMFA_ENROLLMENT = REQUIREDの設定に基づき、未登録の場合 MFA の設定画面が表示されます。

設定後、Snowflake アカウントにログインできます。こちらの手順は以下をご参照ください。
認証ポリシーの適用:ユーザーレベル
今回の設定で認証ポリシーを個々のユーザーに対して設定するには、以下の権限が必要です。
- 認証ポリシーの所有者権限およびユーザーに対する APPLY AUTHENTICATION POLICY 権限
 
ポリシーをユーザーレベルで設定する際は、以下で適用できます。
USE ROLE SECURITYADMIN;
ALTER USER cli_user SET AUTHENTICATION POLICY policies_db.authentication_policies.snowsql_authentication_policy;
このポリシーでは、認証方式としてキーペアのみを許可しています。そのためポリシーを適用したユーザーでユーザー名・パスワードによる認証を行うと認証ポリシーによりアクセスがブロックされます。
>snowsql -a <アカウント> -u cli_user
Password:
250001 (08001): Failed to connect to DB: <アカウント>.snowflakecomputing.com:443. Authentication attempt rejected by the current authentication policy.
許可しているキーペアであれば接続できます。
>snowsql -a <アカウント> -u cli_user --private-key-path rsa_key.p8
Private Key Passphrase:
* SnowSQL * v1.3.2
Type SQL statements or !help
cli_user#(no warehouse)@(no database).(no schema)>
LEGACY_SERVICE として作成したので、パスワードを設定できますがポリシーのCLIENT_TYPES = ('SNOWSQL')より Snowsight へのログインもブロックされます。

パスワードポリシー
Snowflake ではアカウントのデフォルトパスワードポリシーが設定されています。下図は2025年3月時点のトライアルアカウントでの検証ですが、特にパスワードポリシーを設定していない場合、下図のようなポリシーが設定されていました。

組織によってはパスワード要件もあるかと思いますので、そういった際にアカウントで使用するパスワード要件をカスタマイズできます。
パスワードポリシーの作成
今回の設定では、パスワードポリシーの作成はポリシー管理者ロール(password_policy_admin)で作成するので、以下のコマンドで認証ポリシーを作成します。ポリシーの内容は公式ドキュメントのサンプルとして記載されているものですが、パスワードの長さや文字種、試行回数などを設定できます。
USE ROLE password_policy_admin;
USE SCHEMA policies_db.password_policies;
--パスワードポリシーを作成
CREATE PASSWORD POLICY PASSWORD_POLICY_PROD_1
    PASSWORD_MIN_LENGTH = 14
    PASSWORD_MAX_LENGTH = 24
    PASSWORD_MIN_UPPER_CASE_CHARS = 2
    PASSWORD_MIN_LOWER_CASE_CHARS = 2
    PASSWORD_MIN_NUMERIC_CHARS = 2
    PASSWORD_MIN_SPECIAL_CHARS = 2
    PASSWORD_MIN_AGE_DAYS = 1
    PASSWORD_MAX_AGE_DAYS = 30
    PASSWORD_MAX_RETRIES = 3
    PASSWORD_LOCKOUT_TIME_MINS = 30
    PASSWORD_HISTORY = 5
    COMMENT = 'production account password policy';
パスワードポリシーの適用:アカウントレベル
パスワードポリシーをアカウントに適用する際に必要な権限は以下です。
- アカウントに対する APPLY PASSWORD POLICY
- デフォルトでは SECURITYADMIN 以上に付与
 - Global privileges (account-level privileges)|Snowflake DOCUMENTATION
 
 
その他のポリシーと同様に、今回であればポリシーの適用には SECURITYADMIN を使用する設定なので、以下のコマンドでアカウント全体に対するパスワードポリシーを有効化できます。
--アカウントレベルでパスワードポリシーを適用 
USE ROLE SECURITYADMIN;
ALTER ACCOUNT SET PASSWORD POLICY PASSWORD_POLICY_PROD_1;
--アクティブなパスワードポリシーを一覧
USE ROLE ACCOUNTADMIN;
SELECT *
FROM TABLE(
  policies_db.INFORMATION_SCHEMA.POLICY_REFERENCES(
    POLICY_NAME => 'policies_db.password_policies.PASSWORD_POLICY_PROD_1'
  ));
--無効化
ALTER ACCOUNT UNSET PASSWORD POLICY;
パスワードポリシーの適用:ユーザーレベル
今回の設定でパスワードポリシーを個々のユーザーに対して設定するには、以下の権限が必要です。
- パスワードポリシーの所有者権限およびユーザーに対する APPLY PASSWORD POLICY 権限
 
ここでは以下で適用できます。
USE ROLE SECURITYADMIN;
ALTER USER <ユーザー名> SET PASSWORD POLICY policies_db.password_policies.PASSWORD_POLICY_PROD_1;
パスワードポリシーについては、以下でも紹介されていますので、あわせてご参照ください。
セッションポリシー
Snowflake ではセッションポリシーとして以下を制御できます。
- SESSION_IDLE_TIMEOUT_MINS
- Snowflakeクライアントおよびプログラムクライアントからの接続ユーザーが再度認証する必要があるまでにセッションがアイドル状態になる分数
 - デフォルトは240分(4時間)
 
 - SESSION_UI_IDLE_TIMEOUT_MINS
- Snowsight への接続ユーザーが再度認証する必要があるまでにセッションがアイドル状態になる分数
 - デフォルトは240分(4時間)
 
 - ALLOWED_SECONDARY_ROLES
- セッション内で使用できるセカンダリ ロールを指定
 
 
タイムアウトについては、それぞれデフォルトで4時間となっているので、こちらも組織の要件に応じて短く設定するなどの制御が可能です。
セカンダリーロールについては後述します。
セカンダリ ロール
Snowflake ではセカンダリ ロールとして、ユーザーが切り替え可能なすべてのロール権限で操作可能な機能が提供されています。
例として、これまでの設定の状態で以下のユーザーを作成します。
USE ROLE USERADMIN;
CREATE USER test_user
    DEFAULT_ROLE = PUBLIC
    TYPE = PERSON
    PASSWORD='<パスワード>'
    DEFAULT_SECONDARY_ROLES = ( 'ALL' )
;
--SECURITYADMIN を付与
USE ROLE SECURITYADMIN;
GRANT ROLE SECURITYADMIN TO USER test_user;
DEFAULT_SECONDARY_ROLES = ( 'ALL' )として、ユーザーが自分に関連付けられているロールのすべての権限に同時にアクセスできるような設定としています。
この状態で test_user としてログインすると下図のように現在のロールが PUBLIC であっても、このユーザー自身は SECURITYADMIN での操作もできるので、SECURITYADMIN で表示されるポリシー管理のデータベースや各ポリシースキーマが表示されています。

他にも、明示的に PUBLIC ロールを指定したとしても切り替え可能な SECURITYADMIN で表示できる各ポリシーを表示することも可能です。この場合、PUBLIC ロールはプライマリ ロールと呼ばれます。

セカンダリ ロールの特徴として、CREATE 文の実行はプライマリ ロールの権限で承認されます。下図の場合、プライマリ ロールである PUBLIC はセッションポリシーを作成する権限がないのでエラーとなります。

注意点として、オブジェクトの削除などその他のアクションはプライマリ ロールに権限がなくても実行可能となります。

ユーザーのDEFAULT_SECONDARY_ROLES設定値を特に指定していない場合、2025年1月のアップデートでDEFAULT_SECONDARY_ROLES=('ALL')として変更されています。
上記のように、オブジェクトの CREATE はできませんが、プライマリまたはセカンダリ ロールに付与された権限でアクションが承認されるため、より上位の階層権限を持つユーザーであるほど、想定外のロールが有効になることで、意図しない操作や誤操作によるデータの変更や削除のリスクが高まる可能性があります。
セッションポリシーの ALLOWED_SECONDARY_ROLES では、このためにセッション内で使用できるセカンダリ ロールを指定することも可能です。
セッションポリシーの作成
ここでは、以下の設定でセッションポリシーを設定してみます。
- アカウント全体に適用する認証ポリシー
- セッションでセカンダリ ロールのアクティブ化を禁止する
 
 
今回の設定では、ポリシー管理者ロール(session_policy_admin)でセッションポリシーを作成するので、以下のコマンドでポリシーを作成します。
USE ROLE session_policy_admin;
USE SCHEMA policies_db.session_policies;
--アカウント全体に適用する認証ポリシー
CREATE SESSION POLICY block_secondary_roles
ALLOWED_SECONDARY_ROLES = (); --空とすることでセカンダリロールを許可しない
セッションポリシーの適用:アカウントレベル
セッションポリシーをアカウントに適用する際に必要な権限は以下です。
- アカウントに対する  APPLY SESSION POLICY
- デフォルトでは SECURITYADMIN 以上に付与
 - Global privileges (account-level privileges)|Snowflake DOCUMENTATION
 
 
その他のポリシーと同様に、今回であればポリシーの適用には SECURITYADMIN を使用する設定なので、以下のコマンドでアカウント全体に対するセッションポリシーを有効化できます。
--アカウントレベルでパスワードポリシーを適用 
USE ROLE SECURITYADMIN;
ALTER ACCOUNT SET SESSION POLICY policies_db.session_policies.block_secondary_roles;
--アクティブなパスワードポリシーを一覧
USE ROLE ACCOUNTADMIN;
SELECT *
FROM TABLE(
  policies_db.INFORMATION_SCHEMA.POLICY_REFERENCES(
    POLICY_NAME => 'policies_db.session_policies.block_secondary_roles'
  ));
--無効化
ALTER ACCOUNT UNSET SESSION POLICY;
この状態で先のユーザーで画面更新するとセカンダリ ロールはブロックされ、PUBLIC ロールの権限範囲の表示に変わります。

先は実行できた以下も当然エラーとなります。

明示的なセカンダリ ロールの指定もできなくなります。

セッションポリシーの適用:ユーザーレベル
今回の設定でセッションポリシーを個々のユーザーに対して設定するには、以下の権限が必要です。
- セッションポリシーの所有者権限およびユーザーに対する APPLY SESSION POLICY 権限
 
ここでは以下で適用できます。
USE ROLE SECURITYADMIN;
ALTER USER <ユーザー名> SET SESSION POLICY policies_db.session_policies.block_secondary_roles;
ポリシー適用にストアドプロシージャを使用する
今回の設定では、ポリシー作成・管理をカスタムロール、アカウントやユーザーへのポリシー適用には、アカウントレベルの操作権限やユーザーの所有者権限が必要なため SECURITYADMIN を使用していました。
運用ルール次第でもあると思いますが、都度 SECURITYADMIN への切り替えが必要なので、誤操作などのリスクがないわけではありません。ポリシー管理ロールにポリシーの適用まで任せる際にアカウントレベルの権限の付与やユーザーの所有者権限を渡すのが気になる際や、より厳格な運用とする場合、ストアドプロシージャで処理をラッピングすることも選択肢の一つとして考えられます。
Snowflake ではストアドプロシージャを作成すると、デフォルトでは所有者権限で実行されるので、ポリシー適用プロシージャを作成し、その使用権限をポリシー管理者に与えることで、限定的に必要な権限を渡すこともできます。
ここではネットワークポリシーを例にストアドプロシージャを定義してみます。
USE ROLE ACCOUNTADMIN;
USE SCHEMA policies_db.network_rules;
--アカウントにネットワークポリシーを適用
CREATE OR REPLACE PROCEDURE set_net_policy_on_account(net_policy_name VARCHAR)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
AS
$$
BEGIN
    LET sql string := 'ALTER ACCOUNT SET NETWORK_POLICY = '|| :net_policy_name;
    EXECUTE IMMEDIATE :sql;
EXCEPTION
  WHEN OTHER THEN
  RAISE;
END;
$$
;
--アカウントからネットワークポリシーを解除
CREATE OR REPLACE PROCEDURE unset_net_policy_on_account()
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
AS
$$
    ALTER ACCOUNT UNSET NETWORK_POLICY;
$$
;
--ユーザーにネットワークポリシーを適用
CREATE OR REPLACE PROCEDURE set_net_policy_on_user(net_policy_name VARCHAR, user_name VARCHAR)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
AS
$$
BEGIN
    LET sql string := 'ALTER USER ' || :user_name || ' SET NETWORK_POLICY = '|| :net_policy_name;
    EXECUTE IMMEDIATE :sql;
EXCEPTION
  WHEN OTHER THEN
  RAISE;
END;
$$
;
--ユーザーからネットワークポリシーを解除
CREATE OR REPLACE PROCEDURE unset_net_policy_on_user(user_name VARCHAR)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
AS
$$
BEGIN
    LET sql string := 'ALTER USER ' || :user_name || ' UNSET NETWORK_POLICY';
    EXECUTE IMMEDIATE :sql;
EXCEPTION
  WHEN OTHER THEN
  RAISE;
END;
$$
;
ポリシー管理ロールに使用権限を与えます。
USE ROLE SECURITYADMIN;
GRANT USAGE ON ALL PROCEDURES IN SCHEMA policies_db.network_rules TO ROLE network_rule_admin;
SHOW GRANTS TO ROLE network_rule_admin;
動作を確認してみます。
- アカウントレベル
 
USE ROLE network_rule_admin;
USE SCHEMA policies_db.network_rules;
--現在の状態を確認
>SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT;
+----------------+-------+---------+-------+-----------------------------------------------+--------+
| key            | value | default | level | description                                   | type   |
|----------------+-------+---------+-------+-----------------------------------------------+--------|
| NETWORK_POLICY |       |         |       | Network policy assigned for the given target. | STRING |
+----------------+-------+---------+-------+-----------------------------------------------+--------+
--ストアドプロシージャでアカウントにポリシーを適用
>CALL set_net_policy_on_account('PERSON_USER_NET_POLICY');
>SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT;
+----------------+------------------------+---------+---------+-----------------------------------------------+--------+
| key            | value                  | default | level   | description                                   | type   |
|----------------+------------------------+---------+---------+-----------------------------------------------+--------|
| NETWORK_POLICY | PERSON_USER_NET_POLICY |         | ACCOUNT | Network policy assigned for the given target. | STRING |
+----------------+------------------------+---------+---------+-----------------------------------------------+--------+
--ストアドプロシージャでアカウントのポリシーを解除
>CALL unset_net_policy_on_account();
>SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT;
+----------------+-------+---------+-------+-----------------------------------------------+--------+
| key            | value | default | level | description                                   | type   |
|----------------+-------+---------+-------+-----------------------------------------------+--------|
| NETWORK_POLICY |       |         |       | Network policy assigned for the given target. | STRING |
+----------------+-------+---------+-------+-----------------------------------------------+--------+
- ユーザーレベル
 
USE ROLE network_rule_admin;
USE SCHEMA policies_db.network_rules;
--現在の状態を確認
USE ROLE USERADMIN;
>SHOW PARAMETERS LIKE 'NETWORK_POLICY' FOR USER test_user;
+----------------+-------+---------+-------+-----------------------------------------------+--------+
| key            | value | default | level | description                                   | type   |
|----------------+-------+---------+-------+-----------------------------------------------+--------|
| NETWORK_POLICY |       |         |       | Network policy assigned for the given target. | STRING |
+----------------+-------+---------+-------+-----------------------------------------------+--------+
--ストアドプロシージャでユーザーにポリシーを適用
USE ROLE network_rule_admin;
CALL set_net_policy_on_user('person_user_net_policy','test_user');
--現在の状態を確認
USE ROLE USERADMIN;
>SHOW PARAMETERS LIKE 'NETWORK_POLICY' FOR USER test_user;
+----------------+------------------------+---------+-------+-----------------------------------------------+--------+
| key            | value                  | default | level | description                                   | type   |
|----------------+------------------------+---------+-------+-----------------------------------------------+--------|
| NETWORK_POLICY | PERSON_USER_NET_POLICY |         | USER  | Network policy assigned for the given target. | STRING |
+----------------+------------------------+---------+-------+-----------------------------------------------+--------+
--ストアドプロシージャでユーザーのポリシーを解除
USE ROLE network_rule_admin;
CALL unset_net_policy_on_user('test_user');
--現在の状態を確認
USE ROLE USERADMIN;
>SHOW PARAMETERS LIKE 'NETWORK_POLICY' FOR USER test_user;
+----------------+-------+---------+-------+-----------------------------------------------+--------+
| key            | value | default | level | description                                   | type   |
|----------------+-------+---------+-------+-----------------------------------------------+--------|
| NETWORK_POLICY |       |         |       | Network policy assigned for the given target. | STRING |
+----------------+-------+---------+-------+-----------------------------------------------+--------+
ストアドプロシージャ経由でポリシーの設定・設定解除ができました。
さいごに
Snowflake のアカウント保護に関するポリシーの概要と設計について考えてみました。ストアドプロシージャを使用するなど、どこまで厳格とするかは組織によると思いますが、こちらの内容が何かの参考になれば幸いです。







