Skip to main content
ClickHouse は、JSON Web Token (JWT) を使用してユーザーを認証できます。LDAP や Kerberos などの他の外部認証方式とは異なり、JWT 認証では、あらかじめ存在するユーザーの本人確認は行いません。代わりに、各トークンに埋め込まれたクレームから 一時ユーザー を動的に生成します。これらのユーザーはメモリ上にのみ存在し、トークンのクレームに基づくアクセス権が付与され、トークンの有効期限が切れると自動的に削除されます。 この点で、JWT 認証はパスワードベースや証明書ベースの方式とは本質的に異なります。CREATE USER ... IDENTIFIED WITH jwt ステートメントは存在せず、これを実行しようとすると例外が発生します。JWT ユーザーは、トークンのライフサイクルによって管理されます。

概要

認証フローは次のとおりです。
  1. クライアントは、サポートされているいずれかの転送メカニズム (HTTP Authorization: Bearer ヘッダー、TCP ネイティブプロトコル、または gRPC の jwt フィールド) を介して署名付き JWT を提示します。
  2. ClickHouse はトークンの署名を検証します。
  3. 必須のクレーム (exp、iat、iss、sub、aud) が検証されます。
  4. clickhouse:grants および clickhouse:roles のトークンクレームから導出されたアクセス権と権限上限の積集合に基づいて、メモリ内に一時ユーザーが作成されます。
  5. トークンの有効期限が切れると、バックグラウンドのガベージコレクションタスクによってそのユーザーは削除されます。

トークンクレーム

必須クレーム

ClickHouse に提示されるすべての JWT には、次のクレームが含まれている必要があります。 JWKS ベースの鍵解決を使用する場合は、kid (key ID) ヘッダークレームも必須です。

その他の認識済みクレーム

オプションのクレーム

トークン、ヘッダー、ペイロードの例

一時ユーザーの動作

JWTユーザーは、通常のClickHouseユーザーとはいくつかの重要な点で異なります。

ID と命名

各 JWT ユーザーには、iss、sub、aud のクレーム から計算される決定論的な UUID が割り当てられます。この UUID はログインをまたいでも 変わりません。異なるトークンで何度ログインしても、issuer、subject、audience が同じであれば、常に同じ UUID が割り当てられます。 一方、ユーザー名は 変動 します。次のように構成されます。
<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 のクレームが変更されるたびに変化します。つまり、同じアイデンティティであっても、ロールまたは権限セットが異なるトークンでは、生成されるユーザー名も異なります。

アクセス権

有効なアクセス権は次のように算出されます。
ここで、permission_limit は、上限として設定された参照ロールまたはユーザーが保持するアクセス権の集合です。トークンが要求した権限のうち、この上限を超えるものは、通知されることなく破棄されます。

トークンの新しさ

ClickHouse は、安定した各アイデンティティについて、直近に認証されたトークンの iat (発行時刻) クレームを追跡します。保存済みの値と同じか、それより古い iat を持つトークンが提示された場合、サーバーはクレームを再評価せず、既存の一時ユーザーを再利用します。これにより、古いトークンによってユーザーの権限が引き下げられるのを防ぎます。

有効期間とガベージコレクション

一時ユーザーは、トークンが最初に認証されたときに作成され、valid_until (exp から導出) が過ぎると、バックグラウンドのガベージコレクション タスクによって削除されます。GC の間隔は、gc_interval パラメータ (デフォルト: 5 分) で制御されます。 GC の実行間では、期限切れのユーザーが system.users に表示されたままになることがありますが、認証はできなくなります。

永続的なアクセス割り当て

UUID は変わらないため、SQLステートメントを使用して、設定プロファイル、クォータ、行ポリシー、カラムのマスキングポリシーを JWT ユーザーに割り当てることができます。これらの割り当てはアクセス制御ストレージ (ディスク上または ZooKeeper 内) に永続的に保存され、トークンの有効期限切れや再認証後も維持されます。 ユーザーは現在のユーザー名で参照してください:
指定した アイデンティティ のユーザー名と UUID は、ユーザーが有効な間、system.users の name カラムと id カラムで確認できます。
ALTER USER は読み取り専用のため、JWTユーザーには直接使用できないことに注意してください。設定プロファイル、クォータ、またはポリシーを割り当てるには、上記のとおり ALTER SETTINGS PROFILE、ALTER QUOTA、または ALTER ROW POLICY ステートメントを使用してください。

一般ユーザーとの違い

SQL SECURITY DEFINER を使用するビュー

一時ユーザーである JWT ユーザーが SQL SECURITY DEFINER を指定してビューを作成すると、サーバーはそのビューの定義者として機能する永続的なシャドウコピーを自動的に作成します。このシャドウユーザーには、次の特性があります。
  • 名前は <original_jwt_username>:definer
  • NO_AUTHENTICATION が設定される (ログインには使用できません)
  • ビュー作成時点で、元の JWT ユーザーと同じアクセス権を保持する
これにより、一時ユーザーのトークンが期限切れになって元のユーザーがガベージコレクションで削除された後も、ビューは引き続き機能します。

クライアントの利用

トークンを直接渡す

事前に取得したトークンで認証するには、clickhouse-client で --jwt フラグを指定します。
--jwt フラグは --user と同時に使用できません。--jwt を指定した場合、ユーザー名はトークンから取得されます。

HTTP インターフェイス

トークンを Bearer トークンとして Authorization ヘッダーに指定して送信します:
JWT は必ず HTTPS 経由で送信してください。Bearer トークンを平文の HTTP で送信すると、ネットワーク経路上の第三者に傍受される可能性があり、認証情報を漏えいするのと同じです。

OAuth2 デバイスコードによるログイン

clickhouse-client は、--login フラグにより、対話型の OAuth 2.0 デバイス認可グラント (RFC 8628) をサポートしています。 ClickHouse Cloud のエンドポイントに接続する際に --oauth-* オプションを指定しない場合、クライアントは ClickHouse Cloud の IdP でログインし、トークン交換を自動的に実行して ClickHouse 固有の JWT を取得します。トークンは session 中に透過的にリフレッシュされ、新しいトークンを取得すると、クライアントは自動的に再接続します。
カスタム IdP を使用する場合は、OIDC の issuer を --oauth-url に指定します。--oauth-* オプションをいずれか 1 つでも指定すると、ClickHouse Cloud のホストに対してもカスタム IdP フローが使用されます (たとえば、サービスで カスタム identity provider による JWT 認証 が有効になっている場合など) 。クライアントは、issuer の /.well-known/openid-configuration (および関連する OAuth メタデータ URL) から device_authorization_endpoint と token_endpoint を自動検出します。grant_types_supported が存在する場合は、urn:ietf:params:oauth:grant-type:device_code が含まれている必要があります。検出に失敗するとクライアントはエラーを報告するため、メタデータが使用できない場合は --oauth-device-uri と --oauth-token-uri の両方を明示的に指定してください。 ログイン時、クライアントは短い verification_uri と user_code (RFC 8628) を出力します。IdP が verification_uri_complete も返す場合は、そのショートカット URL が出力されてブラウザで開かれます。さらに qrencode ツールが利用可能であれば、端末上に QR コードとしても表示されます。ClickHouse Cloud の IdP では、verification_uri_complete と user_code のみが出力されます。コンフィデンシャルクライアントでは、--oauth-client-secret を --oauth-client-auth basic|post と組み合わせて指定できます。
取得したアクセストークンは、JWT として ClickHouse に渡されます。ロールと権限のマッピングは、これまでどおりサーバー側の JWT 認証設定 (例: clickhouse:roles claim) によって決まります。

ClickHouse Cloud 組み込み JWT 認証器

すべての ClickHouse Cloud サービスには、SQL Console と clickhouse-client の --login フローで使用される、あらかじめ定義された JWT 認証器が用意されています。この認証器は次のように設定されています。 この組み込み認証器の権限上限は、default_role ロールおよび default ユーザーに設定されています。つまり、JWT ユーザーの実効権限はこの 2 つが持つ権限との積集合になるため、トークンによって default_role と default に許可されている範囲を超えて権限を昇格させることはできません。 この認証器を使用するために、追加の設定は必要ありません。サービスの作成時に自動的にプロビジョニングされます。

サービスで JWT 認証を有効にする

組み込みの 認証器 に加えて、独自の identity provider (Microsoft Entra や Okta など) が発行する JWT を受け入れるよう、ClickHouse Cloud サービスを設定できます。この機能は、ClickHouse バージョン 26.4 以降を実行するサービスでは Enterprise プランで利用できます。Cloud Console の Settings → Security → JWT authentication からご自身で設定できます。手順については JWT authentication setup を参照してください。各プロバイダーは、以下によって定義されます。

サーバー間通信

クエリが別の分片またはレプリカに転送される際、JWTトークンはサーバー間プロトコルにも含まれます。リモートノードはそのトークンを独自に再認証し、独自の一時ユーザーを作成します。

トラブルシューティング

  • アクセス権が付与されていない: 参照先のロールまたはユーザーに、必要な権限が付与されていない可能性があります。clickhouse:roles で参照しているロールが存在し、適切な権限が含まれていることを確認してください。
  • トークンが拒否される: トークン内の iss、aud、および署名アルゴリズムが、JWT プロバイダーの想定と一致していることを確認してください。JWKS を使用している場合は、トークンの kid がプロバイダーのキーセット内のキーと一致していることを確認してください。
  • クエリの間にユーザーが消える: 一時ユーザーは、トークンの有効期限が切れると削除されます。長時間のセッションでは、トークンの更新をサポートするクライアント (例: --login モード) を使用してください。
  • CREATE USER ... IDENTIFIED WITH jwt が失敗する: これは想定どおりです。JWT ユーザーは DDL では作成できません。管理は完全にトークンのライフサイクルに委ねられます。