
dbt platform から Snowflake へ AWS PrivateLink で接続し、Network Policy で経路を制限してみた
かわばたです。
Snowflake への接続を AWS PrivateLink に限定している環境では、dbt platform からも PrivateLink で接続する必要があります。そのための Private endpoint を dbt 側に作る機能は、dbt platform の Enterprise+ プランの機能です。
本記事では、dbt platform から AWS PrivateLink 経由で Snowflake に接続します。あわせて、その接続が dbt 側の VPC endpoint を通っていることを、Snowflake 側の記録と Network Policy で確認します。public 接続を拒否する Network Policy の設定先は、共有アカウントへの影響を避けるため、ジョブ用ユーザー DBT_PL_SVC だけです。Snowflake アカウント全体の public 接続は無効化しません。
dbt platform の Private connectivity の概要
dbt platform の Private connectivity は、データプラットフォームなどにプライベート接続するための機能です。AWS、Azure、Google Cloud に対応しています。本記事で使うのは、そのうち AWS PrivateLink で Snowflake に接続する機能です。接続に使う VPC endpoint は、dbt Labs の AWS アカウントの中にあります。dbt platform では、この endpoint を Connection で選びます。その Connection を使う環境からの接続は、PrivateLink 経由です。
対応プランと要件
公式ドキュメントの記載を整理すると次のとおりです。
| 項目 | 内容 |
|---|---|
| dbt platform のプラン | Enterprise+、Virtual Private |
| Snowflake のエディション | Business Critical 以上 |
| クラウド | dbt platform と Snowflake が同じクラウドプロバイダーにあること |
| リージョン | 同じクラウドプロバイダー内なら、リージョンが違っても接続できる |
| Private endpoint の作成 | self-serve(Snowflake on AWS のみ)か、dbt Support への依頼 |
| Snowflake 側の許可 | dbt の AWS アカウントの許可を Snowflake Support に依頼する |
設定の流れ
- Snowflake の管理者が、dbt の AWS アカウントの許可を Snowflake Support に依頼する
SYSTEM$GET_PRIVATELINK_CONFIG()の出力を dbt platform に渡し、Private endpoint を作成する(Support-led では dbt Support に送る)- dbt platform の Connection で Private endpoint を選ぶ
- 必要に応じて、Snowflake の Network Policy で、対象ユーザーの接続元を dbt の VPC endpoint に制限する
前提条件
- dbt platform の Enterprise+ プラン(本記事は AWS のマルチテナント環境)
- dbt platform の Account admin 権限(Private endpoint、Connection、環境の作成に使います)
- Snowflake の Business Critical 以上のアカウント(AWS)
- Snowflake の ACCOUNTADMIN ロール(
SYSTEM$GET_PRIVATELINK_CONFIG()の実行と Network Policy の作成に使います) - Snowflake Support に起票できること
検証環境
| 項目 | 値 |
|---|---|
| dbt platform | Enterprise+、AWS us-east-1 |
| Snowflake | Business Critical、AWS_AP_NORTHEAST_1 |
事前準備
鍵ペアを作成する
dbt のジョブ用と Studio IDE 用に、鍵ペアを 2 組作ります。検証用のため、暗号化なしの PKCS#8 形式です。Git Bash で実行します。
mkdir -p ~/.snowflake/keys
# ジョブ用(DBT_PL_SVC)
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out ~/.snowflake/keys/rsa_key_dbt_pl_svc.p8 -nocrypt
openssl rsa -in ~/.snowflake/keys/rsa_key_dbt_pl_svc.p8 -pubout -out ~/.snowflake/keys/rsa_key_dbt_pl_svc.pub
# Studio IDE 用(DBT_PL_DEV)
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out ~/.snowflake/keys/rsa_key_dbt_pl_dev.p8 -nocrypt
openssl rsa -in ~/.snowflake/keys/rsa_key_dbt_pl_dev.p8 -pubout -out ~/.snowflake/keys/rsa_key_dbt_pl_dev.pub
# 公開鍵の本体を 1 行で表示する(CREATE USER の RSA_PUBLIC_KEY に貼る)
grep -v "PUBLIC KEY" ~/.snowflake/keys/rsa_key_dbt_pl_svc.pub | tr -d '\n'; echo
grep -v "PUBLIC KEY" ~/.snowflake/keys/rsa_key_dbt_pl_dev.pub | tr -d '\n'; echo
秘密鍵は Git リポジトリや記事の画像に含めず、ファイルのアクセス権を制限して保管してください。本番では、鍵の暗号化と保管、ローテーションを組織の方針に合わせて決めてください。
dbt 用のロールとユーザーを作成する
dbt のジョブで使うサービスユーザー DBT_PL_SVC と、Studio IDE で使う DBT_PL_DEV を作成します。認証はどちらも鍵ペアです。ユーザーを分ける理由は、ジョブの接続だけをログイン履歴で見分けるためです。DBT_PL_DEV も TYPE = SERVICE で作っていますが、今回は経路の検証にだけ使います。本番の開発者向けの認証設計は、本記事の対象外です。
USE ROLE USERADMIN;
CREATE ROLE DBT_PL_ROLE;
GRANT ROLE DBT_PL_ROLE TO ROLE SYSADMIN;
CREATE USER DBT_PL_SVC
TYPE = SERVICE
DEFAULT_ROLE = DBT_PL_ROLE
DEFAULT_WAREHOUSE = DBT_PL_WH
RSA_PUBLIC_KEY = '<公開鍵>';
CREATE USER DBT_PL_DEV
TYPE = SERVICE
DEFAULT_ROLE = DBT_PL_ROLE
DEFAULT_WAREHOUSE = DBT_PL_WH
RSA_PUBLIC_KEY = '<公開鍵>';
GRANT ROLE DBT_PL_ROLE TO USER DBT_PL_SVC;
GRANT ROLE DBT_PL_ROLE TO USER DBT_PL_DEV;

USE ROLE SYSADMIN;
CREATE WAREHOUSE DBT_PL_WH
WAREHOUSE_SIZE = XSMALL
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = TRUE;
CREATE DATABASE DBT_PL_DB;
-- Network Rule を作成するスキーマ(dbt のロールには付与しない)
CREATE SCHEMA DBT_PL_DB.NETWORK;
GRANT USAGE ON WAREHOUSE DBT_PL_WH TO ROLE DBT_PL_ROLE;
-- dbt がスキーマ PATH_PRIVATE / PATH_DEV を作れるようにする
GRANT USAGE, CREATE SCHEMA ON DATABASE DBT_PL_DB TO ROLE DBT_PL_ROLE;
鍵が登録されたかは DESC USER で確認できます。RSA_PUBLIC_KEY_FP に値があれば問題ありません。
USE ROLE USERADMIN;
DESC USER DBT_PL_SVC;
DESC USER DBT_PL_DEV;
PrivateLink の設定情報を確認する
Snowflake 側の PrivateLink の設定情報は SYSTEM$GET_PRIVATELINK_CONFIG() で取得します。実行できるのは ACCOUNTADMIN だけです。key ごとに表示すると、後の手順で使う値が分かります。
USE ROLE ACCOUNTADMIN;
SELECT key, value
FROM TABLE(FLATTEN(INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())));
| key | 内容 |
|---|---|
privatelink-account-url |
PrivateLink 用のアカウント URL。dbt の Private endpoint の接続先になる |
regionless-privatelink-account-url |
組織名とアカウント名を含む PrivateLink 用の URL |
privatelink-vpce-id |
Snowflake 側の VPC endpoint service の ID。dbt 側の VPC endpoint の ID とは別の値 |

Snowflake Support に dbt の AWS アカウントの許可を依頼する
Snowflake には AWS アカウントを許可する SYSTEM$AUTHORIZE_PRIVATELINK があります。ただし Snowflake docs によると、SaaS ベンダーの AWS アカウントの許可には使えません。そのため、dbt のマルチテナント環境の AWS アカウント ID 346425330055 を伝えて、Snowflake Support に起票します。この ID は dbt docs に記載されている公開値です。
dbt docs によると、Snowflake は dbt Labs の代理起票ではなく、アカウントの所有者による直接の起票を推奨しています。ケースに書く項目は 3 点で、Snowflake のナレッジ記事にまとまっています。Snowflake のアカウント URL、ベンダーの AWS アカウント ID、許可の依頼です。
今回は Snowsight の Support ページから、次の内容で起票しました。
件名: dbt platform(dbt Labs)からの AWS PrivateLink 接続のため、AWS アカウント ID の許可をお願いします
dbt platform(dbt Labs 社の SaaS、AWS マルチテナント環境)から、弊社の Snowflake アカウントへ AWS PrivateLink で接続する準備をしています。
ナレッジ記事「How to setup Private Connectivity to Snowflake from third party Cloud Service vendors」に沿って、ベンダーの AWS アカウント ID の許可(allowlist)を依頼します。
- Snowflake アカウント URL: https://myorg-myaccount.snowflakecomputing.com
- アカウントロケーター / リージョン: xy12345 / <リージョン>(AWS)
- エディション: Business Critical
- ベンダー: dbt Labs(dbt platform、AWS マルチテナント環境)
- 許可を依頼する AWS アカウント ID: 346425330055
- 依頼内容: 上記の AWS アカウント ID を、SaaS アプリケーションからのプライベート接続のために許可してください
- 参考(dbt 側の手順): https://docs.getdbt.com/docs/platform/secure/private-connectivity/aws/aws-snowflake
許可が完了しましたら、本ケースでご連絡ください。SYSTEM$GET_PRIVATELINK_AUTHORIZED_ENDPOINTS() で確認します。
起票から約 1 営業日で、許可完了の連絡が来ました。
※迅速にご対応いただきありがとうございます!
許可されたかは、許可済みの AWS アカウントの一覧で確認できます。
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$GET_PRIVATELINK_AUTHORIZED_ENDPOINTS();

一覧に 346425330055 が含まれていれば問題ありません。
試してみた
dbt platform で Private endpoint を作成する
Snowflake Support から許可の連絡を受けたら、dbt platform の Account settings で Private endpoints を開きます。新しい endpoint は、一覧の Request new から依頼します。

Provider type は Snowflake が選ばれた状態です。Step 1: Run SQL command に表示される SQL は次の 1 行です。

SELECT SYSTEM$GET_PRIVATELINK_CONFIG();

この SQL を Snowflake で ACCOUNTADMIN として実行し、出力の JSON 全体を Step 2: Paste the output に貼り付けます。Output looks good と表示されれば問題ありません。

Step 3: Choose your account URL で、接続に使うアカウント URL を選択します。

| 選択肢 | key | URL の形式 |
|---|---|---|
| Regionless | regionless-privatelink-account-url |
<組織名>-<アカウント名>.privatelink.snowflakecomputing.com |
| Regional | privatelink-account-url |
<アカウントロケーター>.<リージョン>.privatelink.snowflakecomputing.com |
どちらも同じ Snowflake アカウントに private 接続するための URL で、主な違いはアカウントの識別形式です。今回は Regionless を選びました。理由は次のとおりです。
- Snowflake docs は、アカウントロケーター形式を legacy とし、使用を推奨していません。Regionless は組織名とアカウント名の形式で、Snowflake が現在案内している識別子の形式と同じです
Submit request を押すと、endpoint の作成が始まります。

Connectivity status が Success になれば問題ありません。

endpoint を開くと、Endpoint identifier に dbt 側の VPC endpoint の ID が表示されます。後で Network Rule に入れる値です。

補足: Support-led setup で Private endpoint を作る場合
Account settings に Private endpoints のメニューがない場合は、dbt Support に依頼して endpoint を作ってもらいます。dbt docs での呼び名は Support-led setup です。
今回は実施していないため、2026年10月14日時点の記載を整理します。
手順は 3 つです。
- Snowflake Support に起票し、dbt の AWS アカウント
346425330055の許可を受ける(self-serve と同じ) - 許可されたら、ACCOUNTADMIN で
SELECT SYSTEM$GET_PRIVATELINK_CONFIG();を実行し、出力をコピーする - 次のテンプレートを埋めて、dbt Support(support@getdbt.com)にメールで送る
Subject: New Multi-Tenant (Azure or AWS) PrivateLink Request
- Type: Snowflake
- dbt platform account URL: https://<prefix>.<region>.dbt.com
- SYSTEM$GET_PRIVATELINK_CONFIG output: <手順 2 の出力全体>
- *Use privatelink-account-url or regionless-privatelink-account-url?: privatelink-account-url
- **Create Internal Stage PrivateLink endpoint? (Y/N): N
- dbt AWS multi-tenant environment (US, EMEA, AU, JP): <自分の dbt アカウントのリージョン>
テンプレートの項目について、docs には次の補足があります。
- 接続先の URL は、指定しなければ
privatelink-account-urlが使われます。希望すればregionless-privatelink-account-urlにもできます - Internal Stage の PrivateLink endpoint を作る場合は、先に Snowflake 側で Internal Stage の PrivateLink を有効にしておく必要があります
- AWS アカウント ID
346425330055はマルチテナント環境の値です。Virtual Private(シングルテナント)の ID は dbt Support に確認します
送付後は dbt Labs が設定を進めます。docs の目安は 3〜5 営業日です。endpoint が使えるようになると、Support から連絡があります。その後の Connection の作成は self-serve と同じで、Settings の PrivateLink Endpoint から endpoint を選びます。
Support-led setup を使った場合、Network Rule に入れる VPCE ID の確認先は、docs の案内どおり dbt Support です。接続後は、本記事のように LOGIN_HISTORY の CLIENT_PRIVATE_LINK_ID でも接続元の endpoint の ID を確認できます。
PrivateLink Endpoint を指定した Connection でプロジェクトを作る
まず、Account settings → Connections → New connection → Snowflake で Connection を作ります。Settings で PrivateLink Endpoint を選び、プルダウンから作成した endpoint を選択します。hostname / account の欄は自動で入力されます。

今回は、Database DBT_PL_DB、Warehouse DBT_PL_WH、Role DBT_PL_ROLE で設定しています。

次に、Account settings → Projects → Create new project でプロジェクト kawabata_dbt_privatelink_check を作ります。開発環境の Connection は上記で設定した Connection です。development credentials は DBT_PL_DEV の鍵ペア、スキーマには PATH_DEV を指定します。

Set up a repository は、検証用の Managed リポジトリです。

Studio IDE で Initialize your project を押し、次のモデルを models/privatelink_check.sql として作ります。IDE の接続も PrivateLink 経由です。current_ip_address() は、Snowflake から見た接続元の IPv4 アドレスを返す関数です。
-- models/privatelink_check.sql
{{ config(materialized='table') }}
select
current_timestamp() as checked_at,
current_user() as user_name,
current_ip_address() as client_ip,
current_client() as client_version,
current_session() as session_id,
current_account() as account_locator,
current_region() as region,
'{{ env_var("DBT_CLOUD_ENVIRONMENT_ID", "na") }}' as dbt_environment_id,
'{{ env_var("DBT_CLOUD_RUN_ID", "na") }}' as dbt_run_id

Commit and sync のあと、main に merge します。
次はデプロイ環境 path_private です。dbt platform では、Connection と認証情報をまとめた connection profile を環境に割り当てます。設定した内容は次のとおりです。
- Orchestration → Environments → Create environment → Deployment で環境を作る。種類は General
- Connection profiles → Add new profile で profile を作る。Connection は上述の Connection、Deployment credentials は Key pair で
DBT_PL_SVCの鍵 - スキーマは
PATH_PRIVATE、Extended Attributes はconnect_retries: 0

続いて、ジョブ job-path-private を作ります。場所は Orchestration → Jobs → Create job → Deploy job で、環境は path_private です。

コマンドは dbt build --select privatelink_check で、Generate docs と source freshness はオフです。Run now で実行すると、ログに 1 of 1 OK と出ました。

LOGIN_HISTORY で経路を確認する
DBT_PL_SVC のログイン履歴を、Information Schema の LOGIN_HISTORY_BY_USER で確認します。CLIENT_PRIVATE_LINK_ID 列は、private 接続でログインしたときの endpoint の ID です。
USE ROLE ACCOUNTADMIN;
USE WAREHOUSE DBT_PL_WH;
ALTER SESSION SET TIMEZONE = 'Asia/Tokyo';
SELECT event_timestamp, client_ip, client_private_link_id, reported_client_type,
first_authentication_factor, is_success, error_code, error_message
FROM TABLE(DBT_PL_DB.INFORMATION_SCHEMA.LOGIN_HISTORY_BY_USER(
USER_NAME => 'DBT_PL_SVC', RESULT_LIMIT => 50))
ORDER BY event_timestamp DESC;

IS_SUCCESS が YES のログイン行を見ます。CLIENT_PRIVATE_LINK_ID が、dbt platform に表示された Endpoint identifier と一致していれば問題ありません。そのログインは、dbt 側の VPC endpoint を経由しています。CLIENT_IP がプライベート IP アドレスであることも、補助として確認します。
Network Policy で public IPv4 接続を拒否してもジョブが成功することを確認する
Snowflake docs によると、private endpoint の ID を使う Network Rule は、public からの要求には効果がありません。public も拒否するには、blocked list に IPv4 の Network Rule を入れます。そこで、docs の例と同じ構成の Network Policy を DBT_PL_SVC に設定しました。allowed list に dbt の VPCE ID、blocked list に 0.0.0.0/0(IPv4 の全範囲)を入れた policy です。検証に使ったアカウントは他の利用者と共有しているため、Network Policy はアカウントではなくユーザーに設定しています。
USE ROLE ACCOUNTADMIN;
CREATE NETWORK RULE DBT_PL_DB.NETWORK.ALLOW_DBT_VPCE
MODE = INGRESS
TYPE = AWSVPCEID
VALUE_LIST = ('vpce-0xxxxxxxxxxxxxxxx');
CREATE NETWORK RULE DBT_PL_DB.NETWORK.BLOCK_PUBLIC_V4
MODE = INGRESS
TYPE = IPV4
VALUE_LIST = ('0.0.0.0/0');
CREATE NETWORK POLICY DBT_PL_POLICY
ALLOWED_NETWORK_RULE_LIST = ('DBT_PL_DB.NETWORK.ALLOW_DBT_VPCE')
BLOCKED_NETWORK_RULE_LIST = ('DBT_PL_DB.NETWORK.BLOCK_PUBLIC_V4');
ALTER USER DBT_PL_SVC SET NETWORK_POLICY = DBT_PL_POLICY;
設定先が意図どおりかは、次の SQL で確認できます。アカウントの NETWORK_POLICY は変えていません。
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT;
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN USER DBT_PL_SVC;
DESC NETWORK POLICY DBT_PL_POLICY;

Snowflake docs によると、この構成では private 接続の判定に IPv4 の Network Rule は使われません。public の IPv4 をすべて拒否してもジョブが成功したので、接続は dbt の VPC endpoint を通っています。あわせて、再実行後のログイン履歴でも、CLIENT_PRIVATE_LINK_ID が許可した VPCE ID と一致していることを確認しました。

参考として、手元 PC から Snowflake CLI の一時接続で DBT_PL_SVC として接続すると、エラーになりました。エラーには接続元の IP アドレスが許可されていない旨が表示され、Network Policy で public 接続が拒否されたことが分かります。
snow sql -x --account "myorg-myaccount" --user DBT_PL_SVC --authenticator SNOWFLAKE_JWT --private-key-file "$HOME\.snowflake\keys\rsa_key_dbt_pl_svc.p8" --role DBT_PL_ROLE --warehouse DBT_PL_WH -q "select current_ip_address()"

ACCOUNT_USAGE で接続先のホスト名を確認する
ACCOUNT_USAGE のビューでも経路を確認できます。INGRESS_NETWORK_ACCESS_HISTORY の REQUEST_AUTHORITY 列は、クライアントが接続に使ったホスト名です。SESSIONS と LOGIN_HISTORY を結合すると、セッションごとにログイン時の接続元が分かります。モデルが保存した session_id と同じ SESSION_ID の行が、ジョブのセッションです。反映には SESSIONS で最大 3 時間、INGRESS_NETWORK_ACCESS_HISTORY で最大 4 時間かかります。
USE ROLE ACCOUNTADMIN;
USE WAREHOUSE DBT_PL_WH;
ALTER SESSION SET TIMEZONE = 'Asia/Tokyo';
-- セッションとログインを対応づける
SELECT s.created_on, s.session_id, s.client_application_id,
l.client_ip, l.client_private_link_id, l.reported_client_type, l.is_success
FROM SNOWFLAKE.ACCOUNT_USAGE.SESSIONS AS s
JOIN SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY AS l
ON s.login_event_id = l.event_id
WHERE s.user_name = 'DBT_PL_SVC'
ORDER BY s.created_on;
-- 接続に使われたホスト名
SELECT event_timestamp, user_name, client_ip,
request_authority, is_success, error_code, error_message
FROM SNOWFLAKE.ACCOUNT_USAGE.INGRESS_NETWORK_ACCESS_HISTORY
WHERE user_name = 'DBT_PL_SVC'
ORDER BY event_timestamp;


制限事項・注意点
制限事項・注意点
privatelink-vpce-idは Snowflake 側の VPC endpoint service の ID です。- Network Rule に入れるのは、dbt 側の Endpoint identifier です。2 つの ID は別の値です。
- VPCE ID の Network Rule だけでは、public からの要求は拒否されません(Snowflake docs)。
- public も拒否するには、blocked list に IPv4 の Network Rule が必要です。
- ユーザーに設定した Network Policy は、Snowflake OAuth のトークン要求には原則として適用されません。適用されるのは、セキュリティ統合かアカウントの Network Policy です。
- 例外は組み込みの
SNOWFLAKE$LOCAL_APPLICATION統合で、トークン要求にもユーザーの Network Policy が適用されます(Snowflake docs)。 - Snowflake OAuth を PrivateLink 経由で使う場合、利用者の端末からも PrivateLink の endpoint に到達できる必要があります。
- dbt docs は、可能であれば External OAuth を使うよう案内しています。
- Internal Stage への PrivateLink には別の endpoint が必要で、dbt docs では dbt Support に依頼する手順です。本記事では扱っていません。
- Private endpoints の self-serve 機能は、2026年10月14日時点で beta です。
- Account settings にメニューがない場合は、dbt docs のテンプレートで dbt Support に依頼します(3〜5 営業日)。
- endpoint の Edit / Delete が表示されない場合は、dbt の account manager に有効化を依頼します。
- endpoint の作成直後は、DNS の反映待ちで Studio IDE や Test connection が失敗することがあります。
- Azure と Google Cloud の手順は、それぞれ次の dbt docs にあります。
最後に
dbt platform から Snowflake へ AWS PrivateLink で接続を検証してみました。
self-serve 機能は beta ですが、かなり簡単に設定ができ、待ち時間も少なくスムーズに接続できて体験が良かったです。
この記事が何かの参考になれば幸いです!









