████████╗██╗ ██╗███████╗ █████╗ ██╗ ██╗████████╗██╗ ██╗ ██████╗ ██████╗
╚══██╔══╝██║ ██║██╔════╝██╔══██╗██║ ██║╚══██╔══╝██║ ██║ ██╔════╝ ██╔═══██╗
██║ ███████║█████╗ ███████║██║ ██║ ██║ ███████║ ██║ ███╗██║ ██║
██║ ██╔══██║██╔══╝ ██╔══██║██║ ██║ ██║ ██╔══██║ ██║ ██║██║ ██║
██║ ██║ ██║███████╗██║ ██║╚██████╔╝ ██║ ██║ ██║ ╚██████╔╝╚██████╔╝
╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝
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
- FAQ
- 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 |
| ROADMAP.md | In-flight work and known gaps |
| 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 [email protected] or use GitHub Security Advisories.
See SECURITY.md for supported versions, disclosure policy, scope, and SLA targets.
- Minimum length: 12 characters, enforced at the library level
(
internal/password.MinPasswordLength, NIST 2024 baseline). Signup and password-change requests below this length returnweak_password. - Hashing: Argon2id, using the parameter defaults from
golang.org/x/crypto/argon2. - Anti-enumeration: a fixed-cost dummy Argon2id verify runs on user-not-found, so login timing doesn't reveal whether an email is registered.
- The 12-character minimum is currently fixed at the package level; there
is no
Configfield to override it yet.
Is this production ready? Yes for v1.0+ surfaces (session auth, OAuth providers, RBAC, audit log), covered by STABILITY.md's SemVer contract. v2.0's OAuth 2.1 authorization server and agent-identity primitives are feature complete as of v2.0.0. Check CHANGELOG.md for the current release.
How does it compare to Auth0, better-auth, or Ory Hydra? See the comparison table above. The short version: theauth-go is self-hosted like better-auth/Hydra but also ships MCP authorization and FAPI 2.0-adjacent features (PAR+JAR+DPoP) that none of the alternatives have.
Does it support AI agent / MCP use cases specifically? Yes, this is one of the two things that differentiate it from every other Go auth library. See the MCP resource server section, and the agent-identity and delegation-chain docs.
What databases are supported?
Postgres and MySQL, plus an in-memory backend for tests. The Storage
interface is public, so custom backends are possible.
Is it free and open source? Yes, MIT licensed, no paid tier gating any feature in this repository.
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