https://github.com/libraz/go-oidc-provider
Mount an OpenID Connect Provider on any Go http.Handler. Targets FAPI 2.0 Baseline / Message Signing. Pre-v1.0.
https://github.com/libraz/go-oidc-provider
authorization-server dpop fapi fapi2 golang library oauth2 oidc openid-connect
Last synced: 10 days ago
JSON representation
Mount an OpenID Connect Provider on any Go http.Handler. Targets FAPI 2.0 Baseline / Message Signing. Pre-v1.0.
- Host: GitHub
- URL: https://github.com/libraz/go-oidc-provider
- Owner: libraz
- License: apache-2.0
- Created: 2026-04-26T04:49:10.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-23T08:40:15.000Z (19 days ago)
- Last Synced: 2026-05-23T10:33:46.680Z (19 days ago)
- Topics: authorization-server, dpop, fapi, fapi2, golang, library, oauth2, oidc, openid-connect
- Language: Go
- Homepage: https://go-oidc-provider.libraz.net
- Size: 9.02 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Notice: NOTICE
Awesome Lists containing this project
README
# go-oidc-provider
[](https://github.com/libraz/go-oidc-provider/actions/workflows/ci.yml)
[](https://codecov.io/gh/libraz/go-oidc-provider)
[](https://github.com/libraz/go-oidc-provider/releases)
[](https://pkg.go.dev/github.com/libraz/go-oidc-provider/op)
[](https://goreportcard.com/report/github.com/libraz/go-oidc-provider)
[](LICENSE)
[](https://go-oidc-provider.libraz.net)
OpenID Connect Provider (Authorization Server) library for Go. `op.New(...)`
returns a standard `http.Handler` you mount on `net/http`, `chi`, `gin`, or any
router — no framework lock-in, no global state. Targets FAPI 2.0 Baseline /
Message Signing.
> 📘 **[Documentation site](https://go-oidc-provider.libraz.net)** — concepts,
> use cases, security posture, conformance scoreboard, and the full options
> reference live there. This README is the source-tree map and example
> inventory.
> **Status: pre-v1.0.** `v0.9.0` is the initial public release; the public API
> may change in any minor release until `v1.0.0`.
> [`CHANGELOG.md`](CHANGELOG.md) starts tracking notable changes from the
> release that follows `v0.9.0`.
## Install
```sh
go get github.com/libraz/go-oidc-provider/op@v0.9.0
```
Go 1.25+. Storage adapters are published as sub-modules so their
dependencies stay out of your `go.sum` until you opt in:
```sh
go get github.com/libraz/go-oidc-provider/op/storeadapter/sql@v0.9.0
go get github.com/libraz/go-oidc-provider/op/storeadapter/redis@v0.9.0
```
## Quickstart
`op.New` requires four options at minimum — `Issuer`, `Store`, `Keyset`, and a
32-byte `CookieKey`. The constructor returns an error rather than booting in an
unsafe configuration, so partial setups fail fast.
```go
handler, err := op.New(
op.WithIssuer("https://idp.example.com"),
op.WithStore(inmem.New()),
op.WithKeyset(op.Keyset{{KeyID: "k1", Signer: priv}}),
op.WithCookieKey(cookieKey), // 32 bytes, AES-256-GCM
)
if err != nil {
log.Fatal(err)
}
log.Fatal(http.ListenAndServe(":8080", handler))
```
End-to-end startup (key generation, store wiring, graceful shutdown) lives in
[`examples/01-minimal`](examples/01-minimal/main.go); see also
[Quick Start](https://go-oidc-provider.libraz.net/getting-started/install) and
[Required options](https://go-oidc-provider.libraz.net/getting-started/required-options).
### Local development
The defaults are tuned for production (https-only, public-network-only). When
you boot against `http://127.0.0.1` or a stub RP on the loopback interface, two
opt-ins keep the validators from rejecting the demo wiring:
```go
op.WithAllowLocalhostLoopback(), // admit textual "localhost" hosts
op.WithAllowInsecureBackchannelLogoutForDev(), // admit http://localhost backchannel_logout_uri
```
Both options are dev / CI-only — production embedders leave them off and front
their RPs over TLS. Every example under [`examples/`](examples) that binds a
loopback listener uses these options; an embedder porting one of the demos
into a production stack drops the lines.
### FAPI 2.0 Baseline in one switch
```go
op.WithProfile(profile.FAPI2Baseline) // PAR + JAR + DPoP, ES256, alg lock
```
The constructor refuses to start if the declared profile and the rest of the
options conflict. See
[Use case: FAPI 2.0 Baseline](https://go-oidc-provider.libraz.net/use-cases/fapi2-baseline).
## What this library is — and is not
- **Embeds as `http.Handler`**: framework-agnostic, mountable at any prefix.
- **BYO user model and storage**: small `store.*` substore interfaces; the
library never touches your `users` table directly.
- **Headless interaction driver**: drive login / consent / logout from a SPA
(React, Vue, Svelte, Angular, …) via `op.WithSPAUI`, or supply your own
templates with `op.WithConsentUI`.
- **Audit-first observability**: business events go through `audit.Emitter`
and `op.WithPrometheus(reg)` registers a curated counter set on your
registry. The library does **not** mount `/metrics`, install request-duration
middleware, or wrap your router — that's the embedder's job.
Out of scope on purpose: it is not an IdP (no user table, no password hashing,
no email delivery), not a generic OAuth2 framework (opinionated toward OIDC),
and not a UI kit (the default HTML driver exists so the OP boots without
configuration). Detail in
[Why this library](https://go-oidc-provider.libraz.net/why).
## Standards
OpenID Connect Core 1.0; OAuth 2.0 (RFC 6749) and the Security Best Current
Practices (RFC 9700); PKCE (RFC 7636), DPoP (RFC 9449), PAR (RFC 9126), JAR
(RFC 9101), JARM, mTLS (RFC 8705); FAPI 2.0 Baseline / Message Signing.
Each release is regressed against the OpenID Foundation conformance suite —
the live scoreboard is on the
[conformance results page](https://go-oidc-provider.libraz.net/compliance/ofcs).
A per-RFC matrix is at
[Compliance — RFC matrix](https://go-oidc-provider.libraz.net/compliance/rfc-matrix).
## Storage
Bring your own backend by implementing the substore interfaces in
[`op/store`](op/store). The repository ships:
| Adapter | Module path | Purpose |
|---|---|---|
| `inmem` | `op/storeadapter/inmem` | Reference / dev / test store. The contract harness in [`op/store/contract`](op/store/contract) runs against it. |
| `sql` | `op/storeadapter/sql` | `database/sql` adapter for SQLite, MySQL 8.0+, PostgreSQL 14+. **Sub-module.** Contract harness exercises every substore against a real engine via testcontainers (`go test -tags=testcontainers`). |
| `redis` | `op/storeadapter/redis` | Volatile substores (`InteractionStore`, `ConsumedJTIStore`). **Sub-module.** Refuses to start without TLS (`rediss://`) and AUTH unless `WithDevModeAllowPlaintext` is set explicitly. |
| `composite` | `op/storeadapter/composite` | Hot/cold splitter — durable substores to one backend, volatile to another, while enforcing the transactional-cluster invariant. |
DynamoDB is planned for v1.x as an additional sub-module. Background:
[Operations — multi-instance](https://go-oidc-provider.libraz.net/operations/multi-instance).
## Examples
Runnable demos live under [`examples/`](examples/README.md) — see that index
for the full goal-oriented table, the numeric topic bands, and the docker
stacks shipped with `07-mysql-store` and `09-redis-volatile`. Each row also
maps to a use-case page on the docs site under
[Use cases](https://go-oidc-provider.libraz.net/use-cases/).
```sh
go run -tags example ./examples/01-minimal
```
## Community
- [SECURITY.md](SECURITY.md) — vulnerability reporting policy and supported
versions.
- [CONTRIBUTING.md](CONTRIBUTING.md) — contribution mechanics, Conventional
Commits scopes, test layering expectations.
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — Contributor Covenant 2.1 and the
project's reporting channel.
## License
Apache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE). Third-party dependency
licenses are tracked in [`THIRD_PARTY.md`](THIRD_PARTY.md), regenerated from
`go.mod` by `make licenses`.