2025年4月からパスワード認証時の MFA が必須に
2024年7月のアップデート1 で USER
オブジェクトに TYPE
プロパティが追加され、これまで「ユーザ」と一括りだったものが、人間に紐づくユーザ (PERSON
) とシステムに紐づくユーザ (SERVICE
) とが区別して登録できるようになった。
さらに、現在 (2025年2月時点) では Snowsight にサインインすると以下のようなメッセージが表示される。
Security Alert
Upcoming security changes
To make your accounts more secure, starting in April 2025, Snowflake will require that all human users who sign in with passwords use MFA. This change will not affect SSO sign-ins or service users. Read our blog post to understand what you should do to ensure that there are minimal disruptions for your users.
2025年4月からはパスワード認証でサインインする際に MFA が必須となる2とのこと。
「認証ポリシー」や「LEGACY_SERVICE ユーザ」による回避方法も用意されているが、いずれも移行作業の時間稼ぎのために用意されている方法であり、パスワード認証時の MFA 必須化から免れることはできない。
これに伴って、各ユーザについて以下のように対応する必要がある。
- 人間が使用している
USER
オブジェクト (Snowsight 利用など) の場合- MFA を有効化する
- システム/プログラムが使用している
USER
オブジェクト (API 利用など) の場合-
USER
オブジェクトのTYPE
をSERVICE
に設定し、パスワード認証ではない別の認証方式に切り替える
-
人間の方は、利用者全員に「MFA を有効化しろよ」とアナウンスすれば良いだけなのでまだ難しくない。
問題は 「何らかのシステムからパスワード認証で Snowflake にアクセスしている場合」 で、パスワード認証ではない 別の認証方式に切り替える必要がある。
この「別の認証方式」にはいくつかあるらしいが、この記事ではキーペア認証を使用して Snowflake にアクセスする方法について扱っていく。 (※ この記事ではキーペアのローテーションについては扱わないので、必要であれば各自で調べていただきたい。)
キーペア認証で Snowflake にアクセスする手順
基本的には公式ドキュメント3 通りにやっていくが、細かい手順を補足したりしている。
キーペアの作成
openssl
コマンドを使って RSA キーペアを作成していく。
$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
秘密鍵 rsa_key.p8
が作成された。
$ openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
公開鍵 rsa_key.pub
が作成された。
今回の手順では秘密鍵のパスフレーズを設定せずに作成しているが、一部の Snowflake と連携する SaaS (※) などではキーペア認証を設定する際にパスフレーズ設定が必須となっている場合があるため注意されたい。
※ dbt Cloud, Tableau, OpenMetadata など
サービスユーザを作成し、公開鍵を紐づける
先ほど作成した公開鍵ファイルの内容はそのままだと指定できない。冒頭と末尾にある -----BEGIN PUBLIC KEY-----
のような行を削除したうえで、改行を消した文字列を用意する。
$ cat rsa_key.pub | grep -v "PUBLIC KEY" | tr -d '\n'
MIIB...
この公開鍵文字列を使って Snowflake のサービスユーザを新規作成する。4
CREATE USER myapp
TYPE = SERVICE
DEFAULT_ROLE = PUBLIC
RSA_PUBLIC_KEY = 'MIIB...'
既存のサービスユーザに公開鍵を紐づけたい場合は ALTER
クエリを使う。
ALTER USER myapp SET RSA_PUBLIC_KEY='MIIB...'
Python クライアントから接続する
クライアントから接続する例として、Python (snowflake-connector-python
) から接続してクエリを実行してみる。
ちなみに dbt-snowflake
や terraform-provider-snowflake
を使用する場合の手順は以下の記事がよくまとまっていた。
公開鍵と同様に、秘密鍵の -----BEGIN PRIVATE KEY-----
などを消して改行をなくした文字列を用意する。
$ cat rsa_key.p8 | grep -v "PRIVATE KEY" | tr -d '\n'
MIIE...
接続オブジェクトを作成する際に、秘密鍵を Base64 デコードしたバイト列を private_key
引数に指定することでキーペア認証が利用できる。(※ この例では秘密鍵文字列をハードコーディングしているが、実際にやる際はセキュアな場所に格納しておいて取得するようにしたほうがよい。)
from base64 import b64decode
import snowflake.connector
SNOWFLAKE_PRIVATE_KEY = "MIIE..."
def get_connection():
return snowflake.connector.connect(
account="xxxxxxx-xx00000",
database="myapp",
user="myapp",
private_key=b64decode(SNOWFLAKE_PRIVATE_KEY),
)
正しく設定ができていれば、以下のようにしてクエリが実行できることが確認できると思う。
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("SELECT COUNT(1) FROM mytable")
print(cur.fetchone())