Skip to content

go-oidc-provider

OpenID Connect Provider you mount on any Go http.Handler.

Works with net/http, chi, gin, or any router. PAR · JAR · DPoP · mTLS · PKCE built in. Targets FAPI 2.0 Baseline & Message Signing.

FAPI 2.0 BASELINE · OFCS 138 / 0 · APACHE-2.0 · GO ≥ 1.21

Standard use cases

Five things people most often build with this library. Click through to a working example.

1. Stand up the smallest possible 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() {
  handler, err := op.New(
    op.WithIssuer("https://op.example.com"),
    op.WithStore(inmem.New()),
    op.WithKeyset(myKeyset),    // see Quick Start: ephemeral key generation
    op.WithCookieKey(cookieKey), // 32 bytes — AES-256-GCM
  )
  if err != nil {
    log.Fatal(err)
  }
  log.Fatal(http.ListenAndServe(":8080", handler))
}

See examples/01-minimal and Quick Start.

2. Run a FAPI 2.0 Baseline OP

go
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(inmem.New()),
  op.WithKeyset(myKeyset),
  op.WithCookieKey(cookieKey),
  op.WithProfile(profile.FAPI2Baseline), // PAR + JAR + DPoP, ES256, alg lock
  op.WithStaticClients(/* private_key_jwt client with JWKS */),
)

Why one switch is enough

op.WithProfile(profile.FAPI2Baseline) activates the required features (PAR, JAR, DPoP), intersects token_endpoint_auth_methods_supported with the FAPI allow-list, and tightens the discovery surface. See Use case: FAPI 2.0 Baseline.

3. Issue tokens to backend services (no end user)

go
handler, _ := op.New(
  op.WithIssuer("https://op.example.com"),
  op.WithStore(inmem.New()),
  op.WithKeyset(myKeyset),
  op.WithCookieKey(cookieKey),
  op.WithGrants(grant.ClientCredentials, grant.AuthorizationCode, grant.RefreshToken),
)

See examples/05-client-credentials and Use case: client_credentials.

go
handler, _ := op.New(
  /* required options */
  op.WithSPAUI(op.SPAUI{ /* SPA endpoints */ }),
  op.WithCORSOrigins("https://app.example.com"),
)

See examples/10-react-login and Use case: SPA.

5. Persist on a real database, split hot from cold

go
import (
  "context"

  "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),
)

handler, _ := op.New(
  op.WithStore(combined),
  /* … */
)

See examples/09-redis-volatile and Use case: hot/cold split.


Install

sh
go get github.com/libraz/go-oidc-provider/op@latest

Pre-v1.0

The library is pre-v1.0; minor releases may carry breaking changes. The public API stabilises at v1.0.0. See the pre-v1.0 note in the README.

Apache-2.0. Source: libraz/go-oidc-provider. Vulnerability disclosure: SECURITY.md.