dbt cloudからSnowflakeへのOAuth接続を試してみた

dbt cloudで開発者がSnowflakeに接続するための認証方法としてOAuthを使う方法を試してみました。
2022.02.21

こんにちは、nkhrです。

今回は、SnowflakeのSecurity Integration(Snowflake OAuth for custom clients)を利用して、dbt cloudからSnowflakeへの接続を試してみます。

dbt cloudからSnowflakeへのアクセス認証方法には、以下の3パターンがあります。

  • Snowflake Username&Pasword登録
  • Snowflake KeyPair登録
  • SSO Login設定 (Snowflake Security Integrationの利用)
    • Development(開発)のみで利用可能
    • Deployment(デプロイ)にはCredentials(Username&PasswordまたはKeyPair)の設定が必要

今回の設定は、dbt cloud自体へのSSOではありません。dbt cloud→SnowflakeへのSSO Login(今回試すところ)は、どのPlanでも実行できます(2021/02/21修正:DatabaseのSSO LoginもEnterprise planの対象となるようです(ドキュメント参照)。dbt cloud自体へのSSOログインも、Enterprise版が必要です。

設定前に知っておくと嬉しいこと

SSO Loginを設定したら何がうれしいの?

以下の点がメリットになるかなと思います。

  • dbt cloudに、SnowflakeのUser&PasswrodやKeyPairの登録不要
  • SnowflakeユーザでMFAを有効化している場合は、MFA認証(モバイルアプリのPush通知のApprove)回数を減らせる

DevelopmentとDeploymentって何が違うの?

今回設定するSSO Loginの対象は、Development(開発)で利用する各ログインユーザごとのSnowflakeアクセス認証です。Deployment(デプロイ)は対象としません。

DevelopmentとDeploymentとは何でしょうか。DevelopmentとDeploymentは、Environment(環境)で設定するTypeの違いです。EnvironmentのTypeの違いは、Develop(IDE)で利用される設定か、Jobで利用される設定かの違いになります。

  • Environment Type: Development (開発)
    • Develop(dbt cloudのIDE)で使われるEnvironement
    • Projectで1つのみ作成可能
    • CrendetialsとSchemaはログインユーザごとのProfileで設定(今回のSSO Loginはこちらに対応)
  • Environment Type: Deployment (デプロイ)
    • Job で使われるEnvironment
    • Projectで複数作成が可能
    • Environmentコンポーネント内で、CredentialsとSchemaの設定を保持

Snowflake設定

SnowflakeではSecurity Integrationの方法がいくつかあります。dbt cloudではSnowflake OAuth for custom clientsを利用します。

Security Integrationオブジェクトの作成

Integrationオブジェクトの作成は、デフォルトではACCOUNTADMINのみ実行可能です。

USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE SECURITY INTEGRATION DBT_CLOUD_OAuth
    TYPE = OAUTH
    OAUTH_CLIENT = CUSTOM
    OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
    OAUTH_REDIRECT_URI = 'https://cloud.getdbt.com/complete/snowflake'
    OAUTH_ALLOW_NON_TLS_REDIRECT_URI = FALSE
    ENABLED = TRUE
    OAUTH_ISSUE_REFRESH_TOKENS = TRUE
    OAUTH_REFRESH_TOKEN_VALIDITY = 86400
    BLOCKED_ROLES_LIST = ('SYSADMIN', 'USERADMIN')
    OAUTH_ENFORCE_PKCE = FALSE
    -- PRE_AUTHORIZED_ROLES_LIST = ( '<role_name>' [ , '<role_name>' , ... ] ) ]
    -- OAUTH_USE_SECONDARY_ROLES = IMPLICIT | NONE
    -- NETWORK_POLICY = '<network_policy>'
    -- OAUTH_CLIENT_RSA_PUBLIC_KEY = <public_key1> 
    -- OAUTH_CLIENT_RSA_PUBLIC_KEY_2 = <public_key2> 
    COMMENT = 'For dbt cloud OAuth' 
;

SHOW INTEGRATIONS;
  • 利用不可のROLE設定(BLOCKED_ROLES_LIST)
    • デフォルトでACCOUNTADMINとSECURITYADMINはブラックリストに設定されており、削除できない仕様です。ビジネス上、必要な場合はサポート連絡によりブラックリストから解除できます。
    • 上記のROLEは、PRE_AUTHORIZED_ROLES_LISTにも設定不可です。
  • セカンダリロールの利用(OAUTH_USE_SECONDARY_ROLES)
    • Secundary Roleをセッションで有効にしたい場合は、「OAUTH_USE_SECONDARY_ROLES = IMPLICIT」とします。
  • 接続元IP制限(NETWORK_POLICY)
    • Snowflakeへ接続可能なIPアドレスを制限できます。
    • INTEGRATIONでのNETWORK POLICYを設定しない場合、アカウントに設定されているNETWORK POLICYが有効になります。
  • TSL保護URLのみへのリダイレクト許可
    • デフォルトでは、TSLで保護されていないURLを「OAUTH_REDIRECT_URI」に設定できます。
    • TSL保護されたURLへのリダイレクトのみを許可する場合は「OAUTH_ALLOW_NON_TLS_REDIRECT_URI =TRUE」に設定します。
  • PKCEの必須設定(OAUTH_ENFORCE_PKCE)
    • OAUTHでPKCE(Proof Key for Code Exchange)を必須とする場合は、「OAUTH_ENFORCE_PKCE=TRUE」に設定します。デフォルトはFALSEです。dbt cloud用の設定ではFALSEにします(TRUEだと認証に失敗します)
      • PKCE(ぴくしー)は認可コードを横取りする攻撃 (authorization code interception attack) への対策手段です。
    • dbt cloudはアプリではなくWebサービスなので、この攻撃の前提に該当しないと思います。
  • TOKENのリフレッシュ許可(OAUTH_ISSUE_REFRESH_TOKENS)
    • TRUEに設定することで、TOKEN有効期限切れ時にTOKENのリフレッシュが可能です。
    • FALSEの場合は再認証が必要です。
  • リフレッシュTOKENの有効期限(OAUTH_REFRESH_TOKEN_VALIDITY)
    • 「OAUTH_ISSUE_REFRESH_TOKENS=TRUE」の場合のみ利用できるパラメータです
    • デフォルトは、7776000 (90days)です。

ClientID/ClientSecretの確認

Security Integrationオブジェクトを作成後に、dbt cloud側に設定するclient idとclient secretを取得します。

USE ROLE ACCOUNTADMIN;
with 
integration_secrets as (
  select parse_json(system$show_oauth_client_secrets('DBT_CLOUD_OAUTH')) as secrets
)

select
  secrets:"OAUTH_CLIENT_ID"::string     as client_id,
  secrets:"OAUTH_CLIENT_SECRET"::string as client_secret
from 
  integration_secrets;

dbt cloud設定

dbt cloudのProject作成または編集時に、SSO Loginを有効とするか設定できます。

Project Account Settingsの設定

メニューリストの[Account Settings]から対象のProjectを選択し[Edit]ボタンを表示して、Snowflake Connectionのリンクをクリックします。

Snowflake Connectionの編集画面で、[Edit]ボタンをクリックし、[ALLOW SSO LOGIN]のチェックボックスをONにします。

Development Credentialsの設定

ユーザごとのUser Profile>Development Credentials設定で「SSO」が選択できます。

AUTH METHODを「SSO」に変更し、「Connect Snowflake Account」をクリックすると、下記の画面が表示され「許可」によりSnowflakeのログイン画面へ遷移します。

まとめ

今回は、Snowflake Security Integrationを利用して、dbt cloudのDevelopment時の認証にSSO Loginを設定してみました。

以上、nkhrでした。

参考資料