Snowflake × .NET:パスワード廃止時代の安全な接続(鍵ペア認証・PAT・WIF)と移行手順/接続文字列ガイド

Snowflake が段階的に「ユーザー名+パスワード」だけのサインインを廃止へと進めるなか、ASP.NET/.NET アプリ側の接続方式を見直す必要が出てきました。本記事では、.NET から安全に Snowflake へ接続するための実運用レベルの選択肢(鍵ペア認証/Programmatic Access Token/Workload Identity Federation)を整理し、手順・接続文字列・移行のコツをまとめて解説します。

目次

Snowflake のパスワード廃止の背景と影響範囲

Snowflake はセキュリティ強化の一環として、単一要素のパスワードサインインを段階的に廃止しています。特にアプリケーションやサービス等の非対話ユーザー(TYPE=SERVICE)は、最終的にパスワードでの接続が不可となる計画です。人手によるサインイン(TYPE=PERSON)はパスワードを用いる場合、原則として MFA が必須化されます。現在の計画では、2025 年〜2026 年にかけて段階的な適用が続き、2026 年 10 月までに強固な認証への全面移行が完了する想定です。

  • 対象の見極め:アプリ/バッチ/API 経由の接続は、従来の「ユーザー名+パスワード」からの移行が必須。
  • 推奨アプローチ:Workload Identity Federation(WIF) > 鍵ペア認証 > Programmatic Access Token(PAT)の順で、運用要件に合わせて選定。

ASP.NET/.NET で選べるパスワードレス認証方式(比較)

方式概要主な設定手順(要点)接続文字列の要点メリット留意点
鍵ペア認証(Key Pair / SNOWFLAKE_JWT)RSA/ECDSA の公開鍵・秘密鍵で署名し、パスワード不要で接続1) OpenSSL で 2048bit 以上の鍵を生成
2) ALTER USER <user> SET RSA_PUBLIC_KEY='<publicKey>'
3) .NET ドライバーを最新化
4) 接続文字列に AUTHENTICATOR=SNOWFLAKE_JWT と秘密鍵を指定
AUTHENTICATOR=SNOWFLAKE_JWT
PRIVATE_KEY_FILE または PRIVATE_KEY
(必要に応じて PRIVATE_KEY_FILE_PWD)
高い安全性/鍵ローテーションしやすい/オンプレでも可秘密鍵の保護と配布が運用ポイント。改行やエンコードの扱いで接続エラーになりやすい
Programmatic Access Token(PAT)Snowflake が発行する短命なトークンをパスワード欄に指定して接続1) ALTER USER ADD PROGRAMMATIC ACCESS TOKEN で発行(必要なら ROLE_RESTRICTION を付与)
2) トークン値を安全に保管(表示は作成時のみ)
3) 有効期限とローテーションの運用を準備
PASSWORD=<token_secret>
(AUTHENTICATOR の特別指定は不要)
鍵管理が不要で導入が容易/GUI・SQL で発行・失効を制御可能期限切れリスク/ローテーションの自動化が必須。ネットワークポリシーや役割制限の設計が重要
Workload Identity Federation(WIF)クラウドのネイティブ ID(Azure Managed Identity / AWS IAM / GCP SA 等)で秘密情報を保存せず接続1) Snowflake 側で WIF を有効化し対象サービスユーザーを設定
2) 認証ポリシーで許可プロバイダーや発行者を制限
3) .NET ドライバーを WIF 対応版(4.8.0 以降推奨 5.x)に更新
4) 実行環境(例:Azure のユーザー割当て MI)は環境変数で ID を指示
AUTHENTICATOR=WORKLOAD_IDENTITY
WORKLOAD_IDENTITY_PROVIDER=AZURE|AWS|GCP|OIDC
秘密情報の配布・保管が不要/最小権限と短命クレデンシャルで強固/CI/CD と相性良しクラウド基盤の設定とバージョン要件を満たす必要。オンプレ単体運用には不向き

接続文字列と C# 実装例

前提:.NET ドライバーのバージョン

  • 鍵ペア認証/PAT:現行の Snowflake .NET ドライバー(4.x/5.x)で利用可能。最新版への更新を推奨。
  • WIF:4.8.0 以降で対応(最新 5.x を推奨)。

鍵ペア認証(SNOWFLAKE_JWT)

鍵の作成(OpenSSL)

# 秘密鍵(非暗号化)
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt

# 秘密鍵(暗号化)

openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out rsa_key.p8

# 公開鍵

openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub 

公開鍵の登録(Snowflake)

ALTER USER app_user SET RSA_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----MIIBIj...';

.NET 接続文字列(ファイル指定)

// Windows のパスはエスケープ(\\)に注意
string connStr =
  "account=ACME;" +
  "user=app_user;" +
  "authenticator=SNOWFLAKE_JWT;" +
  "private_key_file=C:\\\\secrets\\\\rsa_key.p8;" +
  "private_key_file_pwd=<必要ならパスフレーズ>" +
  "role=SYSADMIN;warehouse=COMPUTE_WH;db=SALES;schema=PUBLIC;";

using var conn = new Snowflake.Data.Client.SnowflakeDbConnection();
conn.ConnectionString = connStr;
conn.Open(); 

.NET 接続文字列(秘密鍵を文字列で埋め込む)

string privateKeyPem = Environment.GetEnvironmentVariable("SF_PRIVATE_KEY_PEM")!;
// 改行は \n、Base64 の '=' は "==" になるケースに注意(ドライバーの仕様差分によりエスケープが必要)
string connStr =
  "account=ACME;user=app_user;authenticator=SNOWFLAKE_JWT;" +
  $"private_key={privateKeyPem};role=SYSADMIN;warehouse=COMPUTE_WH;db=SALES;schema=PUBLIC;";

つまずきやすいポイント

  • 認証子の表記:一部のバージョンでは authenticator の値が大文字小文字に敏感でした。SNOWFLAKE_JWT と大文字で指定すると安全です。
  • JWT 無効エラー:公開鍵の登録ミス、アカウント識別子/ユーザー名の不一致、システム時刻のずれが典型原因。サーバー時刻の同期も確認を。
  • 鍵ローテーション:RSA_PUBLIC_KEY と RSA_PUBLIC_KEY_2 を併用して無停止で切替可能。更新後に古い鍵を UNSET。

Programmatic Access Token(PAT)

トークンの発行(Snowflake)

-- サービスユーザーの場合は ROLE_RESTRICTION を必須で指定するのが基本
ALTER USER app_user ADD PROGRAMMATIC ACCESS TOKEN app_token
  ROLE_RESTRICTION = 'APP_ROLE'
  DAYS_TO_EXPIRY = 15
  COMMENT = 'app backend token';
-- 返される token_secret はこの時だけ表示。安全に保管すること

運用コマンド(例)

-- 有効なトークンの一覧
SHOW USER PROGRAMMATIC ACCESS TOKENS FOR USER app_user;

-- トークンのローテーション(新しい secret を発行し旧 secret を失効)
ALTER USER app_user ROTATE PROGRAMMATIC ACCESS TOKEN app_token; 

.NET 接続文字列

string token = Environment.GetEnvironmentVariable("SF_APP_PAT")!;
string connStr =
  "account=ACME;user=app_user;" +
  $"password={token};" + // パスワード欄に token_secret をそのまま指定
  "role=APP_ROLE;warehouse=APP_WH;db=SALES;schema=PUBLIC;";

using var conn = new Snowflake.Data.Client.SnowflakeDbConnection { ConnectionString = connStr };
conn.Open(); 

運用の勘所

  • 期限管理:DAYS_TO_EXPIRY で寿命を短く保ち、失効前に自動ローテーションするジョブを用意。
  • 権限の絞り込み:ROLE_RESTRICTION を活用して、トークン利用時の権限を明示的に限定。
  • 制約:PAT で認証した同一セッション内ではそのトークンのローテーションは不可。管理セッションを分離する。

Workload Identity Federation(WIF)

概要:アプリやコンテナが稼働する基盤(Azure/AWS/GCP/OIDC)のネイティブ IDで Snowflake に接続する方式。秘密鍵やトークンを保管・配布しないため、長期運用のセキュリティと運用負荷の両面で最有力の選択肢です。

前提:

  • Snowflake 側:対象ユーザーは TYPE=SERVICE、認証ポリシーで許可プロバイダーや発行者(テナント等)を制限。
  • クライアント側:.NET ドライバーは 4.8.0 以降(推奨 5.x)。

Azure(Managed Identity)の例

  • ユーザー割当て MI を使う場合、アプリ実行環境に MANAGED_IDENTITY_CLIENT_ID を設定して ID を指示。

.NET 接続文字列(WIF)

string connStr =
  "account=ACME;" +
  "user=svc_app;" +                            // Snowflake のサービスユーザー
  "authenticator=WORKLOAD_IDENTITY;" +         // WIF を選択
  "workload_identity_provider=AZURE;" +        // 実行基盤を指定(AWS/GCP/OIDC も可)
  "role=APP_ROLE;warehouse=APP_WH;db=SALES;schema=PUBLIC;";

using var conn = new Snowflake.Data.Client.SnowflakeDbConnection { ConnectionString = connStr };
conn.Open(); // 実行環境のネイティブ ID で秘密情報なしに認証 

WIF の利点と設計ポイント

  • シークレットレス運用:鍵・トークンの保管/配布が不要になり、漏えい面積を縮小。
  • ゼロトラスト指向:発行者やアカウント単位で「どの基盤からの接続を許可するか」を認証ポリシーで厳密に制御。
  • マルチクラウド:AWS IAM / Entra ID / GCP SA / OIDC を横断して同一の接続モデルで統一。

ユースケース別の推奨方針

ユースケース推奨方式理由
クラウド常駐の API/バッチ/マイクロサービスWIF秘密情報を持たずに接続。IdP と役割制御を一元化
オンプレや閉域網からの常時接続鍵ペア認証鍵配布とローテーションを運用に組み込めば長期安定。依存が少ない
導入初期・PoC・GUI 主体の利用PAT発行が簡単で学習コストが低い。後から WIF/鍵へ移行しやすい

移行ステップ(.NET 観点の実務ガイド)

  1. 影響範囲の棚卸し:接続文字列をスキャンし、パスワード利用の箇所とサービスユーザーを洗い出し。
  2. 方式の選定:稼働基盤・保守体制・監査要件を踏まえて WIF / 鍵 / PAT をアプリ単位で決定。
  3. ドライバー更新:Snowflake .NET ドライバーを最新(推奨 5.x)へ。テストから先行適用。
  4. 認証ポリシー設計:WIF の許可プロバイダー、PAT の ROLE_RESTRICTION、鍵のローテーション頻度を定義。
  5. シークレット管理:鍵・PAT は必ず Secrets/Key Vault/Parameter Store 等に格納し、アプリには環境変数で注入。
  6. 監視実装:PAT の期限(SHOW USER PROGRAMMATIC ACCESS TOKENS)や接続エラーを監視。期限アラート&自動ローテーションを投入。
  7. 段階的切替:ステージング → カナリア → 本番。鍵は RSA_PUBLIC_KEY_2 を使い無停止で差し替え。

セキュリティ実装のベストプラクティス

  • サービスユーザー化:アプリ用ユーザーは TYPE=SERVICE とし、人手ログインと混在させない。
  • 最小権限:アプリごとに専用ロールを作成し、ROLE_RESTRICTION で PAT の権限を拘束。二次ロールへの依存を避ける。
  • ネットワーク制御:必要に応じてネットワークポリシーで PAT の利用元を限定。
  • 可観測性:クエリタグ(QUERY_TAG)でアプリ別に可視化。ログと監査証跡を関連付ける。
  • 鍵の保管:秘密鍵はファイル権限を最小化し、配布にはセキュアストアを使用。CI/CD ではアーティファクトに混入させない。

.NET 固有のトラブルと対処集

症状原因の多く対処
JWT token is invalid公開鍵未登録/ユーザー不一致/アカウント識別子のミス/時刻ずれ公開鍵を再設定、account と user を再確認、時刻同期
Could not read private key ... incorrect private key format改行コードや = の扱い、PKCS#8 以外の形式-----BEGIN ...----- 形式の PEM/PKCS#8 を使用。文字列埋め込み時は \n と = エスケープに注意
WIF で接続不可ドライバー未更新/許可プロバイダー未設定/Azure のユーザー割当て MI の Client ID 未指定.NET ドライバーを 4.8.0+ に更新、authenticator=WORKLOAD_IDENTITY/WORKLOAD_IDENTITY_PROVIDER を指定、MANAGED_IDENTITY_CLIENT_ID を設定
PAT の期限切れローテーション運用の未整備期限前アラートと自動ローテーション(管理セッション)を導入

実装サンプル(最小構成の C#)

using System.Data;
using Snowflake.Data.Client;

public static class SnowSample
{
public static void RunWithKeyPair()
{
var cs = "account=ACME;user=app_user;authenticator=SNOWFLAKE_JWT;" +
"private_key_file=C:\\secrets\\rsa_key.p8;" +
"role=APP_ROLE;warehouse=APP_WH;db=SALES;schema=PUBLIC;";
using var conn = new SnowflakeDbConnection { ConnectionString = cs };
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = "select current_user(), current_role(), current_version()";
using var rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine($"{rdr.GetString(0)} / {rdr.GetString(1)} / {rdr.GetString(2)}");
}
}


public static void RunWithPAT()
{
    var token = Environment.GetEnvironmentVariable("SF_APP_PAT")!;
    var cs = "account=ACME;user=app_user;" +
             $"password={token};role=APP_ROLE;warehouse=APP_WH;db=SALES;schema=PUBLIC;";
    using var conn = new SnowflakeDbConnection { ConnectionString = cs };
    conn.Open();
    using var cmd = conn.CreateCommand();
    cmd.CommandText = "call system$wait(1)"; // 簡易ダミー
    cmd.ExecuteNonQuery();
}

public static void RunWithWIF()
{
    var cs = "account=ACME;user=svc_app;authenticator=WORKLOAD_IDENTITY;" +
             "workload_identity_provider=AZURE;role=APP_ROLE;warehouse=APP_WH;db=SALES;schema=PUBLIC;";
    using var conn = new SnowflakeDbConnection { ConnectionString = cs };
    conn.Open();
    using var cmd = conn.CreateCommand();
    cmd.CommandText = "select current_account(), current_region()";
    using var rdr = cmd.ExecuteReader();
    while (rdr.Read())
    {
        Console.WriteLine($"{rdr.GetString(0)} / {rdr.GetString(1)}");
    }
}


} 

移行チェックリスト(貼って使える)

  • 接続先アカウント識別子(<org>-<account> 等)を全アプリで統一/明示。
  • .NET ランタイムと Snowflake .NET ドライバーの互換性確認(ターゲットフレームワーク、ネイティブ依存なし)。
  • WIF を採用する場合、対象サービスユーザーを TYPE=SERVICE とし、認証ポリシーで許可するプロバイダーと発行者を限定。
  • 鍵ペアの場合、鍵生成・配布・回収・保管の RACI とローテーション頻度を決定。RSA_PUBLIC_KEY_2 を用いた無停止切替手順を文書化。
  • PAT の場合、DAYS_TO_EXPIRY とローテーション自動化(失効前 N 日での再発行)を実装。ROLE_RESTRICTION で権限を限定。
  • CI/CD で秘密情報を扱う場合、リポジトリに残らない設計(環境変数注入・マスキング出力)とレビューゲートを設定。
  • 監査・運用:接続失敗の検知(メトリクス/アラート)、ユーザー/ロールの棚卸し、不要トークンの削除。

まとめ:.NET からの最適解

パスワード廃止の流れに合わせ、まずは WIF によるシークレットレス接続を第一候補として検討し、基盤や要件の都合で難しい場合は鍵ペア認証、導入初期や簡便さを重視する場合にPATを選ぶ、という優先順位が現実解です。どの方式も .NET 側は接続文字列の変更で対応でき、移行自体は難しくありません。大切なのは「鍵/トークンの運用(保管・期限・ローテーション)」「認証ポリシーでの制限」「監視」の 3 点を最初から組み込むことです。これらを押さえれば、Snowflake への .NET 接続は安全かつ長期安定で運用できます。


付録:簡易レシピ

鍵ペア認証の 3 ステップ

  1. OpenSSL で rsa_key.p8 と rsa_key.pub を作成。
  2. ALTER USER app_user SET RSA_PUBLIC_KEY='<pub>'。
  3. authenticator=SNOWFLAKE_JWT; private_key_file=... を接続文字列に追加。

PAT の 3 ステップ

  1. ALTER USER ADD PROGRAMMATIC ACCESS TOKEN app_token ROLE_RESTRICTION='APP_ROLE' DAYS_TO_EXPIRY=15。
  2. 出力された token_secret を安全に保管。
  3. 接続文字列の password= に token_secret を設定。

WIF の 3 ステップ

  1. Snowflake で WIF と認証ポリシーを設定し、サービスユーザーに適用。
  2. .NET ドライバーを 4.8.0+(推奨 5.x)へ更新。
  3. authenticator=WORKLOAD_IDENTITY; workload_identity_provider=<AZURE|AWS|GCP|OIDC> を接続文字列に設定。

Q&A:最初に何を選べばよい?

クラウド常駐のモダンワークロードなら WIF 一択。オンプレや閉域でクラウドの IdP を使いづらいなら、鍵ペア認証が堅実です。まずは開発・検証環境で新方式を導入し、エラー監視と期限アラートを整えてから本番に切り替えるのが安全です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次