████████╗██╗ ██╗███████╗ █████╗ ██╗ ██╗████████╗██╗ ██╗ ██████╗ ██████╗
╚══██╔══╝██║ ██║██╔════╝██╔══██╗██║ ██║╚══██╔══╝██║ ██║ ██╔════╝ ██╔═══██╗
██║ ███████║█████╗ ███████║██║ ██║ ██║ ███████║ ██║ ███╗██║ ██║
██║ ██╔══██║██╔══╝ ██╔══██║██║ ██║ ██║ ██╔══██║ ██║ ██║██║ ██║
██║ ██║ ██║███████╗██║ ██║╚██████╔╝ ██║ ██║ ██║ ╚██████╔╝╚██████╔╝
╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝
OAuth 2.1 + MCP authorization for Go. Type-safe, dependency-light, FAPI-adjacent.
go get github.com/glincker/theauth-goa, _ := theauth.New(theauth.Config{
Storage: memory.New(),
BaseURL: "http://localhost:8080",
})
r := chi.NewRouter()
a.Mount(r) // /auth/* magic-link, email-password, OAuth, passkeys, TOTP, SAML
r.With(a.RequireAuth()).Get("/me", func(w http.ResponseWriter, r *http.Request) {
user, _ := theauth.UserFromContext(r.Context())
w.Write([]byte("hello " + user.Email))
})
http.ListenAndServe(":8080", r)- Why theauth-go
- Features at a glance
- Quick start
- MCP resource server
- Documentation
- Examples
- Storage backends
- Security
- Contributing
- License
| theauth-go | Auth0 | better-auth | Goth | Hydra | |
|---|---|---|---|---|---|
| License | MIT | Proprietary | MIT | MIT | Apache 2.0 |
| Self-hosted | Yes | No | Yes | Yes | Yes |
| MCP authorization | Yes | No | No | No | No |
| FAPI 2.0 adjacent (PAR+JAR+DPoP) | Yes | Partial | No | No | Partial |
| DPoP-bound tokens | Yes | No | No | No | No |
| SBOM + Sigstore signed | Yes | No | No | No | No |
| Pluggable storage | Yes | No | Partial | No | Yes |
| Go-native, single import | Yes | No | No | Yes | No |
theauth-go is the first Go auth library where OAuth 2.1, MCP authorization, agent identities, and revocable delegation chains ship in a single go get. It drops into a chi or net/http server in under twenty lines.
Expand full feature list
- Authorization code + PKCE S256 (mandatory)
- Refresh token with rotation + family revocation on replay
client_credentialsfor service accounts and agents- RFC 8693 token exchange: scope narrowing, duration tightening, actor chain capped at 3
- JWT bearer (RFC 7523)
- CIBA: RFC 9509 backchannel authentication (Poll + Ping modes)
- DPoP-bound access tokens (RFC 9449)
- PAR: Pushed Authorization Requests (RFC 9126)
- JAR: JWT-Secured Authorization Requests (RFC 9101)
- CIMD per MCP spec 2025-11-25
/.well-known/oauth-protected-resource(RFC 9728)mcpresourceSDK: zero-dependency module for MCP resource servers- Actor-chain walking via AS introspection
- 401 with
WWW-Authenticate: Bearerper RFC 6750 on failure
- Magic link sign-in
- Email + password with Argon2id (OWASP 2026 defaults, 12-char minimum)
- 12 OAuth providers: GitHub, Google, Microsoft, Discord, Facebook, Slack, GitLab, Bitbucket, Twitch, LinkedIn, X/Twitter, Apple
- WebAuthn passkeys: discoverable login, sign-count replay protection, NIST SP 800-63B single-factor-strong
- TOTP second factor with 10 single-use recovery codes and
pending_2fastep-up state machine - SAML 2.0 Service Provider (per-organization IdP binding, signed assertions only)
- SCIM 2.0: Users and Groups CRUD, RFC 7644 PATCH, per-org isolation
- RBAC with closed permission catalog, seeded roles,
RequirePermissionmiddleware - Organization multi-tenancy with
active_organization_idsession scope - Audit logging: append-only, async, keyset pagination, pluggable SIEM sinks
- storage/memory: zero dependencies, for development and tests
- storage/postgres: production default,
pgx/v5+sqlc - storage/mysql: MySQL 8.x alternative
- storagetest: public contract test suite for custom backends
- 10 OpenTelemetry spans across hot paths
- 10 Prometheus metrics (requests, errors, token issuances, latency histograms)
- Pluggable adapters: bring your own OTel exporter or Prometheus registry
- FAPI 2.0-adjacent: PAR + JAR + JWT-Bearer + DPoP
- Ed25519 JWT signing with 30-day JWKS rotation
- RFC 8707 audience binding (mandatory)
- RFC 9700 refresh-token rotation with replay detection
- RFC 7591 dynamic client registration with bearer-gated initial access tokens
- Per-IP and per-email rate limiting on every credential endpoint
HttpOnly,Secure,SameSite=Laxcookies; only SHA-256 hash persisted
- SBOM generated on every release
- Sigstore keyless signing via
cosign - SLSA-3 provenance attestation
- Verify with:
cosign verify-blob --certificate-identity-regexp=".*" --certificate-oidc-issuer="https://token.actions.githubusercontent.com" <artifact>
Requirements: Go 1.25+
go get github.com/glincker/theauth-goStep 1 -- Create an auth instance with in-memory storage:
import (
"github.com/glincker/theauth-go"
"github.com/glincker/theauth-go/storage/memory"
)
a, err := theauth.New(theauth.Config{
Storage: memory.New(),
BaseURL: "http://localhost:8080", // used in magic-link emails
})Step 2 -- Mount routes and protect your API:
import "github.com/go-chi/chi/v5"
r := chi.NewRouter()
a.Mount(r) // wires /auth/* (magic-link, email-password, OAuth, passkeys, TOTP, SAML, MCP)
r.With(a.RequireAuth()).Get("/dashboard", func(w http.ResponseWriter, r *http.Request) {
user, _ := theauth.UserFromContext(r.Context())
fmt.Fprintf(w, "Welcome %s", user.Email)
})Step 3 -- Switch to Postgres for production:
import (
"github.com/jackc/pgx/v5/pgxpool"
"github.com/glincker/theauth-go/storage/postgres"
)
pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
a, _ := theauth.New(theauth.Config{
Storage: postgres.New(pool), // automatic schema migration on first run
BaseURL: "https://myapp.com",
})Full runnable example: examples/chi-app/
The mcpresource module is a zero-dependency Go module for MCP resource servers. It does not pull in theauth core or any storage adapter.
go get github.com/glincker/theauth-go/mcpresourcev := mcpresource.New(
"https://mcp.example.com",
mcpresource.WithJWKS("https://as.example.com/oauth/jwks"),
mcpresource.WithIntrospection(
"https://as.example.com/oauth/introspect",
"mcp-client-id", "mcp-client-secret",
),
)
r := chi.NewRouter()
r.Use(v.Middleware) // JWT validation, audience check, actor-chain walk, revocation
r.Get("/tools/run", func(w http.ResponseWriter, r *http.Request) {
p, _ := v.Principal(r.Context())
// p.Subject (user), p.Actor (final agent), p.ActorChain (delegation path)
})Full runnable example: examples/mcp-server/
| Getting Started | Installation, quick start, choosing a storage backend |
| Concepts | OAuth 2.1, MCP, PAR/JAR, JWT-Bearer, CIBA, DPoP |
| Guides | Add an OAuth provider, enable passkeys, OTel tracing, SIEM audit streaming |
| Reference | Config, Storage, Errors, Metrics, Spans |
| Security | Threat model, SOC 2 mapping, GDPR data handling |
| Migrations | Version upgrade guides |
| Releases and verification | cosign verify-blob command for SBOM and signed artifacts |
In-repo references:
| Document | Description |
|---|---|
| AGENTS.md | Concise reference for AI coding assistants: patterns, anti-patterns, file map |
| STABILITY.md | Public API surface, SemVer rules, Storage interface special rules |
| CHANGELOG.md | Per-release notable changes following Keep a Changelog |
| SECURITY.md | Vulnerability disclosure policy and contact |
| CONTRIBUTING.md | Dev setup, test commands, commit convention, PR process |
| MIGRATION.md | Step-by-step upgrade guides between major versions |
| Example | What it shows |
|---|---|
examples/chi-app/ |
Magic links and email/password with chi |
examples/echo-app/ |
Drop-in with Echo |
examples/gin-app/ |
Drop-in with Gin |
examples/stdlib-app/ |
Pure net/http, no framework |
examples/mcp-server/ |
MCP resource server using mcpresource middleware |
examples/oauth-multi-provider/ |
GitHub + Google + Microsoft + Discord in one app |
examples/observability-otel/ |
OTel tracing and span export |
examples/observability-prom/ |
Prometheus metrics scrape |
examples/webauthn-passkey/ |
Passkey register and discoverable login |
examples/totp-stepup/ |
Password + TOTP step-up flow |
examples/oauth-apple/ |
Sign in with Apple (JWT client secret) |
examples/oauth-gitlab/ |
Sign in with GitLab (self-hosted or gitlab.com) |
Each example includes a README, main.go, go.mod, docker-compose.yml, .env.example, and Makefile.
| Backend | Path | Use case |
|---|---|---|
| Memory | storage/memory | Development, unit tests, zero deps |
| Postgres | storage/postgres | Production default, pgx/v5 + sqlc |
| MySQL | storage/mysql | MySQL 8.x alternative |
| Contract suite | storagetest | Verify your own custom backend |
Bring your own storage backend by implementing the Storage interface and running the storagetest contract suite against it.
Please do not open a public GitHub issue for security vulnerabilities.
Report to security@glincker.com or use GitHub Security Advisories.
See SECURITY.md for supported versions, disclosure policy, scope, and SLA targets.
See CONTRIBUTING.md for dev setup, test commands, commit convention, and PR process.
Short version:
git clone https://github.com/glincker/theauth-go.git
cd theauth-go
go test -race ./...
go vet ./...Open an issue first for anything beyond a typo or one-file fix.
Built by the founder of theSVG.org.
A Product of GLINR STUDIOS | A GLINCKER COMPANY