Snowflake Secretsとは
SnowflakeのSecretは、APIキーやパスワードといった機密情報を格納するためのスキーマレベルのオブジェクトです。
なぜこの機能が登場したのか
Snowflakeはここ最近、アプリケーションやデータパイプラインをSnowflake内で直接開発できる機能を続々とリリースしています。
- Snowpark Container Servicesにより、任意のプログラミング言語でカスタムアプリケーションを実行可能になりました。
- Snowpark for Pythonは、ELT/ETLパイプライン全体を含むデータエンジニアリング用途で広く採用されつつあります。
- メール、Slack、Microsoft Teams(Webhook経由)でアラートを送信できるようになりました。
- Snowflakeから外部インターネットへのAPI呼び出しが可能になり、SnowflakeアカウントからOpenAI APIを利用するユーザーも増えています。
これらのユースケースではいずれも、各種アプリケーションやサービスへ認証するためにシークレットの保管とアクセスが欠かせません。
Snowflakeでシークレットを管理するメリット
- Snowflakeで作成したシークレットには、使い慣れたSnowflakeのRBACをそのまま適用できます(例:
grant usage on secret to role <role>)。 - シークレットがアプリケーションやパイプラインのコードと同じ場所に存在するため、別途管理すべきシステムが増えません。
- AWS Secrets Managerなどの外部シークレットマネージャーを利用するにしても、そもそもその認証手段を簡潔に整える必要があり、ハードルが高くなりがちです。
Snowflake Secretの作成方法
Snowflakeで作成できるシークレットは4種類あり、種類ごとにDDLが少しずつ異なります。
OAuth
構文
CREATE [ OR REPLACE ] SECRET [ IF NOT EXISTS ] <name>
TYPE = OAUTH2
API_AUTHENTICATION = <security_integration_name>
OAUTH_SCOPES = ( '<scope_1>' [ , '<scope_2>' ... ] )
[ COMMENT = '<string_literal>' ]
例
-- Assume an integration exists:
CREATE OR REPLACE SECURITY INTEGRATION my_oauth2_integration
TYPE = API_AUTHENTICATION
AUTH_TYPE = OAUTH2
ENABLED = TRUE
OAUTH_CLIENT_ID = 'your_client_id'
OAUTH_CLIENT_SECRET = 'your_client_secret'
OAUTH_TOKEN_ENDPOINT = 'https://oauth2.example.com/token'
OAUTH_ALLOWED_SCOPES = ('scope1', 'scope2');
-- create the secret
CREATE OR REPLACE SECRET my_oauth2_secret
TYPE = OAUTH2
API_AUTHENTICATION = my_oauth2_integration
OAUTH_SCOPES = ('scope1', 'scope2')
コードを展開
クラウドプロバイダー
構文
CREATE [ OR REPLACE ] SECRET [ IF NOT EXISTS ] <name>
TYPE = CLOUD_PROVIDER_TOKEN
API_AUTHENTICATION = '<cloud_provider_security_integration>'
[ COMMENT = '<string_literal>' ]
例
-- assume this integration exists called test_integration:
CREATE OR REPLACE SECRET test_secret
TYPE = CLOUD_PROVIDER_TOKEN
API_AUTHENTICATION = 'TEST_INTEGRATION';
Basic認証
構文
CREATE [ OR REPLACE ] SECRET [ IF NOT EXISTS ] <name>
TYPE = PASSWORD
USERNAME = '<username>'
PASSWORD = '<password>'
[ COMMENT = '<string_literal>' ]
例
CREATE OR REPLACE SECRET my_password_secret
TYPE = PASSWORD
USERNAME = 'db_user'
PASSWORD = 'MySecurePass123!'
COMMENT = 'Database credentials for application access';
汎用文字列
構文
CREATE [ OR REPLACE ] SECRET [ IF NOT EXISTS ] <name>
TYPE = GENERIC_STRING
SECRET_STRING = '<string_literal>'
[ COMMENT = '<string_literal>' ]
例
CREATE OR REPLACE SECRET my_string_secret
TYPE = GENERIC_STRING
SECRET_STRING = 'my-secret-api-key-123'
COMMENT = 'API key for service authentication';
コードからSnowflake Secretを使う方法
シークレットの取得に対応しているのはJavaとPythonのみです。Snowpark Container Servicesで他言語のアプリケーションをホストしている場合は、JavaまたはPythonで小さなカスタムモジュールを用意し、そこでシークレットを取得して値をアプリケーションに渡す形になります。
以下は、Pythonでシークレットを取得する例です。
ステップ1:名前でシークレットを取得する関数を作成
CREATE OR REPLACE FUNCTION get_secret_by_name(secret_name STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
HANDLER = 'get_secret_by_name'
EXTERNAL_ACCESS_INTEGRATIONS = (external_access_integration)
AS
$$
import _snowflake
def get_secret_by_name(secret_name):
username_password_object = _snowflake.get_username_password(secret_name)
username_password_dictionary = {}
username_password_dictionary["Username"] = username_password_object.username
コードを展開
ステップ2:関数を呼び出す
1SELECT get_secret_by_name('jeffs_credentials');
通知統合/Webhookでシークレットを利用する
SlackやMicrosoft TeamsなどのWebhookにアラートを送る際、Snowflakeでは通知統合(Notification Integration)にシークレットをシンプルに渡せる仕組みが用意されています。
create notification integration ステートメントの WEBHOOK_SECRET 引数に、完全修飾名 database.schema.<secret_name> を指定するだけです。例:
CREATE OR REPLACE NOTIFICATION INTEGRATION my_slack_webhook_int
TYPE=WEBHOOK
ENABLED=TRUE
WEBHOOK_URL='https://hooks.slack.com/services/SNOWFLAKE_WEBHOOK_SECRET'
WEBHOOK_SECRET=my_secrets_db.my_secrets_schema.my_slack_webhook_secret
WEBHOOK_BODY_TEMPLATE='{"text": "SNOWFLAKE_WEBHOOK_MESSAGE"}'
WEBHOOK_HEADERS=('Content-Type'='application/json');
Snowflakeでのシークレット運用
シークレットの一覧表示
show secrets コマンドで、すべてのシークレットを一覧表示できます。
show secrets; -- shows all secrets in account
show secrets in account; -- verbose way of `show secrets`
show secrets in database analytics; -- shows secrets for a database named analytics
シークレットの削除
drop コマンドでシークレットを削除できます。
drop secret my_oauth2_secret; -- this works if your worksheet or connection has a database and schema context set.
drop secret <fully qualified secret name> -- this will always work
シークレットの変更
alter secretは、キーやパスワードのローテーション、その他シークレットの各種属性を変更する際に使用します。
1alter secret <fully qualitfied secret name> set <parameter> = <value>;
シークレットの詳細確認
describe secret <fully qualified secret name> を実行すると、以下のフィールドが返されます。
- created on
- name
- schema_name
- database_name
- owner
- comment
- secret_type
- username
- oauth_access_token_expiry_time
- oauth_refresh_token_expiry_time
- oauth_scopes
- integration_name
シークレットをSnowflake内で直接管理できれば、アプリケーション・パイプライン・アラートを開発する際の機密情報の取り扱いを大幅に効率化できます。
次回はこの知識をもとに、SnowflakeからSlackへアラートを送る仕組みを実際に構築していきます。
Jeffはデータ&アナリティクス分野のコンサルタントで、インサイトの自動化やデータドリブンな業務プロセス運用において15年以上の経験を持ちます。技術スタックではSnowflake + dbt + Tableauを得意とし、業界としては公益事業、臨床試験、出版、CPG、製造業での実績があります。お気軽にご連絡ください:[email protected]。