ClickHouse は、JSON Web Token (JWT) を使用してユーザーを認証できます。LDAP や Kerberos などの他の外部認証方式とは異なり、JWT 認証では、あらかじめ存在するユーザーの本人確認は行いません。代わりに、各トークンに埋め込まれたクレームから 一時ユーザー を動的に生成します。これらのユーザーはメモリ上にのみ存在し、トークンのクレームに基づくアクセス権が付与され、トークンの有効期限が切れると自動的に削除されます。
この点で、JWT 認証はパスワードベースや証明書ベースの方式とは本質的に異なります。CREATE USER ... IDENTIFIED WITH jwt ステートメントは存在せず、これを実行しようとすると例外が発生します。JWT ユーザーは、トークンのライフサイクルによって管理されます。
概要
認証フローは次のとおりです。
- クライアントは、サポートされているいずれかの転送メカニズム (HTTP
Authorization: Bearerヘッダー、TCP ネイティブプロトコル、または gRPC のjwtフィールド) を介して署名付き JWT を提示します。 - ClickHouse はトークンの署名を検証します。
- 必須のクレーム (
exp、iat、iss、sub、aud) が検証されます。 clickhouse:grantsおよびclickhouse:rolesのトークンクレームから導出されたアクセス権と権限上限の積集合に基づいて、メモリ内に一時ユーザーが作成されます。- トークンの有効期限が切れると、バックグラウンドのガベージコレクションタスクによってそのユーザーは削除されます。
トークンクレーム
必須クレーム
ClickHouse に提示されるすべての JWT には、次のクレームが含まれている必要があります。
| クレーム | 説明 |
|---|---|
alg |
署名アルゴリズム (ヘッダークレーム) 。サポートされる値: RS256。バージョン 26.8 以降では、EC アルゴリズム ES256、ES384、ES512 もサポートされます。 |
exp |
有効期限。一時ユーザーの valid_until を設定します。 |
iat |
発行時刻。同じ アイデンティティ に対する古いトークンのリプレイを防ぐために使用されます。 |
iss |
issuer。プロバイダーで想定される issuer と照合されます。 |
sub |
Subject。生成されるユーザー名の一部になります。 |
aud |
audience。プロバイダーで想定される audience と照合されます。 |
JWKS ベースの鍵解決を使用する場合は、kid (key ID) ヘッダークレームも必須です。
その他の認識済みクレーム
| クレーム | 説明 |
|---|---|
nbf |
有効開始時刻。このクレームは必須ではありませんが、指定されている場合、この時刻より前のトークンは拒否されます。 |
jti |
予約済み。トークンに含まれていても受け付けられますが、現時点では検証や利用は行われません。 |
オプションのクレーム
| クレーム | デフォルト名 | 説明 |
|---|---|---|
| Grants | clickhouse:grants |
SQL GRANT の断片からなる JSON 配列です。例: ["SELECT ON db.*", "INSERT ON db.table1"]。各要素は GRANT ステートメントの本体として解析されます。 |
| Roles | clickhouse:roles |
割り当てるロール名の JSON 配列です。例: ["analyst", "reader"]。 |
| identity provider で異なる命名規則を使用している場合は、デフォルトのクレーム名をカスタムのクレーム名に再マッピングできます。 |
トークン、ヘッダー、ペイロードの例
{
"alg": "RS256",
"kid": "my-key-id"
}{
"iss": "https://idp.example.com",
"sub": "jane.doe",
"aud": "my-clickhouse-cluster",
"exp": 1719504000,
"iat": 1719500400,
"clickhouse:grants": ["SELECT ON analytics.*", "INSERT ON analytics.events"],
"clickhouse:roles": ["analyst"]
}一時ユーザーの動作
JWTユーザーは、通常のClickHouseユーザーとはいくつかの重要な点で異なります。
ID と命名
各 JWT ユーザーには、iss、sub、aud のクレーム から計算される決定論的な UUID が割り当てられます。この UUID はログインをまたいでも 変わりません。異なるトークンで何度ログインしても、issuer、subject、audience が同じであれば、常に同じ UUID が割り当てられます。
一方、ユーザー名は 変動 します。次のように構成されます。
JWT::<subject>::<claims_hash><claims_hash> は、iss、sub、aud のクレームと、clickhouse:roles および clickhouse:grants のクレームから導出されるハッシュです。iss と aud のクレームは このハッシュを通じてのみ 反映され、表示されるユーザー名のプレフィックスには直接埋め込まれなくなりました。これにより、iss/aud が長く不透明な IdP の URL (たとえば Microsoft Entra や Okta) であっても、名前を簡潔で読みやすく保ちつつ、異なる (iss, sub, aud) の組み合わせと、異なる clickhouse:roles / clickhouse:grants のセットが、それぞれ異なる安定した名前に対応することが保証されます。ハッシュに反映されないクレーム (たとえば iat、exp、nbf、または無関係なカスタムクレーム) は、ユーザー名を変更しません。
<claims_hash> の部分は、clickhouse:roles または clickhouse:grants のクレームが変更されるたびに変化します。つまり、同じアイデンティティであっても、ロールまたは権限セットが異なるトークンでは、生成されるユーザー名も異なります。
アクセス権
有効なアクセス権は次のように算出されます。
effective_rights = permission_limit ∩ (token_grants ∪ token_roles)ここで、permission_limit は、上限として設定された参照ロールまたはユーザーが保持するアクセス権の集合です。トークンが要求した権限のうち、この上限を超えるものは、通知されることなく破棄されます。
トークンの新しさ
ClickHouse は、安定した各アイデンティティについて、直近に認証されたトークンの iat (発行時刻) クレームを追跡します。保存済みの値と同じか、それより古い iat を持つトークンが提示された場合、サーバーはクレームを再評価せず、既存の一時ユーザーを再利用します。これにより、古いトークンによってユーザーの権限が引き下げられるのを防ぎます。
有効期間とガベージコレクション
一時ユーザーは、トークンが最初に認証されたときに作成され、valid_until (exp から導出) が過ぎると、バックグラウンドのガベージコレクション タスクによって削除されます。GC の間隔は、gc_interval パラメータ (デフォルト: 5 分) で制御されます。
GC の実行間では、期限切れのユーザーが system.users に表示されたままになることがありますが、認証はできなくなります。
永続的なアクセス割り当て
UUID は変わらないため、SQLステートメントを使用して、設定プロファイル、クォータ、行ポリシー、カラムのマスキングポリシーを JWT ユーザーに割り当てることができます。これらの割り当てはアクセス制御ストレージ (ディスク上または ZooKeeper 内) に永続的に保存され、トークンの有効期限切れや再認証後も維持されます。
ユーザーは現在のユーザー名で参照してください:
ALTER SETTINGS PROFILE my_profile ADD TO 'JWT::jane.doe::<claims_hash>';ALTER USER は読み取り専用のため、JWTユーザーには直接使用できないことに注意してください。設定プロファイル、クォータ、またはポリシーを割り当てるには、上記のとおり ALTER SETTINGS PROFILE、ALTER QUOTA、または ALTER ROW POLICY ステートメントを使用してください。
一般ユーザーとの違い
| 機能 | JWT ユーザー | 一般ユーザー |
|---|---|---|
| 作成 | トークンのクレームから自動作成 | CREATE USER ステートメント |
| 保存先 | メモリ内のみ (一時的) | ディスク、ZooKeeper、または設定ファイル |
CREATE USER ... IDENTIFIED WITH jwt |
サポートされていない (例外が発生する) | その他のすべての認証方式をサポート |
ALTER USER / DROP USER |
サポートされていない | サポート |
| バックアップと復元 | 含まれない | 含まれる |
| ユーザー名 | 自動生成され、固定されない | 管理者が選択し、固定される |
| UUID | iss+sub+aud から決定論的に生成 |
作成時にランダムに生成 |
| 有効期間 | トークンの exp によって制限される |
明示的に削除されるまで |
| アクセス権 | トークンのクレームから導出され、権限上限で制限される | GRANT によって明示的に付与される |
| ホスト制限 | プロバイダーごとのネットワーク設定 | ユーザーごとの HOST 句 |
| 設定プロファイル | UUID による割り当てが可能 (永続的) | 直接設定可能 |
| クォータと行ポリシー | UUID による割り当てが可能 (永続的) | 直接設定可能 |
| デフォルトロール | 設定不可 | 設定可能 |
SQL SECURITY DEFINER を使用するビュー
一時ユーザーである JWT ユーザーが SQL SECURITY DEFINER を指定してビューを作成すると、サーバーはそのビューの定義者として機能する永続的なシャドウコピーを自動的に作成します。このシャドウユーザーには、次の特性があります。
- 名前は
<original_jwt_username>:definer NO_AUTHENTICATIONが設定される (ログインには使用できません)- ビュー作成時点で、元の JWT ユーザーと同じアクセス権を保持する
これにより、一時ユーザーのトークンが期限切れになって元のユーザーがガベージコレクションで削除された後も、ビューは引き続き機能します。
クライアントの利用
トークンを直接渡す
事前に取得したトークンで認証するには、clickhouse-client で --jwt フラグを指定します。
clickhouse-client --host your-instance.clickhouse.cloud --secure --jwt '<your_jwt_token>'HTTP インターフェイス
トークンを Bearer トークンとして Authorization ヘッダーに指定して送信します:
curl -H 'Authorization: Bearer <your_jwt_token>' \
'https://your-instance.clickhouse.cloud:8443/?query=SELECT+currentUser()'OAuth2 デバイスコードログイン
clickhouse-client は、--login フラグによる対話型の OAuth2 デバイスコードフローをサポートしています。ClickHouse Cloud エンドポイントでは、ClickHouse 固有の JWT を取得するためのトークン交換がクライアントによって自動的に行われます。トークンはセッション中に透過的に更新されます。新しいトークンを取得すると、クライアントは自動的に再接続します。
clickhouse-client --host your-instance.clickhouse.cloud --loginClickHouse Cloud 組み込み JWT 認証器
すべての ClickHouse Cloud サービスには、SQL Console と clickhouse-client の --login フローで使用される、あらかじめ定義された JWT 認証器が用意されています。この認証器は次のように設定されています。
| Parameter | Value |
|---|---|
iss (issuer) |
ClickHouse |
aud (audience) |
サービス UUID (Cloud Console の URL に表示されます) |
sub (subject) |
ClickHouse Cloud アカウントのメールアドレス |
この組み込み認証器の権限上限は、default_role ロールおよび default ユーザーに設定されています。つまり、JWT ユーザーの実効権限はこの 2 つが持つ権限との積集合になるため、トークンによって default_role と default に許可されている範囲を超えて権限を昇格させることはできません。
この認証器を使用するために、追加の設定は必要ありません。サービスの作成時に自動的にプロビジョニングされます。
サービスで JWT 認証を有効にする
カスタム identity provider による JWT 認証 は Enterpriseプランで利用できます。アップグレードするには、Cloud Console のプランページにアクセスしてください。
組み込みの 認証器 に加えて、独自の identity provider (Microsoft Entra や Okta など) が発行する JWT を受け入れるよう、ClickHouse Cloud サービスを設定できます。これはベータ機能であり、ClickHouse バージョン 26.4 以降を実行するサービスでは Enterprise プランで利用できます。Cloud Console の Settings → Security → JWT authentication からご自身で設定できます。手順については JWT authentication setup を参照してください。各プロバイダーは、以下によって定義されます。
| パラメータ | 説明 |
|---|---|
| 名前 | サービス上のプロバイダーの一意の名前。 |
| issuer | identity provider が発行するトークンの iss クレームの値。通常はプロバイダーの URL です (例: https://your-tenant.okta.com) 。ClickHouse は、発行者がこの値と一致しないトークンを拒否します。 |
| audience | identity provider がこのサービス向けのトークンに設定する aud クレームの値。ClickHouse は、異なるオーディンス向けに発行されたトークンを拒否します。 |
| JWKS URL | identity provider が JSON Web Key Set を公開する HTTPS エンドポイント (例: https://idp.example.com/.well-known/jwks.json) 。ClickHouse はこのエンドポイントから公開鍵を取得してトークン署名を検証します。必須クレームで説明しているとおり、JWKS 検証では RSA 鍵 (RS256) に加え、バージョン 26.8 以降では P-256、P-384、P-521 曲線の EC 鍵 (ES256、ES384、ES512) も使用できます。 |
| ロールクレーム (任意) | 一時ユーザーの ClickHouse ロールを格納するトークンクレームの名前。デフォルトのクレーム名 clickhouse:roles を使用するには空白のままにします。このクレームには、["analyst", "reader"] のようにロール名の JSON 配列を含める必要があります。 |
サーバー間通信
クエリが別の分片またはレプリカに転送される際、JWTトークンはサーバー間プロトコルにも含まれます。リモートノードはそのトークンを独自に再認証し、独自の一時ユーザーを作成します。
トラブルシューティング
- アクセス権が付与されていない: 参照先のロールまたはユーザーに、必要な権限が付与されていない可能性があります。
clickhouse:rolesで参照しているロールが存在し、適切な権限が含まれていることを確認してください。 - トークンが拒否される: トークン内の
iss、aud、および署名アルゴリズムが、JWT プロバイダーの想定と一致していることを確認してください。JWKS を使用している場合は、トークンのkidがプロバイダーのキーセット内のキーと一致していることを確認してください。 - クエリの間にユーザーが消える: 一時ユーザーは、トークンの有効期限が切れると削除されます。長時間のセッションでは、トークンの更新をサポートするクライアント (例:
--loginモード) を使用してください。 CREATE USER ... IDENTIFIED WITH jwtが失敗する: これは想定どおりです。JWT ユーザーは DDL では作成できません。管理は完全にトークンのライフサイクルに委ねられます。