Skip to content

OFCS 適合状況

go-oidc-providerOpenID Foundation Conformance Suite (OFCS) に対して回帰検査されています。ハーネスはソースリポジトリの conformance/ に置かれており、9 つの OFCS プランを準備します。本ページのベースラインは、v1.0.0 リリース時点のスナップショットを cmd/op-demo インスタンスへ end-to-end で実行した結果です。

個人開発、認証取得は無し

これは個人開発者が維持するプロジェクトです。OpenID Foundation 会員費は支払っておらず、形式的な OIDC 認証は取得していません。本ページの数値は、下に示すプラン集合の再現可能なスナップショットです。これは有償の OpenID Foundation 認証の代替ではなく、そのように引用しないでください。

OFCS スナップショットの読み方: 4 つの仕様ファミリにまたがる 9 プランを op-demo に対して実行し、各 module は PASSED / REVIEW / SKIPPED / 未判定 / FAILED のいずれか 1 つに分類される。テストプラン (9)module ごとの結果OIDC Core 1.06 プランFAPI 2.0 Baseline1 プランFAPI 2.0 Message Signing1 プランFAPI-CIBA1 プランcmd/op-demo対象 OP インスタンスPASSEDREVIEWSKIPPED未判定FAILED

この snapshot が検査する範囲

Planカバー範囲プロファイル
oidcc-basic-certification-test-plan認可コード + PKCE、ID トークン、UserInfo、refresh、discoveryOIDC Core 1.0
oidcc-config-certification-test-plandiscovery ドキュメントと公開 JWKS の形OIDC Core 1.0 — Discovery
oidcc-dynamic-certification-test-plan動的クライアント登録と、そこで登録したクライアントによる認可コードフローOIDC Core 1.0 — Dynamic Registration
oidcc-formpost-basic-certification-test-planbasic プランを response_mode=form_post で再実行OIDC Core 1.0 — form_post
oidcc-rp-initiated-logout-certification-test-plan/end_sessionid_token_hintpost_logout_redirect_uriRP-Initiated Logout 1.0
oidcc-backchannel-rp-initiated-logout-certification-test-planRP 起点のログアウトと、登録済みバックチャネル URI への logout_token 送達Back-Channel Logout 1.0
fapi2-security-profile-id2-test-plan+ PAR、送信者制約付きアクセストークン (DPoP)、厳格 alg list、redirect_uri 完全一致FAPI 2.0 Baseline
fapi2-message-signing-id1-test-plan+ JAR(署名 authorization request)、JARM(署名 authorization response)FAPI 2.0 Message Signing
fapi-ciba-id1-test-planClient-Initiated Backchannel Authentication(poll mode)、mTLS バインドトークンFAPI-CIBA

最新 baseline

271 件中 209 件の module が PASSED — 9 plan 合計の 77.1%
  • PASSED20977.1%
  • REVIEW3914.4%
  • SKIPPED155.5%
  • 未判定20.7%
  • FAILED62.2%
  • WARNING00.0%

FAILED と未判定の module はすべてレビュー済みの release exclusion です — 原因は 3 つだけで、未解決の欠陥はありません

取得日時2026-07-26T23:22:11Zリポジトリ SHA3ccc6bcOFCS イメージrelease-v5.2.1

スナップショットの状態

上のバーは 9 plan 全体の raw 結果です。対応する timestamp 付き JSON は conformance/baselines/ 配下にあります。make conformance-release-verify は、このリリース snapshot を blocker 0 と判定しました。raw failure と未判定 module はすべて conformance/release-exclusions.json のレビュー済み・期限付きエントリと照合されています。この判定は OIDC 認証ではありません。

FAILED 6 件の理由

FAILED と未判定の module は、すべて 3 つの原因のいずれかに帰着します。うち 2 つは 1.x 系で変えない設計判断で、残る 1 つはヘッドレス実行の限界です。未解決の欠陥はひとつもなく、いずれも conformance/release-exclusions.json に担当者と期限付きで記録されています。

署名は ES256 のみ — 段階的移行ではなく恒久的な方針

discovery が広告する署名 alg は ES256 だけです。そのため OIDC Core 1.0 §15.1 の RS256 必須要件を検証する module は失敗し、RS256 署名の ID トークンや UserInfo 応答を求める動的登録は assertion に到達する前に拒否されます。alg を 1 つに絞ることで alg ネゴシエーションと、それに伴うダウングレード対策そのものが不要になります。FAPI 2.0 も RS256 を明確に禁じています。alg list を閉じている理由

4 FAILED1 未判定
back-channel logout は sid 単位ではなく subject 単位

本 OP は backchannel_logout_session_supported: false を広告し、sid ではなく subject 単位でログアウトします。このメタデータは仕様上 optional ですが、この certification module は無条件に true を要求し、プラン残りも同じ assertion で中断します。sid 単位のセッションスコープログアウトは将来の minor で追加予定のオプトインプロファイルで、subject 単位は fail-secure 側の既定です。バックチャネルログアウト

2 FAILED
ハーネスが実行できない鍵ローテーション

oidcc-server-rotate-keys は「署名鍵をローテーションしてから Start を押す」ことを人間に要求します。本ライブラリは鍵束を op.New の時点で確定するため、実運用でのローテーションは provider の作り直しになり、プランで登録済みのクライアントを保持している in-memory store が失われます。OP が提供する内容自体には影響がなく、JWKS は設定済みの鍵をすべて公開しています。鍵ローテーション

1 未判定

plan 別の内訳

バーの長さは全 plan 共通の尺度で、その plan の module 数を表します。1 module の plan が 71 module の plan と同じ重さに見えることはありません。件数 0 の結果は行に出しません。

oidcc-basic-certification-test-plan · 35 module29 PASSED4 REVIEW2 SKIPPED
oidcc-config-certification-test-plan · 1 module1 FAILED
oidcc-dynamic-certification-test-plan · 23 module7 PASSED6 REVIEW5 SKIPPED2 未判定3 FAILED
oidcc-formpost-basic-certification-test-plan · 35 module30 PASSED3 REVIEW2 SKIPPED
oidcc-rp-initiated-logout-certification-test-plan · 11 module3 PASSED8 REVIEW
oidcc-backchannel-rp-initiated-logout-certification-test-plan · 2 module2 FAILED
fapi2-security-profile-id2-test-plan · 58 module48 PASSED9 REVIEW1 SKIPPED
fapi2-message-signing-id1-test-plan · 71 module60 PASSED9 REVIEW2 SKIPPED
fapi-ciba-id1-test-plan · 35 module32 PASSED3 SKIPPED
同じ snapshot を表で見る
PlanPASSEDREVIEWSKIPPEDWARNINGFAILED未判定合計
oidcc-basic-certification-test-plan294200035
oidcc-config-certification-test-plan0000101
oidcc-dynamic-certification-test-plan76503223
oidcc-formpost-basic-certification-test-plan303200035
oidcc-rp-initiated-logout-certification-test-plan38000011
oidcc-backchannel-rp-initiated-logout-certification-test-plan0000202
fapi2-security-profile-id2-test-plan489100058
fapi2-message-signing-id1-test-plan609200071
fapi-ciba-id1-test-plan320300035
合計2093915062271

各テストプランが検証する範囲

OFCS の各テストプランは、それぞれ特定の仕様プロファイルを検証します。以下の表は、プランごとに「該当コードパスを有効化するライブラリオプション」と「その挙動を解説しているページ」を対応づけたものです。組み込み側は、自分の配備が同じ構成を公開しているかをこの表で確認できます。

oidcc-basic-certification-test-plan — OIDC Core 1.0

検証範囲有効化に必要なオプション解説ページ
認可コードフロー + PKCE既定で有効/ja/concepts/authorization-code-pkce
ID トークンの発行と claim既定で有効/ja/concepts/tokens
UserInfo エンドポイント既定で有効/ja/concepts/tokens
Discovery (/.well-known/openid-configuration)既定で有効/ja/concepts/discovery
JWKS の公開既定で有効/ja/operations/jwks
リフレッシュトークン + ローテーション既定で有効、長期 refresh は offline_access スコープが必要/ja/concepts/refresh-tokens
標準スコープ (profileemailaddressphone)スコープごとに op.WithScope(...) を 1 回ずつ/ja/concepts/scopes-and-claims
public / pairwise サブジェクトpairwise は op.WithPairwiseSubject(salt)、適用判定はクライアントの SubjectType/ja/use-cases/pairwise-subject

fapi2-security-profile-id2-test-plan — FAPI 2.0 Baseline

検証範囲有効化に必要なオプション解説ページ
PAR (RFC 9126)op.WithProfile(profile.FAPI2Baseline) がプロファイルとして feature.PAR を有効化/ja/concepts/fapi/ja/use-cases/fapi2-baseline
JAR (RFC 9101)プロファイルが feature.JAR を有効化/ja/concepts/fapi
S256 PKCE の強制プロファイルが強制/ja/concepts/authorization-code-pkce
認可レスポンスの iss (RFC 9207)プロファイルが強制/ja/concepts/issuer
ID トークン署名アルゴリズム ES256プロファイルが強制。OP 発行 ID トークンは PS256 / RS256 では署名しない/ja/concepts/jose-basics
RS256(FAPI 文脈)・HS*none の拒否internal/jose/alg.go の closed enum で禁止/ja/security/design-judgments
private_key_jwtprofile が強制/ja/concepts/client-types
DPoP または mTLS による送信者制約op.WithFeature(feature.DPoP)op.WithFeature(feature.MTLS) のいずれか(FAPI 2.0 では少なくとも一方が必須)/ja/concepts/sender-constraint/ja/concepts/dpop/ja/concepts/mtls
redirect_uri 完全一致プロファイルが強制/ja/concepts/redirect-uri
リフレッシュトークンのローテーションと再利用検知既定で有効/ja/concepts/refresh-tokens

fapi2-message-signing-id1-test-plan — FAPI 2.0 Message Signing

Message Signing は Baseline に署名認可レスポンスを上乗せします。Baseline プランが検証する内容はこのプランでも全て実行され、プロファイル定数を切り替えるだけで JARM が自動有効化されます。

検証範囲有効化に必要なオプション解説ページ
FAPI 2.0 Baseline の全項目(上記)op.WithProfile(profile.FAPI2MessageSigning)(上記と同じ)
署名された認可レスポンス(JARM)プロファイルが feature.JARM を有効化/ja/concepts/fapi(JARM セクション)
token レスポンスの ID トークン署名プロファイルが強制/ja/concepts/tokens
request object 署名 (PS256 / ES256)プロファイルが強制/ja/concepts/fapi

fapi-ciba-id1-test-plan — FAPI-CIBA(Client-Initiated Backchannel Authentication)

CIBA プランは OpenID Connect Client-Initiated Backchannel Authentication grant を検証します。クライアントから開始された認証要求が、ユーザの認証デバイス(プッシュ通知、IVR 等)で非同期に完了し、ポーリング型の token 要求で消費される — という流れです。OP は poll mode で動作し、FAPI-CIBA は FAPI 1.0 のハードコード要件を引き継ぎ tls_client_certificate_bound_access_tokens を必須にするため、mTLS 送信者制約が必須です。

検証範囲有効化に必要なオプション解説ページ
/bc-authorize エンドポイント + auth_req_idop.WithCIBA(op.WithCIBAHintResolver(...))/ja/use-cases/ciba
ヒント解決(login_hint / id_token_hint / login_hint_token組み込み側が HintResolver を提供/ja/use-cases/ciba
ポーリング規律(authorization_pending / slow_down既定で有効、op.WithCIBAPollInterval(...) で advertised interval を上書き可/ja/use-cases/ciba
ポーリング濫用ロックアウトの上限既定 5 strikes、op.WithCIBAMaxPollViolations(n) で上下に調整可/ja/use-cases/ciba
tls_client_certificate_bound_access_tokens(FAPI-CIBA 必須)op.WithProfile(profile.FAPICIBA)feature.MTLS を有効化/ja/concepts/mtls
/bc-authorize への署名 request objectop.WithFeature(feature.JAR)(FAPI-CIBA で自動)/ja/concepts/fapi
request_objectiat / exp クレーム必須化(FAPI-CIBA §5.2.2)プロファイルが強制/ja/concepts/fapi

REVIEW / SKIPPED / WARNING / FAILED の意味

  • REVIEW — テストは実行されたが、ハーネスでは正直に検証できない視覚的 / out-of-band の挙動(同意 UI の文言、エラー画面のスクリーンショット、証明書チェーンの確認)を人間のレビュアーが裏取りする必要がある状態。失敗ではない。
  • SKIPPED — テストが依存する機能を、この OP が discovery やクライアントメタデータで宣言していないために OFCS が実行を見送った状態。例えば RS256 負例テストは、FAPI クライアントが PS256 を署名 alg として宣言しているため適用外になる。失敗ではない。
  • WARNING — OFCS が非 failure の result value として記録する状態。主たる assertion は終端 PASS まで到達したが、運用者が対処すべき advisory がログに残っている場合に使われます。現在の snapshot では 0 件 です。
  • FAILED — module が suite の期待結果に到達しませんでした。v1.0.0 snapshot の 6 件は、恒久的な ES256-only 署名方針による 4 件と、back-channel logout を意図的に subject 単位に留めていることによる 2 件です。いずれもレビュー済みの release exclusion で、明示的かつ期限内の記録がなければ release verifier は失敗します。
  • 未判定 — ハーネスが終端結果を得られませんでした。現在の 2 module はプロセス内の署名鍵ローテーションを必要とするものと、ES256-only OP が正しく拒否する RS256 request object を待ち続けるものです。いずれもレビュー済みの release exclusion です。

自分で conformance を回すには

  1. 該当プロファイルを組み込んだ OP を立ち上げます — security プロファイルなら op.WithProfile(profile.FAPI2Baseline)、message signing なら op.WithProfile(profile.FAPI2MessageSigning)、FAPI-CIBA なら op.WithProfile(profile.FAPICIBA) と CIBA オプション、OIDC Core プランなら WithProfile 無し。
  2. プランを OFCS deployment に登録します。conformance suite は OpenID Foundation が運用しています。ソースリポジトリの conformance/ 配下にプランテンプレートとローカル起動用の固定 Docker イメージが入っています。
  3. プランを実行します。ハーネスは /authorize/par/token/userinfo/jwks ほか discovery で公開された各エンドポイントを必須経路で全て呼び出し、JSON スナップショットを書き出します。記録済 baseline との差分が取れます。

詳細な runbook(make ターゲット、JSON スナップショットの構造、差分ゲート)は下の自分でベースラインを再現するを参照してください。

REVIEW と FAILED の違い

OFCS は主に PASSEDFAILEDREVIEWSKIPPED を返します。本ハーネスは OFCS が advisory として出す WARNING result もそのまま保持します。REVIEW はテスト失敗を意味しません。 自動化では確認できない箇所を人間の運用者に確認してほしい、という意味です — 例「OP はここでログイン画面を表示したか?」。テストは実行され、スクリーンショットを撮り、誰かが OFCS UI で「review 済み」をクリックするまで WAITING に留まります。本ハーネスはそこに到達してエラーが出なければ REVIEW を記録します。

なぜ REVIEW を auto-pass しないか

conformance suite は意図的にこれらの module を人間の判断にゲートしています。ヘッドレスで動く cmd/op-demo は「これがユーザに見えた画面です」というスクリーンショットを誠実にアップロードできません。ゲートを外して通してしまうのは、実際にチェックされた内容を偽ることになります。ハーネスは REVIEW のまま記録し、有償認証取得時は UI を見ながら通すことを前提にしています。

現在 FAILED の module — 理由

3 plan にまたがる 6 module です。各行は conformance/release-exclusions.json のレビュー済み・期限付きエントリと対応しており、記録が欠けている・担当者が無い・期限切れのいずれかであれば make conformance-release-verify がリリースを止めます。

ModulePlan失敗する理由
oidcc-discovery-endpoint-verificationoidcc-configid_token_signing_alg_values_supportedES256 しか列挙しておらず、この module は OIDC Core 1.0 §15.1 の RS256 必須要件を検証するため。
oidcc-discovery-endpoint-verificationoidcc-dynamic同じ assertion、同じ原因が dynamic プランでも発生。
oidcc-idtoken-rs256oidcc-dynamicid_token_signed_response_alg=RS256 で登録を要求するが、動的クライアント登録が invalid_client_metadata を返すため assertion まで到達しない。
oidcc-userinfo-rs256oidcc-dynamicuserinfo_signed_response_alg=RS256 について同様。
oidcc-backchannel-logout-discovery-endpoint-verificationoidcc-backchannel-rp-initiated-logout本 OP は仕様上許容される backchannel_logout_session_supported: false を広告するが、この module がそれを認めないため。
oidcc-backchannel-rp-initiated-logoutoidcc-backchannel-rp-initiated-logout上の module から連鎖。プランがその assertion で中断するため、この module は実行に到達しない。

現在 未判定 の module — 理由

ハーネスが終端結果まで駆動できなかった 2 module です。いずれも実稼働中の suite に対する単体実行で得た証跡付きで記録しています。

ModulePlan判定が出ない理由
oidcc-server-rotate-keysoidcc-dynamic運用者が署名鍵をローテーションして Start を押すのを待つ module です。鍵束は op.New で確定し、プラン実行中に provider を作り直すと登録済みクライアントを保持する in-memory store が失われます。module は runner の idle 上限まで CONFIGURED のまま留まります。
oidcc-request-uri-signed-rs256oidcc-dynamicRS256 署名の request object を push し、認可レスポンスの成功を待つ module です。ES256-only の OP はリダイレクト前に拒否します — これが正しい挙動であり、コールバックが届かないため suite はどちらの結果も記録できません。

現在 REVIEW の module

oidcc-basic plan (4)

Moduleゲート対象
oidcc-ensure-registered-redirect-uriOP が未登録 redirect_uri を拒否したことの手動確認
oidcc-max-age-1max_age=1 でユーザを再プロンプトしたことの手動確認
oidcc-prompt-loginprompt=login で再プロンプトしたことの手動確認
oidcc-response-type-missingresponse_type が無いリクエストに対する first-party error page の手動確認

FAPI 2.0 plans (各 9、同集合)

これらは全て、OP のエラーページのスクリーンショット upload か「ユーザが実際に再プロンプトされたか」の手動判断にゲートされます。ヘッドレスでも問題なく実行できますが、人間のサインオフが入るまでは REVIEW に留まります(fapi2-security-profile-id2fapi2-message-signing-id1 の両プランで同じ 9 件が REVIEW になり、合計 18 件です):

  • fapi2-…-ensure-different-nonce-inside-and-outside-request-object
  • fapi2-…-ensure-different-state-inside-and-outside-request-object
  • fapi2-…-ensure-request-object-with-long-nonce
  • fapi2-…-ensure-request-object-with-long-state
  • fapi2-…-ensure-unsigned-authorization-request-without-using-par-fails
  • fapi2-…-par-attempt-reuse-request_uri
  • fapi2-…-par-attempt-to-use-expired-request_uri
  • fapi2-…-par-attempt-to-use-request_uri-for-different-client
  • fapi2-…-state-only-outside-request-object-not-used

OP は各ケースで正しい HTTP エラーを返します(負例テストの内部 assertion は通過)— OFCS が描画されたエラー UI を人間に inspect してもらいたいだけです。

現在 WARNING の module

現在の snapshot ではありません。以前 WARNING だった fapi-ciba-id1-refresh-token は、通常の PASSED module になっています。

現在 SKIPPED の module — 理由

Module理由
fapi2-…-ensure-signed-client-assertion-with-RS256-fails(×2)プランで使う FAPI クライアントが token_endpoint_auth_signing_alg=PS256 を登録しているため、OFCS はクライアント別 RS256 負例を fapi2 系両プランでスキップ。
fapi2-message-signing-…-ensure-signed-request-object-with-RS256-fails同様 — FAPI クライアントの request_object_signing_alg=PS256RS256 負例を該当外にする。
fapi-ciba-id1-ensure-request-object-signature-algorithm-is-RS256-failsFAPI-CIBA クライアントが request_object_signing_alg=PS256 を登録しているためスキップ。
fapi-ciba-id1-ensure-client-assertion-signature-algorithm-in-backchannel-authorization-request-is-RS256-fails同様 — CIBA クライアントの token_endpoint_auth_signing_alg=PS256
fapi-ciba-id1-ensure-client-assertion-signature-algorithm-in-token-endpoint-request-is-RS256-fails同様。
oidcc-ensure-request-object-with-redirect-urioidcc-basic プランは JAR を有効化しないため、OP は discovery から request_object_signing_alg_values_supported を省略し OFCS はスキップ。
oidcc-unsigned-request-object-supported-correctly-or-rejected-as-unsupported同様 — JAR off、request パラメータ無し、OFCS スキップ。

"SKIPPED" は意図的、「走らなかった」ではない

OFCS のスキップ判定は、discovery とクライアント別メタデータが宣伝する内容に基づきます。プラン内の FAPI クライアントは PS256 をトークンエンドポイント認証 / request object 署名 alg として宣言しているため、OFCS の「RS256 は失敗すべき」プローブは適用外と判定され、「実際に実行して pass を記録する」のではなく skipped になります。

自分でベースラインを再現する

sh
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
make conformance-up
make conformance-baseline LABEL=local-check
ls conformance/baselines/   # JSON スナップショットがここに着地

ハーネスは:

  1. 自己署名 RSA-2048 証明書を生成(scripts/conformance.sh certs)。
  2. https://localhost:8443 で OFCS Docker スタックを立ち上げ。
  3. https://127.0.0.1:9443cmd/op-demo をビルド・起動。
  4. OFCS REST API 経由で plan を seed。ハーネスは 9 plan を scaffold し、上の最新 status table は 9 plan 全体を記録しています。
  5. module 毎の pass/fail を決定論的 JSON に記録。

make conformance-baseline-diff は 2 スナップショット間で PASSED失った module があれば非ゼロ終了 — セキュリティ関連変更に対するプロジェクトのプリマージゲートです。

このコードベースでの FAPI 2.0 の意味

op.WithProfile(profile.FAPI2Baseline) は 2 つの fapi2-* plan が想定する設定を有効化します:

  • feature.PARFAPI2Baseline で自動有効化) — /par がルート可能、/authorizerequest_uri を受理
  • feature.JARFAPI2Baseline で自動有効化) — request / request_uri を署名 JWT として検証
  • feature.JARMFAPI2MessageSigning で追加で自動有効化) — 認可レスポンスを JWT として署名
  • 送信者制約付きアクセストークン — プロファイルは DPoP-or-mTLS 要件を課します。組み込み側が feature.MTLScnf.x5t#S256)を明示的に有効化した場合はそれで要件を満たし、DPoP 既定は追加されません。どちらも明示されていない場合、op.Newfeature.DPoPcnf.jkt)を標準の既定として選ぶため、素の op.WithProfile(profile.FAPI2Baseline) でも sender-constrained access token 付きで起動します。DPoP が有効なら discovery は dpop_signing_alg_values_supported: ES256, EdDSA, PS256 を宣伝
  • JOSE alg 許可リストはコードベース全体で RS256 / PS256 / ES256 / EdDSA にロック、HS*none構造的 に到達不能(internal/jose/alg.go 参照)
  • token_endpoint_auth_methods_supported を FAPI 本番経路(private_key_jwt)に交差
  • redirect_uri 完全一致を強制
  • クライアント別 RequestObjectSigningAlg / TokenEndpointAuthSigningAlg で各 FAPI クライアントを PS256(または ES256 / EdDSA)に絞り込みつつ、discovery doc にはコードベース全体のリストを掲載

WithProfile 後にプロファイルと衝突するオプションを設定すると、op.New(...) は本番に partial-FAPI を出さず構築時エラーを返します。

ハーネスの構成ファイル

Path内容
conformance/README.md運用 runbook
conformance/plans/*.jsonプランテンプレート(server / client / resource ブロック)
conformance/docker-compose.ymlOFCS イメージのタグ固定(release-v5.2.1)+ JKS truststore 実装
scripts/conformance.shcerts / ofcs-up / op-up / seed-plans / drive / batch
tools/conformance/ofcs.pyREST クライアント + ヘッドレス drive スクリプト
conformance/baselines/*.json取得済スナップショット(gitignored — 環境依存)

明示しておく制限事項

  • プランスイートのバージョン。 OFCS は release-v5.2.1 で固定しています。新しい OFCS リリースで追加・改名されたテストは、固定バージョンを引き上げるまで対象外です。
  • ヘッドレス実行。 実行スクリプトは OFCS の REST API をリバースエンジニアリングしているもので、OFCS 側にドキュメントはありません。挙動確認は v5.2.1 でしか取れていません。
  • 本物の RP 証明書なし。 mTLS プラン枠は conformance/certs/ の生成済み自己署名証明書を使っており、プランをインスタンス化できる程度に整えてあるだけです。本物の CA チェーン検証はしていません。
  • OP インスタンス 1 個。 インスタンス間挙動(例: ストア共有の OP 2 個でのトークン introspection)は OFCS ではなく test/scenarios で検査します。

conformance ハーネスは test/scenarios/ 配下の in-process Spec Scenario Suite と並走します。前者はライブ OP に対して HTTP 経由で end-to-end に実行し、後者は同じプロトコル不変条件を in-process で実行します — 両方が緑であることをセキュリティ関連変更の前提にしています。