Skip to content

オプション一覧 ​

op.New に渡せる公開オプションを、設定対象ごとに分類しました。WithIssuer、WithStore、WithKeyset は常に必須です。WithCookieKeys と WithLoginFlow は authorization_code grant を有効にしている場合に必須で、既定 grant 集合では有効です。それ以外は既定を上書きする任意オプションです。op パッケージの godoc(op/doc.go の「Option groups」)にも、同じオプションがグループ別に載っています。

このページの読み方

オプション名のリンクから詳細ページに進めます。「セクション」列は、そのオプションが影響する discovery 文書やエンドポイントの範囲を示します。「既定」が空欄のオプションは組み込みの初期値を持っておらず、明示的に渡したときだけ機能が有効になります。

最初に読むオプション ​

オプションは次の 3 層に分かれます。上から順に読んでください。

層オプション参照先
まずここからWithIssuer、WithStore、WithKeyset。authorization_code が有効な間は WithCookieKeys と WithLoginFlow。続いて WithProfile。そのうえで多くの場合、WithStaticClients、WithLogger、WithMountPrefix、WithTrustedProxies、WithUI、WithPrometheus、WithAuditLogger必須と条件付き必須、プロファイル / feature / grant、クライアント / 登録、観測
ユースケース別追加する機能に合うセクションを選びます。サインイン、UI、トークン、discovery とエンドポイント、subject 戦略、追加 grant、RAR と Grant Management、JWE、mTLS とプロキシ認証 / LoginFlow、UI、トークン、Discovery / エンドポイント、subject 戦略、grant、認可機能、暗号化(JWE)、mTLS / プロキシ / ネットワーク
ほとんど不要開発・テスト用の切り替え(WithAllowInsecureOutboundForDev、WithAllowLocalhostIssuerForDev)とテスト用の注入(WithClock)。本番では有効にしません。WithAllowPrivateNetwork は別扱いで、プライベートネットワーク上の RP に届くためのネットワーク到達性の設定であり、本番でも正当に使いますmTLS / プロキシ / ネットワーク、運用方針

どのオプションが必要か ​

このページは、op.New に渡せる公開オプションを並べた一覧です。80 以上のオプションがあるため、目的が決まった状態で表を眺めると目的の項目を探しにくいことがあります。下の判定図で関連する領域を見つけ、表の該当セクションへ進んでください。

まず全体を左右するオプションから
設定の目的を、それを担う op.New のオプションへ振り分ける判定図の前半。新規に OP を立ち上げる、FAPI のプロファイルを有効化する、機能を 1 つ有効化する、のいずれか。どれにも当たらなければ次の図へ進みます。OP を新規に立ち上げるまだ何も動いていない段階はい必須オプションissuer · store · keyset · cookie 鍵 · ログインいいえFAPI 2.0 を 1 行で有効化する個別の設定ではなくプロファイル全体が欲しいはいWithProfile(…)プロファイルの設定を一括で適用するいいえプロファイルなしで機能を 1 つ有効化するPAR、JAR、JARM、grant management などはいWithFeature(…)機能 1 つを単独で有効にするいいえまだ当てはまらない場合は下へ
プロファイルは後段の設定をいくつか自動的に確定させるため、機能の質問より先にプロファイルの質問をします。
次に grant・送信者制約・トークン形式を絞る
判定図の後半。/token が受け付ける grant を絞る、送信者制約を加える、アクセストークンの形式を選ぶ、のいずれか。どれにも当たらなければ下の全オプション表へ進みます。/token が受け付ける grant を絞る例: client credentials は発行しないはいWithGrants(…)列挙外の grant は拒否されるいいえ送信者制約付きアクセストークンにする漏れたトークン単体では使えない状態にしたいはいWithFeature(DPoP) · WithFeature(MTLS)どちらでも両方でも。各クライアントが選ぶいいえJWT と opaque のどちらにするか決めるaudience 単位で決める判断はいWithAccessTokenFormat(…)失効の到達範囲とレイテンシの取引いいえどれにも当てはまらない — 下の全オプション表へ
2 つの図を上から下へ読む順序が、そのまま設定する順序でもあります。当てはまらないものは下の全オプション表にあります。
  • これから新規に OP を立ち上げる → まず WithIssuer、WithStore、WithKeyset、WithCookieKeys、WithLoginFlow を渡します。後ろの 2 つは authorization_code grant が有効な場合に必須で、既定 grant 集合では有効です。詳しくは必須オプション と最小 OP の組み立て。
  • FAPI を採用せず OAuth 2.1 の姿勢にしたい → これが既定です。WithProfile なしの OP は profile.OAuth21 で動き、すべての authorization-code request に PKCE を要求し、それ以外は OIDC Core の既定を保ちます。PKCE を送れない RP のために、WithProfile(profile.OIDCCore) で外せます。FAPI 2.0 には本ライブラリの profile.FAPI2Baseline(または profile.FAPI2MessageSigning、profile.FAPICIBA)を使います。これらのプロファイルは mTLS が明示されていなければ DPoP を既定選択します。プロファイルが必要とする grant が組み込まれていない場合、OP はエンドポイントを勝手に mount せず op.New が失敗します(profile.FAPICIBA は grant.CIBA を必要とします)。ユースケース: セキュリティプロファイルの宣言、ユースケース: FAPI 2.0 Baseline、ガイド: FAPI 2.0 入門 を参照。
  • プロファイル全体ではなく、機能を 1 つだけ有効にしたい → WithFeature(feature.PAR) / JAR / JARM / DPoP / MTLS / Introspect / Revoke。public / native client は常に PKCE 必須で、既定の profile.OAuth21 と FAPI プロファイル下ではすべての認可コードクライアントに PKCE が必須です。Dynamic Registration、RAR、Grant Management は追加設定が必要なので、それぞれ専用オプションから有効化します。
  • /token で受け付ける grant の集合を絞りたい → WithGrants(grant.AuthorizationCode, grant.RefreshToken, grant.ClientCredentials, grant.DeviceCode)。協力者(collaborator)を要する grant は専用のオプション(WithCIBAGrant(...)、WithJWTBearerGrant(...))で有効にします。詳しくはgrant を有効にする規則を参照してください。WithCustomGrant(...) と WithTokenExchangeGrant(...) も、それぞれの grant に必要なものをまとめて公開します。
  • 送信者制約付きのアクセストークンにしたい → DPoP 系: WithFeature(feature.DPoP) + 必要に応じて WithDPoPNonceSource(op.NewInMemoryDPoPNonceSource(...))。mTLS 系: WithFeature(feature.MTLS) + 必要に応じて WithMTLSProxy(op.MTLSProxy{HeaderName: ..., TrustedProxies: ...})。WithMTLSProxy と WithMTLSRootCAs には feature.MTLS が必要です。複数レプリカで DPoP nonce を使うなら、op/storeadapter/redis の Store.DPoPNonceSource を使います。詳しくはガイド: 送信者制約付きトークン、DPoP、mTLS、ユースケース: DPoP nonce フロー。
  • アクセストークンを JWT / opaque で切り替えたい → OP 全体の既定は WithAccessTokenFormat(...)、RFC 8707 リソースごとに分けたいときは WithAccessTokenFormatPerAudience(...)。ガイド: アクセストークンの形式 を参照。
  • sector ごとに pairwise sub にしたい → WithPairwiseSubject(salt)(32 byte 以上の salt)。ユースケース: Pairwise subject を参照。
  • 起動時にクライアントを静的に投入したい → WithStaticClients(op.PublicClient{...}, op.ConfidentialClient{...}, op.PrivateKeyJWTClient{...})(構造体リテラル)。ガイド: クライアント種別 を参照。
  • Dynamic Client Registration を使いたい → WithDynamicRegistration(...)。ユースケース: 動的クライアント登録 を参照。
  • introspection / revocation エンドポイントを公開したい → WithFeature(feature.Introspect) および / または WithFeature(feature.Revoke)。細かな調整は下の「プロファイル / feature / grant」表を参照。
  • scope カタログを拡張したい → discovery に出す scope は WithScope(op.PublicScope("name", "label"))、内部用は WithScope(op.InternalScope("name"))。ガイド: scope と claim、ユースケース: Public / Internal スコープ を参照。
  • 独自の grant_type を追加したい → WithCustomGrant(handler)。ユースケース: カスタム grant を参照。
  • i18n(国際化)対応をしたい → WithDefaultLocale(...)、WithLocaleBundle(bundle)、WithPreferredLocaleStore(...)。ユースケース: i18n / ロケール解決 を参照。
  • JWE request object を復号したい → OP が受け取る JWE の鍵に WithEncryptionKeyset(...) を指定し、必要なら WithSupportedEncryptionAlgs(op.EncryptionAlgs{KeyManagement: ..., ContentEncryption: ...}) で既定の許可リストを狭めます。外向きの JWE 応答は受信側 client の JWKS の鍵で暗号化します。ユースケース: JWE 暗号化 を参照してください。
  • SPA クライアント向けに CORS を開けたい → WithCORSOrigins(...)。ユースケース: SPA 向け CORS を参照。
  • Prometheus メトリクスを出したい → WithPrometheus(registry)。ライブラリは /metrics を公開しないため、ハンドラの公開はルータ側で行います。ユースケース: Prometheus メトリクス を参照。
  • 監査ログをアプリログとは別の出力先に流したい → WithAuditLogger(*slog.Logger)。Audit イベントカタログ を参照。
  • ブラウザの SPA にログイン画面を任せたい → WithUI(op.SPAUI{LoginMount: ...})。WithUI(op.DriverUI{Driver: ...}) は、ブラウザ以外のフロントエンドや、HTML 以外を描画する driver 用に取っておきます。op.SPAUI の下ではログイン・同意・アカウント選択を SPA が担い、SPA が <LoginMount>/state から取得するプロンプトは JSON(interaction.JSONDriver)で描画されます。ユースケース: SPA / 対話画面のカスタマイズ を参照。

オプションの合成 ​

オプションは次の 3 種類のいずれかです。

  • 単一値。 引数を取るオプションは、行に加算的と書かれていない限り、1 つの設定を決めます。同じオプションを 2 回渡した場合(<Name> may be called at most once)や、2 つのオプションが同じ設定を決める場合(WithSubjectGenerator conflicts with prior WithPairwiseSubject)は op.New が失敗します。後の呼び出しが前の呼び出しを黙って置き換えることはありません。
  • 加算的。 繰り返し呼ぶと要素が積み上がります。WithStaticClients、WithCORSOrigins、WithTrustedProxies、WithTrustedProxyHosts、WithScope、WithFeature、WithProfile、WithInteractions、WithLoginAttemptObserver、WithFirstPartyClients、WithCustomGrant、WithAuthorizationDetailTypes、WithProtectedResources が該当します。
  • フラグ。 引数のないオプションは冪等で、繰り返しても何も変わりません。

次の 2 つは繰り返し呼べますが、規則がより狭くなります。WithEndpoints は複数回呼べますが、各パスのフィールドは単一値です。WithLocaleBundle のロケールの各キーは単一値で、2 回の呼び出しで同じロケールの別々のキーを渡すことはできますが、同じキーは渡せません。

オプション値内容既定
WithDefaults...op.Option内側のオプションを既定値として扱うなし
  • WithDefaults:内側の単一値オプションは、WithDefaults の外にあるオプションが同じ設定を決めたとき、順序に関係なくそちらに譲る。内側の加算的オプションとフラグはそのまま適用される。既定値どうしが同じ設定を決める場合は、やはり op.New が失敗する。共通のオプション一覧の上に、デプロイごとの上書きを重ねる用途に使う: op.New(op.WithDefaults(baseOptions()...), op.WithAccessTokenTTL(5*time.Minute))。op/testkit は自身の設定を WithDefaults 経由で渡すので、testkit.WithOptions(...) は引き続き testkit の既定を置き換える

必須と条件付き必須 ​

Option値セクション既定
WithIssuerstringdiscovery issuer / JWT iss / cookie scope—
WithStorestore.Storeプロトコル状態のすべてのサブストア—
WithUserStorestore.UserStoreID トークンと /userinfo の claim を読むエンドユーザ記録の供給元。推論された供給元より優先されるLoginFlow.Primary が op.PrimaryPassword ならその Store(primary の op.StepOneOf 内にあれば最初の op.PrimaryPassword の Store)
WithKeysetop.Keyset(既定の ES256 は ECDSA P-256 鍵、WithSigningAlgorithm(op.AlgRS256) を指定したときは 2048 ビット以上の RSA 鍵)JWKS / JWS 署名—
WithCookieKeys32 byte の鍵session / CSRF cookie の AES-256-GCMauthorization_code 有効時に必須
WithLoginFlowop.LoginFlowユーザのサインイン方法authorization_code 有効時に必須
  • WithUserStore:同梱アダプタの具象 Users() はそのまま渡せる: op.WithUserStore(st.Users())。有効な grant がエンドユーザを解決しうる(client_credentials 以外のすべて)のに、このオプションも op.PrimaryPassword の store も指定されていないと op.New が失敗するため、passkey のみ・device-code・CIBA の構成では必須。既定:WithStore のバックエンドが参照されることはない。client_credentials だけの OP では不要。

プロファイル / feature / grant ​

Option値セクション既定
WithProfileprofile.Profile本ライブラリの profile.OAuth21(既定)、profile.OIDCCore、または FAPI プロファイルを宣言profile.OAuth21
WithFeaturefeature.Flag (1 呼び出しで 1 つ、繰り返し可)PAR / DPoP / mTLS / JAR / JARM / introspect / revoke を個別に有効化控えめな既定
WithGrants...grant.Type (可変長)/token で受け付ける grant を限定authorization_code、refresh_token
WithScopeop.Scope (1 呼び出しで 1 つ。op.PublicScope / op.InternalScope コンストラクタを利用)scope カタログを拡張openid、profile、email、address、phone、offline_access
WithOpenIDScopeOptional(引数なし)OAuth 2.0 単独(scope に openid を含まない)を許容openid 必須
WithStrictOfflineAccess(引数なし)refresh_token の発行を offline_access の同意取得時に限定緩やかな既定(openid が付与されれば発行)
  • WithProfile:profile.OAuth21 は OAuth 2.1 で、すべての authorization-code request に PKCE を求める。profile.OIDCCore は OpenID Connect Core 1.0 の形で、confidential client では PKCE 任意。他のプロファイルとは組み合わせられず、組み合わせると op.New が失敗する。FAPI プロファイルでは mTLS が明示されていない場合に DPoP を既定の送信者制約方式として選択。プロファイルが要求する feature は自動で有効化されるが、grant が足りない場合は op.New が失敗し、有効化に必要なオプション名をエラーが示す。
  • WithGrants:単一値なので、複数の helper から option を合成する場合は渡す前に grant 集合をまとめてください。既定の集合を置き換えます。WithLoginFlow、WithUI、WithInteractions、WithFirstPartyClients を明示的に設定したまま grant.AuthorizationCode を含めないと、op.New は op.ErrAuthorizationCodeGrantRequired で失敗します。device_code や CIBA の claim の取得元になっている login flow と、WithDefaults の中のオプションは数えません

grant と feature の有効化方法 ​

有効化の仕組みは 3 種類あります。協力者を要しない grant は WithGrants、協力者を要する機能は専用のオプション、プロトコル拡張は WithFeature(またはその機能を要求するプロファイル)で有効にします。WithGrants と専用オプションのどちらからでも有効にできるのは device_code だけです。

機能有効化の方法
authorization_code、refresh_token既定で有効。WithGrants で集合を置き換える
client_credentialsWithGrants(grant.ClientCredentials)
Device code(RFC 8628)WithDeviceCodeGrant。WithGrants で選んだ集合に、オプションの順序にかかわらず grant.DeviceCode が加わる
CIBA poll モードWithCIBAGrant。これを使わずに WithGrants へ grant.CIBA を入れると op.New が失敗する
JWT bearer(RFC 7523)WithJWTBearerGrant。これを使わずに WithGrants へ grant.JWTBearer を入れると op.New が失敗する
Token exchange(RFC 8693)WithTokenExchangeGrant(WithIDJAGIssuance でもこの grant が有効になる)
独自の grant_typeWithCustomGrant
PAR、JAR、JARM、DPoP、mTLS、introspection、revocationWithFeature(feature.X)、またはそれを要求するプロファイルによる自動有効化
動的クライアント登録、RAR、Grant Managementそれぞれ専用のオプション(WithDynamicRegistration、WithAuthorizationDetailTypes、WithGrantManagement)。対応する feature フラグはない
PKCE常にサポート。feature.PKCE は効果がなく、渡すと op.New が起動時に警告を出す。code_challenge は既定(profile.OAuth21)で全クライアントに必須で、confidential client で任意になるのは WithProfile(profile.OIDCCore) の場合だけ

grant を有効にする規則 ​

  • 協力者を要する grant は専用のオプションで有効にします。WithGrants だけでは op.New が拒否します。CIBA には login hint の resolver(WithCIBAGrant)が、JWT bearer には信頼する issuer と subject の解決(WithJWTBearerGrant)が必要です。
  • device_code は協力者を要しないので、どちらでも有効にできます。WithGrants(..., grant.DeviceCode) でも WithDeviceCodeGrant(op.DeviceCodeGrant{}) でも構いません。
  • WithGrants に挙げた grant を専用のオプションでも有効にしても、何も起きません(no-op)。専用のオプションは、WithGrants で選んだ集合に、順序にかかわらず自分の grant を加えます。

クライアント / 登録 ​

Option値セクション既定
WithStaticClients...op.ClientSeed (op.PublicClient / op.ConfidentialClient / op.PrivateKeyJWTClient を渡す)起動時にクライアントレジストリを初期投入空
WithHighEntropyClientSecrets(引数なし)OP 全体の client-secret 検証を high-entropy keyed-hash 形式へ切り替えるArgon2 互換の client secret
WithFirstPartyClients...string (client ID)ファーストパーティ同意スキップの対象なし
WithDynamicRegistrationop.DynamicRegistration/register を公開(RFC 7591 / 7592)無効
WithClientIDMetadataDocumentsop.ClientIDMetadataDocuments(構造体。任意の Allow 関数)Client ID Metadata Documents(draft-ietf-oauth-client-id-metadata-document)を有効にする無効
  • WithStaticClients:client_id の重複、Secret も SecretHash もない ConfidentialClient、jwks と jwks_uri を両方持つシードは op.New が拒否する。シードを一度書き込んだ後は、保存済みのレコードが正となる。シードを編集したら起動前に SyncStaticClients を実行する(クライアントのオンボーディング を参照)
  • WithHighEntropyClientSecrets:既存の Argon2 client hash は後から変換できないため、有効化前に全クライアントを再プロビジョニングする
  • WithClientIDMetadataDocuments:Allow func(ctx, clientID string) bool は、取得の前に毎回呼ばれる。nil なら、ドラフトの URL 規則を満たす URL をすべて許可する。MCP の認可クライアントが使う登録経路で、URL の client_id は取得したドキュメントに解決される。ドキュメントが宣言できるのは authorization_code と refresh_token の grant、認証方式は none か private_key_jwt だけ。PKCE は常に必須で、これらのクライアントがファーストパーティ自動同意を受けることはない。登録済みのクライアントは、同じ値の URL より優先される。1 回だけ指定できる。Experimental(IETF ドラフトに追従)で、discovery に client_id_metadata_document_supported を載せる

認証 / LoginFlow ​

Option値セクション既定
WithLoginFlowop.LoginFlowStep + Rule の宣言的 DAGなし
WithInteractions...op.Interaction (可変長)WithUI で選んだモードが描画する、資格情報以外の追加画面(T&C、KYC など)consent のみ
WithLoginAttemptObserverop.LoginAttemptObserverRuleAfterFailedAttempts 用の失敗回数集計なし
WithMFAEncryptionKeys32 byte の鍵TOTP シークレットを AES-256-GCM で保存時暗号化なし
WithAuthnLockoutStorestore.AuthnLockoutStore組み込みの password / TOTP / email-OTP / recovery-code ステップが共有する、subject 単位の失敗カウンタを永続化WithStore の値が持つ AuthnLockouts()
WithACRPolicyop.ACRPolicy (interface)または op.ACRLevels(独自 acr から最小 AAL への map)ログインがどの acr を満たしたかの判定と報告op.DefaultACRPolicy(標準の acr URI のみ)
  • WithLoginFlow:LoginFlow.Primary は subject を確定させる step でなければならない。StepTOTP・StepEmailOTP・StepRecoveryCode は既知の subject を前提とするため、subject を確定する primary の後に Rule の step として置く。違反すると op.New が失敗する。Primary(またはそこに置いた StepOneOf)の PrimaryPasskey はパスワードレスのログインになり、RequireUserVerification が必須で、未設定なら op.New が失敗する。独自の op.Authenticator は op.ExternalStep で組み込み、risk assessor は LoginFlow.Risk に指定する
  • WithInteractions:consent と chooser は組み込み画面の名前で、この名前の要素は op.New が拒否する

WithAuthnLockoutStore が支えるのは、subject ごとに 1 つの 24 時間ローリングカウンタです。累計 30 回の失敗で 1 時間、90 回で 24 時間ロックします。組み込みの PrimaryPassword、StepTOTP、StepEmailOTP、StepRecoveryCode はすべてこのカウンタに数えられるので、認証要素を切り替えて推測の回数を倍にすることはできません。誤ったパスワードは数えられ、ロック中は正しいパスワードでも誤りと同じ応答で拒否されます。パスワードのログインに成功してもカウンタはリセットされません。存在しないユーザ名と、パスワードハッシュを持たないアカウントはカウンタに触れません。PrimaryPasskey は対象外で、passkey の ceremony の責務です。Primary より後の ExternalStep は CountFailures を設定するとこのカウンタに加わります。Primary では subject が未確定のため設定できず、リモートの verifier が自前のロックアウトを持ちます。ロックが新たに成立すると lockout.engaged を発行します(監査イベント)。

このオプションを指定しない場合、op.New は WithStore の値が AuthnLockouts() を持っていればそれを使います。in-memory、SQL、DynamoDB の adapter は持っており、composite.Store は AuthnLockouts の kind に振り分けたバックエンドのものを転送します。明示したオプションが常に優先されます。カウンタを使うステップ(パスワード、第 2 要素、CountFailures を持つ ExternalStep)がログインフローにあるのに store が解決できないときは、op.New は起動を拒否して op.ErrAuthnLockoutStoreRequired を返します。errors.Is で判定できます。SQL と DynamoDB の store は耐久性があり、レプリカ間で共有されます。inmem.Store.AuthnLockouts() はプロセスローカルで、再起動時にリセットされます。

WithACRPolicy には任意の op.ACRPolicy を渡せます。op.ACRLevels は独自の acr 値を宣言する map 形式です(MFA / ステップアップを参照)。Resolve が ok=false を返したとき、essential の acr 要求は unmet_authentication_requirements で拒否され、voluntary の要求ではログインが到達したレベルの標準 URI が報告されます。

認証 factor のレコードは意図的に store.Store の外にあります。StepTOTP / PrimaryPasskey / StepRecoveryCode / StepEmailOTP はそれぞれ専用 store を受け取ります。登録スキーマ、暗号鍵、アカウント復旧ポリシーは組み込みアプリケーション側の設計だからです。in-memory、SQL、DynamoDB adapter は対応する accessor を公開します。examples/27-durable-mfa-store は、同梱 SQL adapter の factor store を OP のコアテーブルと同じ DB で使う例です。別のバックエンドでだけ factor-store 契約を自前実装してください。

TOTP と email-OTP の Version は store が発行する opaque な equality-only CAS token です。順序性を推測したり自前で生成したりせず、stale な CAS は consumed / stale error として扱います。PasskeyStore.Put は異なる subject の同じ credential ID を atomically に拒否し、credential を別 subject へ移してはなりません。

耐久 store 実装者向けに重要な factor-store 契約が 2 つあります。store.EmailOTPStore.Get は code の ExpiresAt だけでなく EmailOTPRecord.RetainUntil までは record を読める状態に保つ必要があります。これにより、code が失効しても resend cap と brute-force counter はリセットされません。store.RecoveryStore.Consume は、提示された code hash と現在保存されている slot の hash を比較し、古い hash を拒否する必要があります。recovery code を再生成した後に、漏洩済みの古い code が新しい batch の slot を消費するのを防ぐためです。

UI ​

Option値セクション既定
WithUIop.HTMLUI、op.SPAUI、op.DriverUI のうちちょうど 1 つサインイン・同意・アカウント選択の描画方式を選ぶ。単一値で、有効なモードは 1 つだけなので組み合わせの問題は生じないop.HTMLUI{}(組み込みの HTML ページ)
op.HTMLUI構造体: Login / Consent / Chooser(それぞれ op.PageTemplate: Template *html/template.Template と ContentSecurityPolicy)組み込みのページを描画し、Template を設定した画面だけを差し替える。state / CSRF / 永続化は OP が担当組み込みのマークアップ
op.SPAUI構造体: LoginMount / StaticDir / ContentSecurityPolicySPA の入口と静的アセット一式を OP 側で公開し、interaction の状態も JSON で提供なし
op.DriverUI構造体: Driver interaction.Driver自前のドライバ(サーバ側レンダラ、外部フロントエンド向けの JSON ドライバなど)で prompt を描画なし
WithLogoutUIop.LogoutUI (構造体: ConfirmTemplate / SignedOutTemplate (どちらも *html/template.Template で必須)と ContentSecurityPolicy)RP-Initiated Logout の 2 つのページ(確認ページとサインアウト完了ページ)を組み込み側テンプレートで描画同梱ページ
WithCORSOrigins...stringAPI CORS に追加する明示 originAPI route は自動導出、ceremony は issuer のみ
WithDefaultLocaleop.Locale (BCP 47 タグ)canonical BCP 47 の既定 UI locale。未登録の default は op.New が拒否"en"
WithLocaleBundleop.LocaleBundle (1 呼び出しで 1 つ、繰り返し可)同梱 HTML ドライバ用のロケール別メッセージバンドルを登録英語 + 日本語の初期バンドル
WithPreferredLocaleStoreop.PreferredLocaleStore§L.2 優先順序の先頭で参照されるユーザ単位ロケール上書きなし
  • WithUI:ブラウザのサインイン系オプションで、authorization_code なしで設定すると op.New が失敗する。各モードは下記
  • op.HTMLUI:Template が nil の画面は組み込みのマークアップのまま。Login は同意・チューザ・パスキー以外のすべてのサインイン prompt(パスワード、TOTP、メール OTP、リカバリ、factor 選択、captcha、自前 Step)を担う。カスタムログイン UIを参照
  • op.SPAUI:route になるのは LoginMount だけ。ContentSecurityPolicy は SPA の入口に付く既定のポリシーを置き換える(後述)
  • op.DriverUI:自前のドライバや、独自の translator を持つ interaction.HTMLDriver にページテンプレートを重ねるときは、interaction.TemplateOverlayDriver を渡す
  • WithLogoutUI:確認テンプレートは Fields を range で出力する必要があり、宣言した CSP は既定のヘッダ全体を置き換え、どの WithUI モードでも有効。ログアウト画面をブランド化するを参照
  • WithCORSOrigins:redirect URI の origin は API CORS 用には自動導出されるが、interaction と end-session の ceremony check は issuer origin + この明示リストだけを許可

WithUI が受け取るモードは 1 つだけなので、モードどうしが衝突することはありません。SPAUI.LoginMount だけが SPA route になります。同意画面とアカウント選択は login interaction state surface を使い、logout の確認ページは通常の end-session flow に残り、サーバが描画します。見た目を変えるには WithLogoutUI を使います。詳細は カスタムアカウント選択 UI を参照してください。

SPA の入口(StaticDir を指定した場合の LoginMount/{uid})には、既定の Content-Security-Policy が付きます。値は default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none' です。インライン script、外部 origin、<base> 要素を使う bundle は SPAUI.ContentSecurityPolicy を指定してください。値は PageTemplate.ContentSecurityPolicy と同じ規則で検証され、拒否された値は op.New が失敗します。アセットの応答にはポリシーが付きません。詳細は SPA カスタムインタラクションを参照してください。

ceremony の origin は issuer と same-site でなければなりません。login.example.com と op.example.com のような issuer の sibling は、ここに列挙すれば利用できますが、完全に別サイトの origin は CORS header を受け取っても interaction / end-session ceremony は動きません。__Host- cookie が SameSite の制約で送信されず、endpoint が 404 を返すためです。UI は issuer 自身か same-site の sibling host に置いてください。cookie 属性は変更できません。

WithLocaleBundle は locale tag を小文字・ハイフン区切りの canonical BCP 47 形式にします。Provider.SetLocaleCookie(w, locale) と Provider.ClearLocaleCookie(w) が公開 cookie seam です。SetLocaleCookie は exact match と language-only fallback を解決し、登録済み locale に一致しなければ op.ErrLocaleNotRegistered を返します。cookie は __Host-oidc_locale、Secure、HttpOnly、SameSite=Lax で、login session とは独立しています。

トークン ​

Option値セクション既定
WithAccessTokenFormatop.AccessTokenFormat (AccessTokenFormatJWT / AccessTokenFormatOpaque)OP 全体で JWT / opaque を選択JWT
WithAccessTokenFormatPerAudiencemap[string]op.AccessTokenFormat (RFC 8707 リソース → 形式)audience ごとに形式を切り替えOP 全体の値
WithAccessTokenRevocationStrategyop.AccessTokenRevocationStrategy発行済 JWT アクセストークンの失効ポリシーgrant tombstone
WithAccessTokenTTLtime.Durationアクセストークンの寿命5 分
WithSigningAlgorithmop.SigningAlgorithm(op.AlgES256 / op.AlgRS256)OP がすべての JWS の発行に使う単一のアルゴリズムES256
WithRefreshTokenTTLtime.Duration通常のリフレッシュトークンの寿命30 日
WithRefreshTokenOfflineTTLtime.Durationoffline_access が付与されたときのリフレッシュトークンの寿命通常のリフレッシュトークンの寿命を継承
WithRefreshGracePeriodtime.Duration (0 で無効化、負値は拒否。リフレッシュトークンをローテーションしない FAPI 2.0 profile では op.New がエラーを返す)ローテーション後の猶予期間60 秒
WithDPoPNonceSourceop.DPoPNonceSource (interface)サーバ供給の DPoP nonce ストアなし
WithIDTokenScopeClaims...string(scope 名)指定した scope が /userinfo で開放する claim を ID Token にも書き込む無効
  • WithAccessTokenRevocationStrategy:値は RevocationStrategyGrantTombstone、RevocationStrategyJTIRegistry、RevocationStrategyNone。既定の GrantTombstone は Store.GrantRevocations()、JTIRegistry は Store.AccessTokens() を必須とし、いずれも op.New で検査される
  • WithSigningAlgorithm:アクティブな WithKeyset の鍵の種類(ES256 は ECDSA P-256、RS256 は 2048 ビット以上の RSA)と、discovery や動的クライアント登録が示す値が決まる。アルゴリズムを切り替える間は、アクティブな鍵より後ろの Keyset エントリに別アルゴリズムの鍵を置けるが、それぞれに NotAfter が必要。profile.FAPI2Baseline、profile.FAPI2MessageSigning、profile.FAPICIBA では AlgRS256 が拒否され、それ以外の値は op.New が失敗する。1 回だけ指定できる
  • WithRefreshTokenOfflineTTL:既定:WithRefreshTokenTTL を継承(ゼロ値で延長しない)。
  • WithDPoPNonceSource:op.NewInMemoryDPoPNonceSource が同梱実装
  • WithIDTokenScopeClaims:profile、email、address、phone、または Claims が空でない登録済みの custom scope を 1 つ以上渡す。対象は authorization_code、refresh_token、device_code、CIBA の各 grant の ID Token。OIDC Core §5.4 から意図的に外れる。公開 / 内部 scopeを参照

WithInMemoryDPoPNonceLogger は op.New ではなく op.NewInMemoryDPoPNonceSource に渡す補助オプションです。同梱の in-memory nonce source を使う場合だけ指定します。

profile.FAPI2Baseline と profile.FAPI2MessageSigning はリフレッシュトークンをローテーションしない(Security Profile §5.3.2.1(9))ため、設定すべき猶予期間がなく、これらの profile ではこの option を op.New が拒否します。これらの profile 以外では、負でない duration を指定できます。

WithAccessTokenFormat と WithAccessTokenFormatPerAudience が制御するのは、組み込み grant path が発行するアクセストークンです。custom grant の BoundAccessToken は、どちらの option を指定しても常に RFC 9068 JWT として mint されます。custom grant で opaque 値が必要な場合は、handler 自身で mint して AccessToken として返してください。送信者制約付きにしたい場合も、cnf は handler 自身が付与します。

認可コードおよびその refresh chain から発行される JWT アクセストークンには、userinfo_claims という private claim が入ります。値は OIDC claims リクエストの userinfo メンバーで、リクエストになければ {} です。/userinfo はこの claim から返す claim を決めます。リソースサーバは無視してかまいません。この名前は予約済みで、custom grant の extra claims からは設定できません。

Discovery / エンドポイント ​

Option値セクション既定
WithEndpointsop.Endpoints (構造体: 各エンドポイントのパス上書き)各エンドポイントのパスを上書き仕様の既定
WithMountPrefixstring (/ で始める。ルートに置くなら /)プロトコルエンドポイントに issuer 相対のパス接頭辞を設定。discovery のパスは issuer から別に決まる/oidc
WithClaimsSupported...string (可変長)discovery の claims_supported を埋める省略
WithClaimsParameterDisabled(引数なし)claims_parameter_supported を無効にする有効
WithACRValuesSupported...string (可変長)acr_values_supported を公開空(discovery に出ず、許可リストなし)
WithDiscoveryMetadataop.DiscoveryMetadata (型付きの service_documentation / policy / TOS / UI locale / mTLS alias フィールド + Extra map[string]any)OP が所有しない RFC 8414 / OIDC Discovery メタデータを discovery 文書に追加なし
WithPARTTLtime.Duration/par が発行する request_uri の寿命を上書き60 秒
WithJWKSRotationActivefunc() boolローテーション期間中だけ JWKS の Cache-Control を短期キャッシュに切り替える述語常に長期キャッシュ
  • WithClaimsParameterDisabled:malformed JSON は引き続き拒否するが、正しい claims payload の投影は抑止して authorize / PAR では無視する
  • WithACRValuesSupported:空でない場合、同じ許可リストを /auth、/par、CIBA の /bc-authorize でも強制する
  • WithDiscoveryMetadata:UILocalesSupported は非空時に自動導出された locale list を上書きし、OP 管理フィールドと衝突する Extra key は拒否(OP 自身が公開する prompt_values_supported も含む)
  • WithPARTTL:失効判定はブラウザが /auth に URI を提示した時点で行い、その後の code 発行では単回使用性だけを強制

subject 戦略 ​

Option値セクション既定
WithSubjectGeneratorop.SubjectGenerator (interface)sub claim の導出を上書き。同梱の op/subject.UUIDv7 が既定UUIDv7 をそのまま使用
WithPairwiseSubject[]byte salt(32 byte 以上)OIDC Core §8.1 の sector ごと pairwise sub 導出を有効化public(UUIDv7)
  • WithSubjectGenerator:generator は各 projection で呼ばれ、同じ input に deterministic で surprise I/O を行ってはならない
  • WithPairwiseSubject:途中で戦略を切り替えると op.New が拒否する

詳細は ユースケース: Pairwise subject。

grant — Device Code / CIBA / カスタム grant / Token Exchange ​

Option値セクション既定
WithDeviceCodeGrantop.DeviceCodeGrantRFC 8628 device-authorization grant を有効化無効
WithCIBAGrantop.CIBAGrantCIBA poll mode を有効化。/bc-authorize を公開し CIBA URN を登録。1 回だけ呼べる無効
WithCustomGrantop.CustomGrantHandler組み込み側が定義する grant_type URN を /token に登録なし
WithTokenExchangeGrantop.TokenExchangeGrant(構造体。Policy が必須)RFC 8693 token-exchange grant を有効化無効
WithJWTBearerGrantop.JWTBearerGrant(構造体。Issuers []op.AssertionIssuer、ResolveSubject func(ctx, op.AssertionSubject) (string, error))RFC 7523 §2.1 の JWT bearer grant を有効化し、その URN を /token に登録する無効
WithIDJAGIssuanceop.IDJAGIssuancePolicy(インターフェース。Allow(ctx, op.IDJAGRequest) (*op.IDJAGDecision, error)。nil 不可)token exchange が requested_token_type=urn:ietf:params:oauth:token-type:id-jag に対し、この OP が発行した ID token を元に署名付きの Identity Assertion JWT Authorization Grant(ID-JAG)を返せるようにする無効
  • WithDeviceCodeGrant:/device_authorization を公開し /token に URN を登録。1 回だけ呼べる。フィールド: VerificationURI(デバイス画面に表示する絶対 URL。既定は <issuer>/device)、TTL(新規 device_code レコードの expires_in 寿命。アクセストークン TTL とは独立。既定 10 分)、PollInterval(広告する poll interval。これより速い poll は slow_down。既定 5 秒)。ゼロ値のフィールドは既定のまま、負の期間は op.New が拒否する。この grant はエンドユーザを解決するため、op.New には WithUserStore か op.PrimaryPassword の store も必要
  • WithCIBAGrant:フィールド: HintResolver(必須)、DefaultRequestTTL(既定 600 秒)、MaxRequestTTL(requested_expiry の上限。ゼロなら上限なし)、PollInterval(既定 5 秒)、MaxPollViolations(既定 5)。ゼロ値のフィールドは既定のまま。負の期間、および MaxRequestTTL を超える DefaultRequestTTL は op.New が拒否する。profile.FAPICIBA では、既定と最大の有効期限を 10 分までに制限する
  • WithCustomGrant:custom name の重複と組み込み grant type との collision は構築時に拒否される。handler はアクセストークンをそのまま返すか、BoundAccessToken 要求として返して OP に署名させる
  • WithTokenExchangeGrant:ポリシーがリクエスト単位で受理可否(admission)を判断し、OP の既定値をさらに狭めることもできる。1 回だけ呼べる
  • WithJWTBearerGrant:各 AssertionIssuer には Issuer(OP 自身の issuer は不可、重複不可)、JWKSURI(https)と JWKS のどちらか一方、空でない AllowedClients、Profile(op.AssertionProfileJWT=ゼロ値、または experimental の op.AssertionProfileIDJAG)を設定する。ResolveSubject は検証済み assertion をローカルの subject に対応づける。プロビジョニングされていないアカウントには op.ErrUnknownAssertionSubject を返す。この grant は end user を解決するため、op.New は WithUserStore か op.PrimaryPassword の store も要求する。これを使わずに WithGrants へ grant.JWTBearer を入れると op.New が失敗する。assertion の jti はすべて一度きりで(store.ConsumedJTIStore は複数レプリカで共有する)、refresh token も ID token も発行せず、access token は grant レコードに紐づかないため Provider.RevokeSubject では失効しない。1 回だけ呼べる
  • WithIDJAGIssuance:audience、scope、resource を制限できるのはポリシーだけで、拒否するには op.ErrIDJAGUnknownAudience か op.ErrIDJAGDenied を返す。WithTokenExchangeGrant なしでも token-exchange grant が有効になる。1 回だけ呼べる。Experimental(IETF ドラフトに追従)

device-code・CIBA・token exchange の各 grant が発行する credential は、記録された grant の配下に置かれます。そのため grant の失効、ユーザ削除、pairwise sub の解決がこれらにも届きます。custom grant は、handler が grant を記録した場合にだけ grant に紐づきます。custom grant 自身の refresh rotation が発行するアクセストークンは常に JWT です。

DeviceCodeGrant.TTL と DeviceCodeGrant.PollInterval は WithAccessTokenTTL から導出されません。アクセストークンを短命にしても、TV / CLI のペアリング手順までユーザがセカンドスクリーンに移る前に失効しないようにするためです。詳細は Device Code、CIBA、カスタム grant、トークン交換。

認可機能 — RAR / Grant Management / Protected Resource Metadata ​

オプション値説明既定
WithAuthorizationDetailTypes...op.AuthorizationDetailTypeRFC 9396 Rich Authorization Requests を有効化無効
WithGrantManagementop.GrantManagement{Actions []op.GrantManagementAction; ActionRequired bool}OAuth 2.0 Grant Management draft を有効化無効
WithProtectedResources...op.ProtectedResource登録した各リソースについて RFC 9728 protected-resource メタデータを /.well-known/oauth-protected-resource とリソース path の接尾辞で公開し、authorization_servers に issuer を載せるなし
  • WithAuthorizationDetailTypes:受理する type を validator とともに登録する。authorization_details は /auth、/par、/token で検証され、grant に永続化され、JWT アクセストークンと introspection に反映され、discovery で公開される。nil の Validate は op.New で拒否される
  • WithGrantManagement:grant_management_action / grant_id を処理し、query / revoke エンドポイントを公開し、token 応答に grant_id を載せ、設定した action 集合を discovery で公開する。Experimental(IETF draft 追跡)。1 回だけ呼べる(2 回目は op.New が失敗する)
  • WithProtectedResources:ProtectedResource.IntrospectionClients はその resource を audience とする access token を指定 confidential caller が introspect するための委譲であり、refresh token には適用されない

op.StepUpChallenge(realm, acrValues, maxAge) は op.New のオプションではなく独立したヘルパで、組み込み側のリソースサーバが返す RFC 9470 の WWW-Authenticate: Bearer challenge を組み立てます。OP 自身はこれを発行しません。

詳細は Rich authorization requests、Grant management、Protected resource メタデータ、MFA / ステップアップ。

暗号化(JWE) ​

Option値セクション既定
WithEncryptionKeysetop.EncryptionKeyset (RSA 2048 bit 以上 / EC P-256/384/521 の秘密鍵、use=enc)OP の inbound 復号用 JWK を公開し、/auth と /par の JWE request object を復号なし
WithSupportedEncryptionAlgsop.EncryptionAlgs{KeyManagement []string; ContentEncryption []string}既定の許可リスト(RSA-OAEP-256 / ECDH-ES{,+A128KW,+A256KW} × A{128,256}GCM)を 狭める だけ既定の許可リスト全体
  • WithEncryptionKeyset:outbound JWE 応答は受信側 client の JWKS を使う
  • WithSupportedEncryptionAlgs:広げることはできない。KeyManagement は JWE の alg、ContentEncryption は enc の値で、それぞれ 1 回だけ狭められる

詳細は ユースケース: JWE 暗号化。

mTLS / プロキシ / ネットワーク ​

Option値セクション既定
WithMTLSRootCAs*x509.CertPool直接または前送りされた client certificate を OP 自身が検証するための公開 trust pool。nil は拒否未設定(終端側で検証)
WithMTLSProxyop.MTLSProxy{HeaderName string; TrustedProxies []string}edge でヘッダ経由の mTLS を終端なし
WithTrustedProxies...string (CIDR。加算的で、繰り返し呼ぶと積み上がる)許可した proxy からの X-Forwarded-For / -Proto / -Host を、実クライアントの IP・スキーム・ホストとして解決なし
WithTrustedProxyHosts...string (hostname)trusted proxy CIDR が設定されている場合に、正規の issuer host 以外の X-Forwarded-Host 許可リストを追加issuer host のみ
WithAllowLocalhostRedirectURIs(引数なし)http の redirect URI のホストに文字列 localhost を許可する(RFC 8252 のネイティブアプリとローカル開発向け)リテラル loopback のみ
WithAllowLocalhostIssuerForDev(引数なし)issuer に文字列 localhost を許可する。ローカル開発と passkey の検証向けで、開発専用リテラル loopback の IP のみ
WithAllowPrivateNetwork...op.OutboundTargetネットワーク到達性: 指定した取得・配送が、プライベートネットワーク(RFC 1918、loopback、link-local、ULA)に届くことを許容するすべて拒否
WithAllowInsecureOutboundForDev...op.OutboundTargetdev / CI fixture 用に plain-HTTP の loopback 宛先を許容する拒否
WithJWKSHTTPTransporthttp.RoundTripperJAR と private_key_jwt が使う RP 管理 JWKS 取得の transport を差し替えるシステム trust の transport
WithBackchannelLogoutop.BackchannelLogout(構造体: Transport / Timeout / FanOutBudget)Back-Channel ログアウトの配送設定transport は既定、5 秒、30 秒
  • WithMTLSRootCAs:WithMTLSProxy の後ろで tls_client_auth のクライアントを認証するなら必須。feature.MTLS なしで指定すると op.New がエラーを返す
  • WithMTLSProxy:TrustedProxies から来た request の forwarded certificate が正本。TrustedProxies が空なら WithTrustedProxies の CIDR を使い、両方が空なら op.New が失敗する。feature.MTLS なしで指定すると op.New がエラーを返す。(*op.Provider).MTLSProxy() が実効値を読み戻す
  • WithTrustedProxies:未設定の間はこれらのヘッダを無視し、最初に届いたリクエストで警告を 1 回出力する(WithLogger 未設定なら slog.Default() へ)
  • WithAllowLocalhostRedirectURIs:リテラル 127.0.0.1 / [::1] は厳格既定のまま。本番でも使える
  • WithAllowPrivateNetwork:target は op.OutboundJWKS(client JWKS)、op.OutboundJAR(request_uri)、op.OutboundSector(dynamic registration 時の sector_identifier_uri)、op.OutboundClientIDMetadata(Client ID Metadata Document の client_id URL。http スキームも許容。機能と同じく Experimental)、op.OutboundBackchannel(backchannel_logout_uri への配送)、op.OutboundSharedSignals(Shared Signals の push エンドポイント。クラウドメタデータのアドレスは引き続き拒否する。詳細は Shared Signals)。繰り返し呼ぶと積み上がる。引数なしや未知の値は op.New が失敗する
  • WithAllowInsecureOutboundForDev:受け付ける target は op.OutboundBackchannel(backchannel_logout_uri と配送)と op.OutboundSharedSignals(http:// の push エンドポイント)で、それ以外は op.New が失敗する。issuer が開発用ホスト(loopback の IP リテラル、localhost、RFC 6761 の .localhost / .test / .invalid / .example 配下の名前)でない場合、op.New は拒否する
  • WithJWKSHTTPTransport:接続時の SSRF 判定は維持される
  • WithBackchannelLogout:Transport が一斉通知のリクエストを運び、Timeout は RP ごとのリクエストを、FanOutBudget は RP ごとの timeout とは独立に 1 event 全体を制限する。ゼロ値のフィールドは既定値になる

WithAllowPrivateNetwork は、プライベートネットワーク上(オンプレミス、サービスメッシュ、社内 RP など)の RP に届くためのネットワーク到達性の設定です。本番でも正当に使え、各 target が広げるのは名前を挙げた取得処理だけです。有効にした target ごとに、op.New は広げる対象を示す 1 行を出します。通常は INFO で、オープンな動的クライアント登録か Client ID Metadata Documents も有効な場合は WARN です。WARN になるのは、JWKS、JAR、sector、Client ID Metadata、Back-Channel ログアウトの各 target で、対象の URL を RP が決めるためです。認証されていない呼び出し元が取得や配送の先を内部サービスへ向けられる(SSRF の露出)ことになります。Shared Signals の target は常に INFO です。

target が無効のまま取得や配送が拒否されると、拒否の内容に解除するオプション名が入ります(; pass op.WithAllowPrivateNetwork(op.OutboundJWKS) to admit private-network targets)。RP の JWKS、request_uri、Client ID Metadata Document の取得では、WithLogger に WARN を 1 行(outbound fetch refused by the private-network deny-list)出します。同じ URL については negative cache の有効期間に 1 回までです。sector_identifier_uri は独自の警告ログに、Back-Channel ログアウトと Shared Signals は失敗時の監査レコードに同じ内容を載せます。RP への応答は変わりません。cloud metadata のアドレスはどのオプションでも拒否され、オプション名は入りません。

観測 ​

Option値セクション既定
WithLogger*slog.Logger構造化された運用ログ(handler は redaction ミドルウェアでラップされる)構築時の診断は slog.Default()、リクエスト時の記録は破棄
WithAuditLogger*slog.LoggerOIDC domain business event 専用の監査 sink。HTTP access log ではないWithLogger を継承
WithPrometheus*prometheus.Registry選定した OP counter を呼び出し側 registry に登録(/metrics route、HTTP lifecycle metric、health endpoint は mount しない)なし

運用方針 ​

Option値セクション既定
WithSessionDurabilityPostureop.SessionDurabilityPostureBack-Channel Logout の監査ログに方針を注釈付け(SOC 用途)。実行時の制御は変えないセッションストアから導出
WithSharedSignals(引数なし)OP を Shared Signals Framework 1.0 の transmitter にする無効
WithClockop.Clocktoken の有効期限、監査レコードの timestamp、レート制限 window に使う時刻ソース(テスト用に注入)time.Now
  • WithSessionDurabilityPosture:たとえば AOF 永続化を有効にした Redis のように、導出される値を上書きしたいときに宣言する。SessionDurabilityDurable を宣言したのに、セッションストアが永続でないと報告する場合は、op.New が警告を 1 回出す。既定:store.SessionDurabilityReporter を実装し Durable() が true を返せば durable(SQL と DynamoDB のアダプタが該当)、そうでなければ volatile。
  • WithSharedSignals:受信側は OAuth クライアントで、ssf.read か ssf.manage スコープの client_credentials トークンを取得し、ストリームを設定して、CAEP / RISC のイベントを push または poll で受け取る。store.SharedSignalsStore を実装するストア、store.GrantClientLister を実装する Grants()、WithCookieKeys が必要。ssf. で始まるスコープ名は予約済み。push ワーカーは op.New から Provider.Shutdown まで動く。詳細は Shared Signals

op.New が拒否する構成 ​

必須オプションの欠落以外にも、次の組み合わせは「受け取って無視する」のではなく、op.New が設定エラーとして返します。

構成拒否する理由
store.Store が返す substore が typed-nil(nil ポインタを持つ interface)単純な nil 判定を通り抜け、初回利用時に panic する
WithLoginFlow の 2 回指定1 つのプロバイダにログインの仕組みは 1 つだけ
すでに確定した subject を前提とする LoginFlow.Primaryprimary の step が動く時点では subject がまだ決まっていない
consent / chooser という名前の WithInteractions 要素組み込み画面の名前として予約済み
単一値のオプションの 2 回指定、または同じ設定を決める 2 つのオプション(オプションの合成を参照)後の呼び出しが前の設定を黙って置き換えてしまう
WithUI に nil を渡す。Template のないページに ContentSecurityPolicy を指定した HTMLUI。LoginMount が空、または / で始まらない SPAUI、あるいはアクセスできるディレクトリではない StaticDir。Driver が nil の DriverUI、または Inner が nil の interaction.TemplateOverlayDriver。interaction.NormalizeCSP が拒否する ContentSecurityPolicy描画できないモード、または OP が送れないポリシー
WithGrants に grant.AuthorizationCode がないのに WithUI を設定(WithDefaults の外)WithUI が描画する prompt は authorization code フローのもの。op.New は op.ErrAuthorizationCodeGrantRequired を返す
2 回目の WithLogoutUI、nil の ConfirmTemplate または SignedOutTemplate、interaction.NormalizeCSP が拒否する ContentSecurityPolicy、Fields の全要素を出力しない確認テンプレートリクエスト時に失敗するログアウト画面や、OP が送れないポリシーになる
2 回目の WithIDTokenScopeClaims、引数なし、空の名前・openid・offline_access・未登録の名前、ID Token が予約している claim を Claims に含む custom scopeclaim を開放しない scope や、OP が自分で署名する claim と衝突する scope になる
PreviousSecret と PreviousSecretHash を両方持つ、または PreviousSecretExpiresAt のない ConfidentialClient のシード。WithHighEntropyClientSecrets のもとでの平文の PreviousSecret(Argon2id でハッシュされる)や Argon2id の PreviousSecretHash決して受理されない旧シークレットや、high-entropy の検証器が読めないハッシュになる
組み込み HTML ドライバ上の PrimaryPasskey ステップ(TemplateOverlayDriver を値・ポインタのどちらで渡した場合も含む)ドライバが script を出力しないため、WebAuthn の ceremony を完了できるユーザがいない。SPAUI か、ceremony を実行するドライバを持つ DriverUI を使う
既定のポリシーまたは op.ACRLevels が解決できない WithACRValuesSupported の値、空のキー・AAL1〜AAL3 以外の値・誤ったレベルの標準 URI キーを持つ op.ACRLevelsOP が報告できない acr を広告してしまう
負の CIBAGrant.DefaultRequestTTL / CIBAGrant.PollInterval、profile.FAPICIBA で 10 分を超える CIBA の既定・最大有効期限許容範囲外
secret のない ConfidentialClient シード、jwks と jwks_uri を両方持つクライアントレコードRFC 7591 §2 が両者の併用を禁じており、空の secret ハッシュは空の client_secret を受理してしまう
必要な grant が有効でない WithProfileエラーに、その grant を有効にするオプション名が出る
profile.OIDCCore を他のプロファイルと併せて宣言プロファイル要件が明示的にないことを表すので、他と組み合わせると矛盾するか意味を成さない
WithUserStore も、ログインフローの op.PrimaryPassword の store もないのに、有効な grant がエンドユーザを解決しうる(client_credentials 以外のすべて)エンドユーザ記録の供給元がない。WithStore のバックエンドがユーザの参照元になることはない

StepEmailOTP も、Store・Sender・Users が nil または typed-nil なら op.New を失敗させます。どれも最初のリクエストまで待たずに失敗します。

起動時の診断 ​

受理はされるものの、意図した構成とは考えにくいものがあります。op.New は、そのような構成ごとに警告を構築時に 1 回、WithLogger で渡した logger(未指定なら slog.Default())へ出します。

構成警告の内容
WithLogger も WithAuditLogger も未指定リクエスト処理中の運用ログと監査レコードが破棄される
WithStaticClients のエントリが、OP の有効にしていない grant_types を挙げている。GrantTypes を空にしたシードは authorization_code と refresh_token を受け取るため、どちらかが有効でなければ警告されるその grant のトークンリクエストは unsupported_grant_type で拒否される。メッセージには有効にするオプション名が出る
feature.PKCE を渡した効果がない。上の PKCE の行を参照
WithTrustedProxies 未指定で X-Forwarded-* つきのリクエストが届いたヘッダは無視される
WithAllowPrivateNetworktarget ごとに、広げる対象を示す 1 行。INFO だが、オープンな動的クライアント登録か Client ID Metadata Documents も有効な場合、JWKS、JAR、sector、Client ID Metadata、Back-Channel ログアウトの各 target は WARN(SSRF の露出)になる。mTLS / プロキシ / ネットワークを参照

WithKeyset の有効な鍵が署名アルゴリズムに合わない場合は、警告ではなくエラーです。2048 ビット以上の RSA 鍵を既定の ES256 のまま渡すと op.New が失敗し、メッセージは to sign with this key, add WithSigningAlgorithm(op.AlgRS256) で終わります。

ここでは設定しないもの ​

意図的にオプションにしていない項目です。理由は各リンク先の設計判断を参照してください。

  • JOSE 検証用の許可リスト — client assertion、JAR request object、DPoP proof など入力側の署名検証では RS256 / PS256 / ES256 / EdDSA の固定集合を使います。本ライブラリが発行する JWT の署名は ES256 のみです。どちらの面も広げるフラグはありません。セキュリティ方針 §2 を参照。
  • PKCE method — S256 のみ。plain は構造的に拒否されます。
  • Cookie scheme — __Host- プリフィックス、AES-256-GCM、double-submit CSRF が常に有効です。必須オプション § WithCookieKeys を参照。
  • 乱数源 — crypto/rand のみ。math/rand は lint で禁止しています。
  • /metrics の公開 — ライブラリではなくルータ側の責務です。ユースケース: Prometheus メトリクス を参照。

このリストの裏取り ​

カタログはライブラリ本体のソースから取っています。自分で監査するには:

sh
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
grep -hE '^func With[A-Z].*\) Option \{' $(ls op/*.go | grep -v _test.go) | sort -u

このパターンは op.Option を返す関数だけを拾うので、op.New が受け取るオプションが並びます。WithInMemoryDPoPNonceLogger は op.NewInMemoryDPoPNonceSource 用のヘルパーで、op.New のオプションではありません。

関数名と受け取る型のシグネチャが正典であり、各関数の godoc コメントが契約の正本です。