SELECTSELECT

SELECT

Snowflakeのシークレット管理:実践ガイド

By Jeff SkoldbergJan 24, 20254 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

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

Show all Secrets in Snowflake

シークレットの削除

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

Show all Secrets in Snowflake

シークレットの変更

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

Show all Secrets in Snowflake

シークレットをSnowflake内で直接管理できれば、アプリケーション・パイプライン・アラートを開発する際の機密情報の取り扱いを大幅に効率化できます。

次回はこの知識をもとに、SnowflakeからSlackへアラートを送る仕組みを実際に構築していきます。

Jeffはデータ&アナリティクス分野のコンサルタントで、インサイトの自動化やデータドリブンな業務プロセス運用において15年以上の経験を持ちます。技術スタックではSnowflake + dbt + Tableauを得意とし、業界としては公益事業、臨床試験、出版、CPG、製造業での実績があります。お気軽にご連絡ください:[email protected]