パッケージポリシー

紹介

パッケージポリシーを使用すると、アカウントレベルでAnacondaからサードパーティのPythonパッケージの許可リストとブロックリストを設定できます。これにより、より厳しい監査やセキュリティ要件に対応できるようになり、環境内で利用可能なパッケージやブロックされるパッケージをより細かく制御できるようになります。

Snowpark PythonがどのようにAnacondaからサードパーティパッケージを取り込むことができるかの詳細については、 サードパーティパッケージの使用 をご参照ください。

Pythonの UDF、 UDTF、またはストアドプロシージャを作成する場合、許可リストとブロックリストはPython環境の作成時に考慮されます。許可リストとブロックリストは、Python環境を作成するのに必要なすべてのパッケージに適用されます。指定したパッケージで環境を作成できない場合、クエリは失敗します。

Pythonの UDF、 UDTF、またはストアドプロシージャを実行する場合、Snowflakeは許可リストとブロックリストをチェックし、すべてのパッケージがパッケージポリシーで許可されていることを確認します。それ以外の場合、クエリは失敗します。

制限事項

  • パッケージポリシーは、Anacondaの法的条件に同意した場合にのみ適用されます。

  • パッケージポリシーは、組み込み関数やネイティブアプリには適用されません。

パッケージポリシーの実装と使用

パッケージポリシーオブジェクトを作成するには、以下の権限が必要です。

  • パッケージポリシーの作成を予定しているデータベースとスキーマに対する USAGE。

  • パッケージポリシーの作成を予定しているスキーマに対する CREATE PACKAGES POLICY。

パッケージポリシーオブジェクトを作成した後に、それをアカウントに適用するには以下の権限が必要です。

  • パッケージポリシーオブジェクトの OWNERSHIP。

  • アカウントの APPLY PACKAGES POLICY。

次のステップに従って、パッケージポリシーを実装します。

ステップ1: パッケージポリシー管理者カスタムロールを作成する

ユーザーがパッケージポリシーを作成および管理できるようにするカスタムロールを作成します。このトピック全体を通して、カスタムロールの例には policy_admin という名前が付けられていますが、ロールには適切な名前を付けることができます。

カスタムロールがすでに存在する場合は、次のステップに進みます。

それ以外の場合は、 policy_admin カスタムロールを作成します。

use role useradmin;

create role policy_admin;
Copy

ステップ2: policy_admin カスタムロールに権限を付与する

policy_admin カスタムロールに次の権限がまだない場合は、以下に示すようにこれらの権限を付与します。

  • パッケージポリシーを含むデータベースとスキーマに対する USAGE。

  • パッケージポリシーを含むとスキーマに対する CREATEPACKAGESPOLICY。

  • アカウントの APPLY PACKAGES POLICY。

use role securityadmin;

grant usage on database yourdb to role policy_admin;

grant usage, create packages policy on schema yourdb.yourschema to role policy_admin;

grant apply packages policy on account to role policy_admin;
Copy

ステップ3: 新しいパッケージポリシーを作成する

policy_admin カスタムロールを使用して、言語、許可リスト、ブロックリストを指定した新しいパッケージポリシーを作成します。ALLOWLIST、 BLOCKLIST、 ADDITIONAL_CREATION_BLOCKLIST、 COMMENT はオプションのパラメーターです。デフォルトでは、許可リストの値は ('*') で、ブロックリストの値は () となります。

パッケージが許可リストとブロックリストの両方で指定されている場合、ブロックリストが優先されます。Pythonのランタイムバージョンを許可リストに明示的に追加する必要があり、親パッケージのすべてのパッケージと基になる依存関係も許可リストに明示的に追加する必要があります。

許可リストまたはブロックリストで ==<=>=<、または > などのバージョン指定子を使用することで、特定のパッケージのバージョン、またはバージョンの範囲を指定することができます。例: numpy>=1.2.3numpy==1.2.* のようなワイルドカードを使うことができます。これは、numpy 1.2のマイクロバージョンを意味します。

注釈

現在、許可リストまたはブロックリストでは、1つのパッケージにつき1つの範囲演算子しか指定できません。 pkg>1.0, <1.5 のように、複数の範囲演算子を指定することはサポートされていません。このため、あるパッケージバージョンの間隔を許可するようにポリシーを構成するには、許可リストに範囲の一方を設定し、ブロックリストに範囲のもう一方を設定します。たとえば、1.0より大きく1.5より小さいパッケージバージョンを許可するには、許可リストを pkg>1.0 に設定し、ブロックリストを pkg>1.5 に設定します。

USE ROLE policy_admin;

CREATE PACKAGES POLICY yourdb.yourschema.packages_policy_prod_1
  LANGUAGE PYTHON
  ALLOWLIST = ('numpy', 'pandas==1.2.3', ...)
  BLOCKLIST = ('numpy==1.2.3', 'bad_package', ...)
  ADDITIONAL_CREATION_BLOCKLIST = ('bad_package2', 'bad_package3', ...)
  COMMENT = 'Packages policy for the prod_1 environment'
;
Copy

条件:

yourdb.yourschema.packages_policy_prod_1

パッケージポリシーの完全修飾名。

LANGUAGE PYTHON

このパッケージポリシーが適用される言語。

ALLOWLIST = ('numpy', 'pandas==1.2.3', ...)

このパッケージポリシーの許可リスト。これは、パッケージの仕様をカンマで区切った文字列です。

BLOCKLIST = ('numpy==1.2.3', 'bad_package', ...)

このパッケージポリシーのブロックリスト。これは、パッケージの仕様をカンマで区切った文字列です。

ADDITIONAL_CREATION_BLOCKLIST = ('bad_package2', 'bad_package3', ...)

作成時にブロックされるパッケージ仕様のリストを指定します。このパラメーターの設定を解除するには、空のリストを指定します。 ADDITIONAL_CREATION_BLOCKLIST が設定されている場合は、作成時に基本の BLOCKLIST に追加されます。仮 UDFs と匿名ストアドプロシージャの場合、 ADDITIONAL_CREATION_BLOCKLIST は作成時と実行時の両方で BLOCKLIST に付加されます。

COMMENT = 'Packages policy for the prod_1 environment'

パッケージポリシーの目的を指定するコメント。

上の例では、作成時に適用されるブロックリストは ADDITIONAL_CREATION_BLOCKLISTBLOCKLIST になるので、ブロックされるパッケージは numpy==1.2.3bad_packagebad_package2bad_package3 になります。実行時に適用されるブロックリストは、 numpy==1.2.3bad_package になります。仮 UDFs と匿名ストアドプロシージャでは、 numpy==1.2.3bad_packagebad_package2bad_package3 を含むブロックリストが作成時と実行時の両方で適用されます。

Pythonパッケージの依存関係のリストを取得するには、 SHOW_PYTHON_PACKAGES_DEPENDENCIES 関数を使用します。最初のパラメーターは使用しているPythonランタイムのバージョンで、2番目は依存関係を表示するパッケージのリストです。たとえば、 numpy パッケージの依存関係を表示するには、このコマンドを使用します。

USE ROLE ACCOUNTADMIN;

select SNOWFLAKE.SNOWPARK.SHOW_PYTHON_PACKAGES_DEPENDENCIES('3.8', ['numpy']);
Copy

結果は依存関係とそのバージョンのリストです。

['_libgcc_mutex==0.1', '_openmp_mutex==5.1', 'blas==1.0', 'ca-certificates==2023.05.30', 'intel-openmp==2021.4.0',
'ld_impl_linux-64==2.38', 'ld_impl_linux-aarch64==2.38', 'libffi==3.4.4', 'libgcc-ng==11.2.0', 'libgfortran-ng==11.2.0',
'libgfortran5==11.2.0', 'libgomp==11.2.0', 'libopenblas==0.3.21', 'libstdcxx-ng==11.2.0', 'mkl-service==2.4.0',
'mkl==2021.4.0', 'mkl_fft==1.3.1', 'mkl_random==1.2.2', 'ncurses==6.4', 'numpy-base==1.24.3', 'numpy==1.24.3',
'openssl==3.0.10', 'python==3.8.16', 'readline==8.2', 'six==1.16.0', 'sqlite==3.41.2', 'tk==8.6.12', 'xz==5.4.2', 'zlib==1.2.13']

Snowpark環境でPython 3.8の依存関係を表示するには、パッケージを指定せずに関数を呼び出します。

select SNOWFLAKE.SNOWPARK.SHOW_PYTHON_PACKAGES_DEPENDENCIES('3.8', []);
Copy

関数がどのパッケージを使用しているかを知りたい場合は、 DESCRIBE FUNCTION を使用して印刷することができます。これは、パッケージの依存関係をすべて識別するための代替方法です。これを行うには、関数を作成し、パッケージ仕様で最上位のパッケージを指定します。次に、 DESCRIBE FUNCTION を使用して、すべてのパッケージとその依存関係のリストを取得します。このリストをコピーしてパッケージの許可リストに貼り付けることができます。パッケージポリシーを一時的に設定解除しておかないと、一部のパッケージがブロックされる可能性があることに注意してください。次の例は、「snowflake-snowpark-python」パッケージの依存関係を探す方法を示したものです。

create or replace function my_udf()
returns string
language python
packages=('snowflake-snowpark-python')
runtime_version=3.10
handler='echo'
as $$
def echo():
  return 'hi'
$$;

describe function my_udf();
Copy

利用可能なすべてのパッケージとバージョンを表示したい場合は、 INFORMATION_SCHEMA.PACKAGES ビューをクエリします。

select * from information_schema.packages;
Copy

現在使用しているパッケージのセットを確認したい場合は、この SQL ステートメントを使用します。

-- at the database level

CREATE OR REPLACE VIEW USED_ANACONDA_PACKAGES
ASSELECT FUNCTION_NAME, VALUE PACKAGE_NAME
FROM (SELECT FUNCTION_NAME,PARSE_JSON(PACKAGES)
PACKAGES FROM INFORMATION_SCHEMA.FUNCTIONS
WHERE FUNCTION_LANGUAGE='PYTHON') USED_PACKAGES,LATERAL FLATTEN(USED_PACKAGES.PACKAGES);

-- at the account level

CREATE OR REPLACE VIEW ACCOUNT_USED_ANACONDA_PACKAGES
ASSELECT  FUNCTION_CATALOG, FUNCTION_SCHEMA, FUNCTION_NAME, VALUE PACKAGE_NAME
FROM (SELECT FUNCTION_CATALOG, FUNCTION_SCHEMA, FUNCTION_NAME,PARSE_JSON(PACKAGES)
PACKAGES FROM SNOWFLAKE.ACCOUNT_USAGE.FUNCTIONS
WHERE FUNCTION_LANGUAGE='PYTHON') USED_PACKAGES,LATERAL FLATTEN(USED_PACKAGES.PACKAGES);
Copy

ステップ4: アカウントにパッケージポリシーを設定する

policy_admin カスタムロールを使って、 ALTER ACCOUNT コマンドでアカウントにポリシーを設定します。

use role policy_admin;

alter account set packages policy yourdb.yourschema.packages_policy_prod_1;
Copy

注釈

アカウントに設定済みのパッケージポリシーを置換するには、まずパッケージポリシーの設定を解除してから、そのアカウントに新しいパッケージポリシーを設定します。または、 FORCE を使うと、パッケージポリシーの設定を解除せずに、パッケージポリシーを設定することができます。例:

alter account set packages policy yourdb.yourschema.packages_policy_prod_2 force;
Copy

どのポリシーがアカウントでアクティブかを確認したい場合は、この SQL ステートメントを使用します。

select * from table(information_schema.policy_references(ref_entity_domain=>'ACCOUNT', ref_entity_name=>'<your_account_name>'))
Copy

このクエリの結果、 POLICY_STATUS という名前の列が表示されます。

DDL コマンドの実行に必要な権限

次のテーブルは、パッケージポリシー DDL 操作と必要な権限の関係をまとめたものです。

操作

必要な権限

パッケージポリシーを作成する

スキーマに対する CREATE PACKAGES POLICY 権限を持つロール。

パッケージポリシーを変更する

パッケージポリシーに対する OWNERSHIP 権限を持つロール。

パッケージポリシーをドロップする

パッケージポリシーに対する OWNERSHIP 権限を持つロール。

パッケージポリシーを記述する

パッケージポリシーに対する OWNERSHIP または USAGE 権限を持つロール。

パッケージポリシーを表示する

パッケージポリシーに対する OWNERSHIP または USAGE 権限を持つロール。

パッケージポリシーを設定および設定解除する

アカウントに対する APPLY PACKAGES POLICY 権限とパッケージポリシーに対する OWNERSHIP 権限を持つロール。

パッケージポリシー DDL

Snowflakeは、パッケージポリシーオブジェクトを管理するために次の DDL コマンドを提供します。

パッケージポリシーの可観測性

アカウントに設定されているパッケージポリシーに対するアクセス権がないユーザーが、そのコンテンツを閲覧することができます。

ユーザーは、パッケージポリシーに USAGE 権限を追加することで、誰がパッケージポリシーのコンテンツを閲覧できるかを制御できます。アカウント管理者またはパッケージポリシー所有者は、パッケージポリシーを使用する必要があるロールにこの権限を付与することができます。

CURRENT_PACKAGES_POLICY Information Schemaビューには、現行アカウントの各Snowparkパッケージポリシーの行が表示されます。

select * from information_schema.current_packages_policy;
Copy
+------+----------+-----------+-----------+-------------------------------+---------+
| NAME | LANGUAGE | ALLOWLIST | BLOCKLIST | ADDITIONAL_CREATION_BLOCKLIST | COMMENT |
+------+----------+-----------+-----------+-------------------------------+---------+
| P1   | PYTHON   | ['*']     | []        | [NULL]                        | [NULL]  |
+------+----------+-----------+-----------+-------------------------------+---------+