Skip to content

Start here ​

The documentation is organised by topic, and the topics are many. This page goes the other way: find what you want to build, then open the page that explains it and the example that runs it.

Each example is a self-contained program in the examples/ directory of the source repository. Examples build behind the example build tag, so run one from its own directory:

sh
cd examples/01-minimal && GOWORK=off go run -tags example .

New to the library? Do the first row, then come back for the row that matches your deployment.

From a goal to a page ​

I want to...ReadRun
Decide which client types, profile and options my deployment needsChoose a configurationthe example named in the row you pick
Get the smallest OP runningMinimal OP, Minimal OP and RP pair01-minimal
Use my existing users table and databaseIntegrate with an existing database, Bring your own user store, Persistent storage (SQL)24-byo-userstore, 53-production-sql
Build my login screens as a SPASPA / custom interaction. Option: WithUI(op.SPAUI{...})10-react-login, 17-spa-composite-store
Let my SPA be the relying party that signs users inCORS for SPA. Options: op.PublicClient in WithStaticClients, WithCORSOrigins14-cors-spa
Sign users in to my own web app without a consent screen (first-party web login)First-party consent skip. Options: WithFirstPartyClients, plus WithStaticClients for the same client IDs; not combinable with a FAPI 2.0 profile40-first-party-skip-consent
Issue tokens to a backend service (machine-to-machine)client_credentials. Options: WithGrants(grant.ClientCredentials) (WithGrants replaces the default grant set, so an app that also has browser login lists all its grants: grant.AuthorizationCode, grant.RefreshToken, grant.ClientCredentials), WithStaticClients with a confidential client, WithScope, and WithHighEntropyClientSecrets for generated secrets05-client-credentials
Run a FAPI 2.0 APIFAPI 2.0 Baseline, and FAPI 2.0 Message Signing for signed requests and responses. Options: WithProfile(profile.FAPI2Baseline), WithStaticClients. The profile enables DPoP for you; add WithFeature(feature.MTLS) to use mTLS instead03-fapi2, 50-fapi-tls-jwks
Accept MCP-style public clients that identify themselves by URLMCP authorization server. Options: WithClientIDMetadataDocuments, WithProtectedResourcesnone
Require a second factor or step-upMFA / step-up20-mfa-totp, 23-step-up, 28-email-otp-recovery
Let users sign in with a passkey instead of a passwordPasswordless passkey. Options: WithLoginFlow with PrimaryPasskey and WithUI(op.SPAUI{...}) (the built-in HTML pages cannot run the WebAuthn ceremony), plus WithUserStore when the flow has no PrimaryPassword29-passkey
Protect my API with the OP's tokensProtect an API36-resource-server
Mount the OP under an existing routerMount on your router36-resource-server
Run it in productionGo-live checklist, Key rotation, Storage maintenance, Client onboarding53-production-sql
Move users with bcrypt hashes over without a resetMigrating bcrypt passwords53-production-sql

Example 53 appears in several rows because it is the one program that wires the production pieces together: signing and cookie keys read from files, a SQL schema checked at startup, a reloadable handler driven by SIGHUP, a retention sweep, an existing users table with bcrypt hashes, a command that synchronises static clients, and graceful shutdown. It defaults to SQLite so it runs without a database server. A real deployment switches to MySQL or PostgreSQL by opening that database's driver and passing the matching dialect to the SQL store.

If your goal is not in the table ​

  • Use cases lists every example and the page that goes with it, grouped by topic.
  • Concepts explains OAuth and OIDC from the three roles up, for the options you are about to set.
  • Required options names what op.New refuses to start without.
  • Reference is the option-by-option listing.