Skip to content

go-oidc-provider

Go の http.Handler に組み込める OpenID Connect Provider。

net/http、chi、gin など任意のルーターで動作。PAR · JAR · DPoP · mTLS · PKCE を内蔵。FAPI 2.0 Baseline / Message Signing に対応。

FAPI 2.0 BASELINE · OFCS 210 PASSED / 全 271 モジュール · 9 プラン · APACHE-2.0 · GO ≥ 1.25

go-oidc-provider は既存の Go アプリに http.Handler として組み込み、OP エンドポイント、ストア、ログ、鍵をアプリ側の運用基盤に接続する。既存 Go アプリrouter / middlewareOIDC Providerhttp.Handler/oidc/auth /oidc/token/oidc/jwksStoreKeysetログ / 監査マウント

代表的な使い方

本ライブラリでよく作る構成を 5 つ挙げます。いずれもリポジトリに動作する実例があります。

1. 最小構成の OP を立ち上げる

go
package main

import (
  "log"
  "net/http"

  "github.com/libraz/go-oidc-provider/op"
  "github.com/libraz/go-oidc-provider/op/storeadapter/inmem"
)

func main() {
  st := inmem.New()
  handler, err := op.New(
    op.WithIssuer("https://op.example.com"),
    op.WithStore(st),
    op.WithKeyset(myKeyset),     // クイックスタート: 揮発鍵の生成例あり
    op.WithCookieKeys(cookieKey), // 32 バイト — AES-256-GCM
    op.WithLoginFlow(op.LoginFlow{
      Primary: op.PrimaryPassword{Store: st.UserPasswords()},
    }),
  )
  if err != nil {
    log.Fatal(err)
  }
  log.Fatal(http.ListenAndServe(":8080", handler))
}

examples/01-minimalクイックスタート を参照。

2. FAPI 2.0 Baseline 対応の OP を動かす

go
st := inmem.New()
clientJWKS, _ := op.LoadPublicJWKS("conformance/keys/fapi-client.jwks.json")
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(st),
  op.WithKeyset(myKeyset),
  op.WithCookieKeys(cookieKey),
  op.WithLoginFlow(op.LoginFlow{
    Primary: op.PrimaryPassword{Store: st.UserPasswords()},
  }),
  op.WithProfile(profile.FAPI2Baseline), // PAR + JAR、DPoP 既定、ES256、FAPI 絞り込み
  op.WithStaticClients(op.PrivateKeyJWTClient{
    ID: "demo-fapi",
    JWKS: clientJWKS,
    RedirectURIs: []string{"https://app.example.com/callback"},
    Scopes: []string{"openid", "profile"},
  }),
)

プロファイル 1 行で済む理由

op.WithProfile(profile.FAPI2Baseline) は、プロファイルが必須とする機能(PARJAR)を有効化し、token_endpoint_auth_methods_supported を FAPI 許可リストに絞り込みます。mTLS を明示していない場合は DPoP を既定で選び、discovery 文書もそれに合わせて調整します。詳細は 使い方: FAPI 2.0 Baseline を参照してください。

3. バックエンド向けトークンを発行する(エンドユーザなし)

go
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(inmem.New()),
  op.WithKeyset(myKeyset),
  op.WithGrants(grant.ClientCredentials),
  op.WithStaticClients(op.ConfidentialClient{
    ID: "backend-service",
    Secret: "cc-demo-secret-rotate-me",
    AuthMethod: op.AuthClientSecretBasic,
    GrantTypes: []string{"client_credentials"},
    Scopes: []string{"api:read"},
  }),
  op.WithScope(op.PublicScope("api:read", "API リソースの読み取り")),
)

examples/05-client-credentials使い方: client_credentials を参照。

4. ログイン・同意・ログアウトを SPA から扱う

go
st := inmem.New()
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(st),
  op.WithKeyset(myKeyset),
  op.WithCookieKeys(cookieKey),
  op.WithLoginFlow(op.LoginFlow{
    Primary: op.PrimaryPassword{Store: st.UserPasswords()},
  }),
  op.WithSPAUI(op.SPAUI{
    LoginMount: "/login",
    StaticDir:  "../internal/webui/static",
  }),
)

UI オプション

op.WithSPAUI / op.WithConsentUI / op.WithChooserUI は、OP 側で SPA の入口を公開する構成、独自の同意テンプレート、独自のアカウント選択テンプレートを扱うためのオプションです。SPA の配信を自前のルータで行いたい場合は interaction.JSONDriver も使えます。詳細は examples/10-react-login使い方: SPA を参照してください。

5. 永続ストアと揮発ストアを分離する

go
import (
  "context"

  "github.com/libraz/go-oidc-provider/op"
  "github.com/libraz/go-oidc-provider/op/storeadapter/composite"
  oidcredis "github.com/libraz/go-oidc-provider/op/storeadapter/redis"
  oidcsql "github.com/libraz/go-oidc-provider/op/storeadapter/sql"
)

durable, _  := oidcsql.New(db, oidcsql.MySQL())
volatile, _ := oidcredis.New(context.Background(),
  oidcredis.WithDSN("rediss://redis:6380/0"),
  oidcredis.WithRedisAuth(redisUser, redisPassword),
)
combined, _ := composite.New(
  composite.WithDefault(durable),
  composite.With(composite.Sessions, volatile),
  composite.With(composite.Interactions, volatile),
  composite.With(composite.ConsumedJTIs, volatile),
)

loginFlow := op.LoginFlow{Primary: op.PrimaryPassword{Store: durable.UserPasswords()}}
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(combined),
  op.WithKeyset(myKeyset),
  op.WithCookieKeys(cookieKey),
  op.WithLoginFlow(loginFlow),
)

examples/09-redis-volatile使い方: Hot / Cold 分離 を参照。


インストール

sh
go get github.com/libraz/go-oidc-provider/[email protected]

安定 API

op.New と同梱ストレージアダプタだけで構成した場合は、通常そのまま更新できます。独自のストアやその他の拡張を組み込んでいる場合は、更新前に CHANGELOG.md の移行案内を確認してください。godoc が Experimental: で始まる symbol は通常のマイナーリリース例外で、変更される可能性があります。

ライセンスと関連情報

Apache-2.0。ソースは libraz/go-oidc-provider。脆弱性報告は SECURITY.md を参照してください。