OIDC ベースの JWT アクセストークンを用いてユーザーアクセスを制御する
このページは英語版のページが機械翻訳されたものです。英語版との間に矛盾または不一致がある場合は、英語版を正としてください。
ScalarDB Cluster は、OpenID Connect (OIDC) プロバイダー (Keycloak など) が発行する JWT アクセストークンに基づいてユーザーアクセスを制御できます。これはパスワードベース認証の代替手段として機能し、クライアントアプリケーションが ScalarDB パスワードを直接管理することなく認証リクエストを実行できるようにします。属性ベースアクセス制御 (ABAC) と組み合わせることで、ScalarDB Cluster は JWT アクセストークンに埋め込まれたクレームに基づいて、リクエストごとにアクセスを動的に制限できます。
OIDC ベースアクセス制御の動作原理
以下のセクションでは、OIDC ベースアクセス制御のユースケース、認証フロー、および検証ルールについて説明します。
ユースケース
OIDC ベースアクセス制御は、1人以上の OIDC ユーザーが単一の ScalarDB サービスユーザーにマップされるシナリオ向けに設計されています。OIDC クライアントアプリケーションは、OIDC プロバイダーを通じてユーザーを認証し、ScalarDB ユーザー名とアクセススコープを含む JWT アクセストークンを取得し、ScalarDB Cluster への各リクエストでそのトークンを送信します。
OIDC プロバイダーは JWT アクセストークンをクライアントアプリケーションに発行します。クライアントは ScalarDB Cluster への各リクエストでトークンを送信し、ScalarDB Cluster はトークンを検証し、ScalarDB ユーザーにマップし、トークンクレームに基づいてアクセスを制限します。
認証フロー
クライアントが JWT アクセストークンとともにリクエストを送信すると、ScalarDB Cluster は以下のステップを実行します:
- OIDC プロバイダー設定の取得。 ScalarDB Cluster は
{issuer_url}/.well-known/openid-configurationから OpenID プロバイダー設定を取得し、結果をキャッシュします。 - JWKS の取得。 ScalarDB Cluster はプロバイダー設定から JSON Web Key Set (JWKS) URL を抽出し、キーを取得してキャッシュします。
- JWT の検証。 ScalarDB Cluster は RFC 9068 に従ってトークンの署名と標準クレームを検証します。
- トークンの ScalarDB ユーザーへのマッピング。 ScalarDB Cluster は設定されたクレームから ScalarDB ユーザー名を抽出し、ユーザーレコードを検索します。
- 認証方法の検証。 ScalarDB Cluster は、ユーザーが OIDC 認証の使用を許可されており、発行者が信頼されていること を確認します。OIDC 認証は、ユーザーが
AUTH_METHOD OIDCオプションで作成された場合に有効になります。 - 有効時の ABAC 制限の適用。 OIDC ベース ABAC が有効な場合、JWT には ABAC クレームが含まれている必要があります。ScalarDB Cluster はセッションの ABAC ユーザータグを計算して適用します。ABAC クレームがないトークンは拒否されます。
- リクエストの実行。 ScalarDB Cluster は、適用可能な制限とともに、マップされた ScalarDB ユーザーとしてリクエストを実行します。
JWT アクセストークンの検証
ScalarDB Cluster は RFC 9068 に従って JWT アクセストークンを検証します。具体的には、以下のチェックを実行します:
typヘッダー: デフォルトでは、typヘッダーはat+jwtまたはapplication/at+jwtである必要があります。require_at_jwt_typをfalseに設定することで、このチェックを無効にできます。- 署名: トークンの署名は、OIDC プロバイダーの JWKS エンドポイントからのキーを使用して検証されます。以下のアルゴリズムのみが受け入れられます: RSASSA-PKCS-v1_5、RSASSA-PSS、ECDSA。
issクレーム: 発行者 はtrusted_issuersで設定された値と一致する必要があります。audクレーム: オーディエンスにはaudience.nameで設定された値が含まれている必要があります。expクレーム: トークンは期限切れであってはいけません。設定可能なクロックスキュー許容値が適用されます。
ユーザーマッピング
ScalarDB Cluster は、検証された JWT から username.claim_name で指定されたクレームの値を抽出して ScalarDB ユーザーを特定します。ScalarDB はこの値を使用して、users メタデータテーブル内の対応するユーザーレコードを検索します。
ユーザー名クレームは慎重に選択してください。ScalarDB ユーザーを OIDC ユーザー間で意図せずまたは誤って共有すると、セキュリティ問題が発生する可能性があります。
動的 ABAC 制限
OIDC ベース ABAC が有効な場合、ScalarDB Cluster は JWT から ABAC クレーム (デフォルト名: scalardb_abac) を読み取り、現在のリクエストに対するユーザーのアクセスを動的に制限するために使用します。ABAC クレームは、マップされた ScalarDB ユーザーの権限を制限することはできますが、拡張することはできません。
ABAC クレームが存在するが ScalarDB ユーザーの権限を超えている場合、リクエストは拒否されます。OIDC ベース ABAC が有効で、JWT から ABAC クレームが欠落している場合も、リクエストは拒否されます。
ABAC の詳細については、ユーザーアクセスをきめ細かく制御するを参照してください。クレーム構造と検証ルールの詳細については、JWT ABAC クレームリファレンスを参照してください。
設定
このセクションでは、OIDC ベースアクセス制御の設定について説明します。一般的な認証・認可設定については、ユーザーの認証と認可を参照してください。
サーバー側設定
以下は、OIDC ベースアクセス制御に必要な最小限のサーバー側設定です。scalar.db.cluster.auth.enabled を true に設定する必要もあります。ABAC を使用する場合は、scalar.db.cluster.abac.enabled も true に設定する必要があります。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
scalar.db.cluster.auth.oidc.trusted_issuers | 信頼される OIDC 発行者 URL。iss クレームがこの値と一致しないトークンは拒否されます。OIDC ベースアクセス制御を使用する場合、このプロパティを指定する必要があります。 | empty |
scalar.db.cluster.auth.oidc.username.claim_name | ScalarDB ユーザー名を抽出するために使用される JWT クレーム名。OIDC ベースアクセス制御を使用する場合、このプロパティを指定する必要があります。 | empty |
scalar.db.cluster.auth.oidc.audience.name | JWT aud クレームの期待値。 | scalardb |
scalar.db.cluster.auth.oidc.abac.enabled | OIDC ベース ABAC を有効にするかどうか。true の場合、JWT には ABAC クレームが必要です。 | false |
追加のサーバー側設定 (キャッシュ TTL、クロックスキューなど) については、ScalarDB Cluster 設定の OIDC 設定を参照してください。
クライアント側設定
以下は、OIDC ベースアクセス制御のクライアント側設定です。oidc_jwt を使用する場合、scalar.db.username と scalar.db.password プロパティは必要ありません。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
scalar.db.cluster.client.auth.type | プリミティブインターフェースの認証タイプ。OIDC の場合は oidc_jwt に設定します。 | empty (userpass として扱われる) |
scalar.db.sql.cluster_mode.auth.type | SQL インターフェースの認証タイプ。OIDC の場合は oidc_jwt に設定します。 | empty (userpass として扱われる) |
OidcJwtAccessTokenHolder を使用してプログラム的に JWT アクセストークンを渡すことができ、これは多くの OIDC ユーザーを処理する場合に推奨されるオプションです。あるいは、アクセストークンプロパティ (プリミティブインターフェー スの場合は scalar.db.cluster.client.auth.oidc_jwt.access_token、SQL インターフェースの場合は scalar.db.sql.cluster_mode.auth.oidc_jwt.access_token) でトークンを提供することもでき、これは特に SQL CLI などのツールでテストする場合に簡単に開始できます。ただし、トークンは初期化時に設定されるため、リフレッシュはできません。
追加のクライアント側設定については、ScalarDB Cluster 設定のプリミティブインターフェースおよび SQL インターフェースの設定を参照してください。
チュートリアル - OIDC と ABAC でアクセス制御
このチュートリアルでは、OIDC プロバイダーとして Keycloak を使用して、OIDC ベースアクセス制御と ABAC を設定する方法を説明します。ScalarDB Cluster の設定、ABAC ポリシーの設定、Keycloak の設定、および curl と Java クライアントの両方を使用した検証を行います。
前提条件
- 以下のいず れかの Java Development Kit (JDK):
- Oracle JDK: 8、11、17、または 21 (LTS バージョン)
- OpenJDK ディストリビューション (Eclipse Temurin、Amazon Corretto、または Microsoft Build of OpenJDK): 8、11、17、または 21 (LTS バージョン)
- Docker 20.10 以降と Docker Compose V2 以降
- JSON 処理用の
jq
このチュートリ アルでは、Keycloak のホスト名として auth.localhost を使用します。macOS と Linux では、*.localhost サブドメインは RFC 6761 に従って自動的に 127.0.0.1 に解決されます。環境で名前解決が機能しない場合 (一部の Windows 設定や Firefox などの特定のブラウザ)、hosts ファイル (macOS/Linux では /etc/hosts、Windows では C:\Windows\System32\drivers\etc\hosts) に以下のエントリを追加してください:
127.0.0.1 auth.localhost
ScalarDB Cluster を使用するには、ライセンスキー (試用ライセンスまたは商用ライセンス) が必要です。ライセンスキーをお持ちでない場合は、お問い合わせください。
1. ScalarDB Cluster 設定ファイルの作成
scalardb-cluster-node.properties という名前の設定ファイルを作成し、以下の設定を追加します。<YOUR_LICENSE_KEY> と <LICENSE_CHECK_CERT_PEM> を ScalarDB ライセンスキーとライセンスチェック証明書の値に置き換えてください。ライセンスキーと証明書の詳細については、プロダクトライセンスキーの設定方法を参照してください。
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql:5432/postgres
scalar.db.username=postgres
scalar.db.password=postgres
scalar.db.cluster.node.standalone_mode.enabled=true
scalar.db.sql.enabled=true
# このチュートリアルでの SELECT 文による全スキャンを実行するためにクロスパーティションスキャンを有効にします。
# これは OIDC や ABAC 自体には必要ありません。
scalar.db.cross_partition_scan.enabled=true
scalar.db.cross_partition_scan.filtering.enabled=true
# 認証と認可を有効にする
scalar.db.cluster.auth.enabled=true
# OIDC 設定
# auth.localhost はホストでは RFC 6761 により解決され、コンテナ内では Docker ネットワークエイリアスにより解決されます。
scalar.db.cluster.auth.oidc.trusted_issuers=http://auth.localhost:8080/realms/scalardb-demo
scalar.db.cluster.auth.oidc.audience.name=scalardb
scalar.db.cluster.auth.oidc.username.claim_name=scalardb_username
scalar.db.cluster.auth.oidc.jwt.access_token.require_at_jwt_typ=true
# ABAC 設定
scalar.db.cluster.abac.enabled=true
scalar.db.cluster.auth.oidc.abac.enabled=true
# ライセンスキー設定
scalar.db.cluster.node.licensing.license_key=<YOUR_LICENSE_KEY>
scalar.db.cluster.node.licensing.license_check_cert_pem=<LICENSE_CHECK_CERT_PEM>