セキュア UDFs とストアドプロシージャの使用による機密情報の保護¶
機密情報にアクセスしてはならないユーザーから機密情報を確実に隠すために、ユーザー定義関数(UDF)とストアドプロシージャを作成するときに SECURE キーワードを使用できます。
このトピックでは、次の方法について説明します。
このトピックの内容:
UDF またはプロシージャー定義の可視性の制限¶
UDF またはストアドプロシージャの場合は、ユーザーが定義の詳細を表示できないようにすることができます。UDF またはプロシージャがセキュアであることを指定すると、これらの詳細は承認されたユーザー、つまり関数を所有するロールを付与されたユーザーのみに表示されます。
たとえば、セキュアな関数またはプロシージャの場合、未承認のユーザーに対して省略される情報には次のものがあります。
本文(ロジックを構成するハンドラーコード)
インポートのリスト
ハンドラー名
パッケージリスト
未承認のユーザーは、次の情報を引き続き表示できます。
パラメーターの型
戻り型
ハンドラー言語
Null処理
ボラティリティ
ロールの付与について詳しくは、 GRANT ROLE と アクセス制御の概要 をご参照ください。
セキュアな関数またはプロシージャでは、未承認のユーザー、つまり関数またはプロシージャを所有するロールを付与 されていない ユーザーは、次のいずれかを使用する場合に関数またはプロシージャの定義を表示できません。
UDFs の場合
SHOW FUNCTIONS および SHOW USER FUNCTIONS コマンド
DESCRIBE FUNCTION コマンド
FUNCTIONS Information Schemaビュー
プロシージャの場合
SHOW PROCEDURES コマンド
DESCRIBE PROCEDURE コマンド
PROCEDURES Information Schemaビュー
両方の場合
ハンドラーがJava、Python、またはScalaで記述されている関数とプロシージャでは、Snowflakeステージからコードまたはデータファイルをインポートする IMPORTS 句が許可されていることに注意してください。SECURE キーワードを使用しても、これらのステージの可視性やアクセスには影響 しません。
さらに、ハンドラーがJava、Python、またはScalaで記述されている関数とプロシージャの場合、関数とプロシージャーをセキュアにすると、リソースがそれらの間で共有されないように、個別のサンドボックスで実行されることが保証されます。
SECURE キーワードの使用の詳細については、 セキュア UDF またはストアドプロシージャの作成 をご参照ください。
UDF の機密データ可視性の制限¶
UDFs では、 UDF をセキュアにすると、非表示にする必要があるデータをユーザーに表示しないようにすることができます。これを実行するには、 UDF を作成または変更するときに SECURE キーワードを使用します。
データプライバシーのために特に指定されている場合は、 UDF をセキュアと定義します(つまり、基になるテーブルのすべてのユーザーに公開されるべきではない機密データへのアクセスを制限するため)。
ユーザーが基になるデータ表現を理解する必要のないデータのクエリを簡素化するために作成された場合など、クエリの利便性のために定義されている場合は、 UDF をセキュアに しないでください。これは、Snowflakeクエリオプティマイザーが安全な UDFs を評価するときに、通常の UDFs に使用される最適化をバイパスするためです。これにより、安全な UDFs のクエリパフォーマンスが低下する可能性があります。
UDF の基になるデータの可視性を制限するには、作成または変更するときに SECURE キーワードを使用します。詳細については、 セキュア UDF またはストアドプロシージャの作成 をご参照ください。
データが公開されるしくみ¶
プッシュダウン と呼ばれる最適化など、一部の UDFs の内部最適化では、ベーステーブルの基になるデータへのアクセスが必要です。このアクセスにより、 UDF のユーザーから隠されたデータが、プログラムによる方法を介して間接的に公開される可能性があります。特定の状況では、ユーザーには直接表示されない行に関する情報を推測できる場合があります。
セキュア UDFs はこれらの最適化を使用しないため、ユーザーが基になるデータにアクセスすることは間接的にもありません。プッシュダウンの詳細については、 プッシュダウンの最適化およびデータの可視化 をご参照ください。
Tip
安全な UDF を使用するかどうかを決定するときは、 UDF の目的を考慮し、データのプライバシー/セキュリティとクエリパフォーマンスのトレードオフを検討する必要があります。
また、データの機密性が高く、ある型のオブジェクト( UDFsなど)を介したアクセスを保護する必要があると判断した場合、他の型のオブジェクト(ビューなど)を介したアクセスも保護することを必ず検討する必要があります。
例えば、安全な UDFs が特定のテーブルへのアクセスのみを許可する場合、同じテーブルへのアクセスを許可するビューもすべて安全である必要があります。
セキュア UDFs がデータを保護するしくみ¶
プッシュダウンの最適化およびデータの可視化 で説明されているように、プッシュダウン最適化では、クエリの処理方法を決定するフィルタの順序を変更できます。データの保護に使用される適切なフィルターが適用される前に、一般的なフィルターを実行できる最適化がフィルターの順序を変更すると、基になる詳細が公開される可能性があります。したがって、解決策としては、最適化が安全でない場合には、オプティマイザーが特定の型のフィルターをプッシュダウンしないようにすることです(より一般的には、フィルタープッシュダウンを含むがこれに限定されない特定の型の最適化をオプティマイザーが使用できないようにする)。
UDF を「安全」と宣言すると、オプティマイザーは特定のフィルターをプッシュダウンしません(より一般的には、特定の最適化を使用しない)。ただし、特定の型の最適化を防止すると、パフォーマンスに影響を与える可能性があります。
機密データへのアクセスを保護するためのベストプラクティス¶
安全な UDFs は、関数によってフィルタリングされたテーブルの行のデータがユーザーに表示される可能性を防ぎます。ただし、 UDFs を慎重に構築しないと、データ所有者が基礎となるデータに関する情報を誤って公開してしまう可能性はまだあります。このセクションでは、回避すべき潜在的な落とし穴について説明します。
シーケンスによって生成された列の値を公開しない¶
代理キーを生成する一般的な方法は、シーケンス列または自動インクリメント列を使用することです。これらのキーが、基礎となるデータのすべてにアクセスできないユーザーに公開されている場合、ユーザーは基礎となるデータ分布の詳細を推測できる可能性があります。
例えば、ID列を公開する関数 get_widgets_function()
があるとします。シーケンスからIDが生成される場合、 get_widgets_function()
のユーザーは、ユーザーがアクセスできる2つのウィジェットの作成タイムスタンプ間に作成されたウィジェットの総数を推測できます。次のクエリと結果について考えてみましょう。
select * from table(get_widgets_function()) order by created_on;
------+-----------------------+-------+-------+-------------------------------+
ID | NAME | COLOR | PRICE | CREATED_ON |
------+-----------------------+-------+-------+-------------------------------+
...
315 | Small round widget | Red | 1 | 2017-01-07 15:22:14.810 -0700 |
1455 | Small cylinder widget | Blue | 2 | 2017-01-15 03:00:12.106 -0700 |
...
結果に基づいて、ユーザーは1139ウィジェット(1455 - 315
)が1月7日から1月15日の間に作成されたと疑う可能性があります。この情報が機密性が高すぎて関数のユーザーに公開できない場合、次のいずれかの方法を使用できます。
シーケンス生成列を関数の一部として公開しない。
シーケンスによって生成された値の代わりに、ランダム化された識別子(UUID_STRING により生成)を使用する。
プログラムで識別子を難読化する。
スキャンされたデータサイズへの可視性を制限する¶
安全な関数を含むクエリの場合、Snowflakeはスキャンされたデータの量(バイトまたはマイクロパーティションのいずれか)またはデータの合計量を公開しません。これは、データのサブセットのみにアクセスできるユーザーから情報を保護するためです。
ただし、ユーザーはクエリのパフォーマンス特性に基づいて、基礎となるデータの量について観察することができます。例えば、2倍の長さで実行されるクエリは、2倍のデータを処理する可能性があります。そのような観察結果は良くても概算程度ですが、場合によっては、このレベルの情報でさえ公開されることは望ましくありません。
このような場合は、ベースデータの関数をユーザーに公開するのではなく、ユーザー/ロールごとにデータを具体化する必要がありますこのトピックで説明されている widgets
テーブルでは、ウィジェットにアクセスできるロールごとにテーブルが作成されます。これらの各テーブルには、そのロールがアクセスできるウィジェットのみが含まれ、ロールにはそのテーブルへのアクセス権が付与されます。これは、単一の機能を使用するよりもはるかに複雑ですが、非常に高いセキュリティの状況では、これが必要になる場合があります。
安全な UDFs およびマスキングポリシー¶
UDF が安全な UDF であるかどうかに関係なく、 UDF を使用する場合は、 マスキングポリシー で、列、 UDF、およびマスキングポリシーのデータ型が一致していることを確認します。
詳細については、 マスキングポリシー内のユーザー定義関数 をご参照ください。
セキュア UDF またはストアドプロシージャの作成¶
UDF またはプロシージャーを作成または変更するときに SECURE キーワードを使用すると、それらをセキュアにすることができます。
UDF を作成または変換してセキュアにするには、以下を使用するときに SECURE を指定します。
プロシージャを作成してセキュアにするには、次を使用するときに SECURE を指定します。
UDF またはプロシージャがセキュアかどうかの判断¶
SHOW FUNCTIONS または SHOW PROCEDURES コマンドを使用して、関数またはプロシージャがセキュアかどうかを判断できます。コマンドは、IS_SECURE 列を含むテーブルを返します。値は、セキュアの場合は Y
、セキュアではない場合は N
です。
次の例のコードは、 MYFUNCTION
関数のプロパティのテーブルを返します。
show functions like 'MYFUNCTION';
クエリプロファイルでのセキュリティ機能の詳細の表示¶
安全な関数の内部は、 クエリプロファイル (ウェブインターフェイス内)で公開されません。非所有者は所有者のクエリプロファイルにアクセスできるため、これは安全な関数の所有者にも当てはまります。