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 などのツールでテストする場合に簡単に開始できます。ただし、トークンは初期化時に設定されるため、リフレッシュはできません。また、オペレーション属性を使用して、特定のトランザクション、操作、または SQL ステートメントにトークンを渡すこともできます。詳細については、JWT アクセストークンをプログラムで渡すを参照してください。
追加のクライアント側設定については、ScalarDB Cluster 設定のプリミティブインターフェースおよび SQL インターフェースの設定を参照してください。
JWT アクセストークンをプログラムで渡す
設定プロパティに JWT アクセストークンを設定する代わりに、以下の方法でプログラムで渡すことができます:
- スレッドごと:
OidcJwtAccessTokenHolderを使用して、コードブロックの実行中に現在のスレッドのトークンを設定します。 - トランザクション、操作、または SQL ステートメントごと: auth 属性
auth-typeとauth-oidc-jwt-access-tokenを使用します。
どちらのメカニズムも userpass および oidc_jwt 認証タイプで同じように機能し、認証と認可ガイドのクレデンシャルをプログラムで渡すで説明されています。OidcJwtAccessTokenHolder を使用した完全なアプリケーション例については、以下のチュートリアルの 7. Java クライアントでの接続を参照してください。
チュートリアル - 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>
2. Docker Compose フ ァイルの作成
docker-compose.yaml という名前の設定ファイルを作成し、以下の設定を追加します。
services:
postgresql:
container_name: "postgresql"
image: "postgres:15"
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready || exit 1"]
interval: 1s
timeout: 10s
retries: 60
start_period: 30s
keycloak:
container_name: "keycloak"
image: "quay.io/keycloak/keycloak:26.2"
ports:
- 8080:8080
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KC_HOSTNAME=http://auth.localhost:8080
command: start-dev
networks:
default:
aliases:
- auth.localhost
scalardb-cluster-standalone:
container_name: "scalardb-cluster-node"
image: "ghcr.io/scalar-labs/scalardb-cluster-node-with-abac-byol-premium:3.19.0"
ports:
- 60053:60053
- 9080:9080
volumes:
- ./scalardb-cluster-node.properties:/scalardb-cluster/node/scalardb-cluster-node.properties
depends_on:
postgresql:
condition: service_healthy
ghcr.io/scalar-labs/scalardb-cluster-node-with-abac-byol-premium イメージは、ABAC 機能が有効な ScalarDB Cluster ノードイメージで、公開されていません。このイメージへのアクセスについては、お問い合わせください。
3. サービスの開始
以下のコマンドを実行して、PostgreSQL、Keycloak、および ScalarDB Cluster をスタンドアロンモードで開始します。
docker compose up -d
すべてのサービスが健全になるまで待ちます。以下のコマンドで確認できます:
docker compose ps
4. ABAC ポリシーの設定と OIDC ユーザーの 作成
ScalarDB Cluster に接続するため、このチュートリアルでは SQL CLI を使用します。SQL CLI は ScalarDB Cluster に接続して SQL クエリを実行するツールです。SQL CLI は ScalarDB リリースページからダウンロードできます。
scalardb-cluster-sql-cli.properties という名前の設定ファイルを作成し、以下の設定を追加します。
scalar.db.sql.connection_mode=cluster
scalar.db.sql.cluster_mode.contact_points=indirect:localhost
# 認証と認可を有効にする
scalar.db.cluster.auth.enabled=true
以下のコマンドを実行して SQL CLI を開始します。プロンプトが表示されたら、ユーザー名とパスワードをそれぞれ admin と admin として入力します。
java -jar scalardb-cluster-sql-cli-3.19.0-all.jar --config scalardb-cluster-sql-cli.properties
次に、以下の SQL 文を実行して ABAC ポリシーを設定し、OIDC ユーザーを作成します。
レベル、コンパートメント、およびグループを持つポリシーの作成
-- ポリシーの作成
CREATE ABAC_POLICY demo_policy WITH DATA_TAG_COLUMN demo_policy_tag;
-- レベルの作成 (レベル番号が高いほど高い機密性)
CREATE ABAC_LEVEL HS WITH LONG_NAME HIGHLY_SENSITIVE AND LEVEL_NUMBER 3000 IN POLICY demo_policy;
CREATE ABAC_LEVEL S WITH LONG_NAME SENSITIVE AND LEVEL_NUMBER 2000 IN POLICY demo_policy;
CREATE ABAC_LEVEL C WITH LONG_NAME CONFIDENTIAL AND LEVEL_NUMBER 1000 IN POLICY demo_policy;
-- コンパートメントの作成
CREATE ABAC_COMPARTMENT HR WITH LONG_NAME HUMAN_RESOURCES IN POLICY demo_policy;
CREATE ABAC_COMPARTMENT FIN WITH LONG_NAME FINANCE IN POLICY demo_policy;
-- グループの作成 (親子階層を持つ)
CREATE ABAC_GROUP EU WITH LONG_NAME EUROPE IN POLICY demo_policy;
CREATE ABAC_GROUP NA WITH LONG_NAME NORTH_AMERICA IN POLICY demo_policy;
CREATE ABAC_GROUP CS WITH LONG_NAME CUSTOMER_SUCCESS AND PARENT_GROUP EU IN POLICY demo_policy;
ネームスペースへのポリシーの適用
-- ネームスペースの作成とポリシーの適用
CREATE NAMESPACE IF NOT EXISTS my_namespace;
CREATE ABAC_NAMESPACE_POLICY ns_policy_demo USING POLICY demo_policy AND NAMESPACE my_namespace;
-- ポリシーの有効化
ENABLE ABAC_POLICY demo_policy;
ENABLE ABAC_NAMESPACE_POLICY ns_policy_demo;