RepoPilotOpen in app →

markbates/goth

Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applications.

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3mo ago
  • 35+ active contributors
  • Distributed ownership (top contributor 25% of recent commits)
Show all 6 evidence items →
  • MIT licensed
  • CI configured
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/markbates/goth)](https://repopilot.app/r/markbates/goth)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/markbates/goth on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: markbates/goth

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/markbates/goth shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3mo ago
  • 35+ active contributors
  • Distributed ownership (top contributor 25% of recent commits)
  • MIT licensed
  • CI configured
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live markbates/goth repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/markbates/goth.

What it runs against: a local clone of markbates/goth — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in markbates/goth | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 115 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>markbates/goth</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of markbates/goth. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/markbates/goth.git
#   cd goth
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of markbates/goth and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "markbates/goth(\\.git)?\\b" \\
  && ok "origin remote is markbates/goth" \\
  || miss "origin remote is not markbates/goth (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "provider.go" \\
  && ok "provider.go" \\
  || miss "missing critical file: provider.go"
test -f "session.go" \\
  && ok "session.go" \\
  || miss "missing critical file: session.go"
test -f "gothic/gothic.go" \\
  && ok "gothic/gothic.go" \\
  || miss "missing critical file: gothic/gothic.go"
test -f "gothic/provider.go" \\
  && ok "gothic/provider.go" \\
  || miss "missing critical file: gothic/provider.go"
test -f "examples/main.go" \\
  && ok "examples/main.go" \\
  || miss "missing critical file: examples/main.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 115 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~85d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/markbates/goth"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Goth is a Go library that provides a unified, plugin-based authentication framework supporting 50+ OAuth/OAuth2/OIDC providers (Google, GitHub, Apple, Auth0, etc.). It abstracts provider-specific auth flows behind two simple interfaces—Provider and Session—letting developers add authentication to Go web apps without reimplementing each provider's protocol. Flat monorepo structure: root-level provider.go and session.go define the core interfaces; gothic/gothic.go is the HTTP handler wrapper; 50+ provider implementations live under providers/{name}/{name}.go with parallel session.go and _test.go files. examples/main.go is a runnable demo.

👥Who it's for

Go web developers building applications that need multi-provider authentication (social login, enterprise SSO). Specifically backend engineers using frameworks like gorilla/mux or chi who want to avoid vendor lock-in and provider duplication.

🌱Maturity & risk

Production-ready and actively maintained. The repo has 50+ real provider implementations with tests, CI/CD via GitHub Actions (.github/workflows/ci.yml), and uses Go 1.24.0. The extensive supported provider list and stable API indicate maturity, though single-maintainer risk exists.

Standard open source risks apply.

Active areas of work

Active maintenance visible in dependencies (Go 1.24.0 update, recent jwt and oauth2 versions). CI/CD workflows (.github/workflows/) are configured. Specific recent activity is not visible from the file list alone, but the codebase shows continuous provider expansion and test coverage.

🚀Get running

git clone https://github.com/markbates/goth.git
cd goth
go mod download
cd examples
go build
./examples
# Open http://localhost:3000

Daily commands:

cd examples
go build
./examples
# Requires env vars: TWITTER_KEY, FACEBOOK_KEY, GITHUB_KEY, etc. (see examples/main.go)

🗺️Map of the codebase

  • provider.go — Defines the core Provider interface that all authentication providers must implement—the fundamental contract of the entire framework
  • session.go — Defines the Session interface for storing authenticated user data—required to understand how user state is persisted across all providers
  • gothic/gothic.go — High-level HTTP handler wrapper that orchestrates the authentication flow and session management for web applications
  • gothic/provider.go — Provider registry and lookup mechanism that manages all available authentication providers in the application
  • examples/main.go — Reference implementation showing how to wire up providers and handle OAuth callbacks—essential onboarding guide
  • providers/amazon/amazon.go — Concrete provider implementation demonstrating the pattern used across all 50+ OAuth/OAuth2 providers in the framework

🧩Components & responsibilities

  • Provider (Interface) (golang.org/x/oauth2, net/http) — Orchestrates OAuth flow: generates auth URL, exchanges code for token, fetches user profile, optionally refreshes tokens
    • Failure mode: Invalid OAuth credentials, misconfigured scopes, or provider API changes → login fails or user data incomplete
  • Session (Interface) (gorilla/sessions, gorilla/context) — Serializes and stores authenticated user state (tokens, profile) between HTTP requests
    • Failure mode: Session store unavailable or corrupted → user logged out, forced re-auth, or security breach if state leaked
  • Gothic HTTP Handler — HTTP middleware that routes login/callback requests to correct provider and manages redirect

🛠️How to make changes

Add a New OAuth2 Provider

  1. Create provider directory under providers/{providername}/ (providers/newprovider/newprovider.go)
  2. Implement the Provider interface: Name(), Login(), HandleCallback(), FetchUser(), and RefreshToken(). Reference amazon.go as a template (providers/newprovider/newprovider.go)
  3. Create a Session type that implements the Session interface (GetAuthURL(), SetAuthorizationCode(), GetUser()). Typically stores AccessToken, RefreshToken, ExpiresAt, and user profile data (providers/newprovider/session.go)
  4. Register the provider in gothic by calling goth.UseProviders() or gothic.Store.Set() in your application. See examples/main.go for registration pattern (examples/main.go)
  5. Write unit tests following existing pattern. Test both successful auth flow and error cases (providers/newprovider/newprovider_test.go)

Integrate Goth into a Web Application

  1. Import goth packages and register desired providers with their OAuth credentials (ClientID, ClientSecret, Scopes) (examples/main.go)
  2. Set up two HTTP routes: one for login redirect (calls gothic.BeginAuthHandler) and one for callback (calls gothic.CompleteUserAuth) (gothic/gothic.go)
  3. Store the authenticated user session using gorilla/sessions or your preferred session store. The Session object from CompleteUserAuth contains the user profile (gothic/gothic.go)
  4. Protect routes by checking for an authenticated session. Use GetUser() or similar methods from the session to verify user identity (gothic/provider.go)

Handle Multi-Provider Setup

  1. Register multiple providers in your app initialization using goth.UseProviders(provider1, provider2, ...) (examples/main.go)
  2. On login, redirect to gothic.BeginAuthHandler with ?provider=provername query parameter (gothic/gothic.go)
  3. The callback handler automatically routes to the correct provider's HandleCallback() based on state parameter stored in session (gothic/gothic.go)

🔧Why these technologies

  • golang.org/x/oauth2 — Standard OAuth2 client library in Go ecosystem; handles token exchange, refresh, and HTTP client wrapping with automatic token injection
  • github.com/gorilla/sessions — Secure session management with cookie-based and server-side storage; integrates cleanly with HTTP handlers
  • github.com/golang-jwt/jwt — JWT parsing for providers like Apple that use ID tokens instead of traditional user info endpoints
  • github.com/mrjones/oauth — Legacy OAuth 1.0a support for older providers (e.g., Twitter before API v2 migration)

⚖️Trade-offs already made

  • Interface-based design with minimal enforcement—providers implement Provider + Session but no base type

    • Why: Maximum flexibility for protocol variations; each provider can customize auth flow, token handling, and user data serialization
    • Consequence: Code duplication across providers; no shared base struct means each implements boilerplate (URL construction, HTTP calls). Harder to refactor provider-wide changes
  • No built-in persistence layer—session storage delegated to application

    • Why: Goth remains transport-agnostic; applications can choose Redis, database, in-memory, etc.
    • Consequence: Developers must implement session store integration; examples show gorilla/sessions but don't enforce it. Potential for inconsistent session handling
  • Provider-per-directory structure with separate session.go files

    • Why: Clear organization; easy to find provider code and tests together
    • Consequence: 50+ directories increase repo surface area; harder to maintain consistent patterns; no DRY principle for common OAuth2 flows
  • No request rate limiting or retry logic built-in

    • Why: Scope remains focused on authentication; rate limiting is application/deployment concern
    • Consequence: Apps must handle OAuth provider rate limits and transient failures themselves

🚫Non-goals (don't propose these)

  • Authorization (scopes and permissions are provider-specific; Goth doesn't enforce policy)
  • Session encryption or signing—delegated to gorilla/sessions or user's session store
  • Persistent user database or identity storage—Goth extracts user profile but doesn't save it
  • Real-time token refresh—apps must call RefreshToken() explicitly
  • Multi-factor authentication or passwordless flows—only OAuth/OAuth2/OpenID Connect
  • WebAuthn, SAML, or custom protocol support—requires custom provider implementation

🪤Traps & gotchas

Required env vars: examples/main.go expects TWITTER_KEY, FACEBOOK_KEY, GITHUB_KEY, etc.; absence silently skips providers. Insecure defaults: gothic.Store uses Secure: false and no domain restrictions—must be overridden in production (see README Security Notes). OAuth redirect URI: must exactly match provider config or auth will fail; per-provider format varies (some require trailing slash). Session cookie signing: uses gorilla/sessions SecureCookie; requires stable secret key across restarts or sessions invalidate. State parameter: handled automatically but only if session middleware is chained correctly before Goth handlers.

🏗️Architecture

💡Concepts to learn

  • OAuth 2.0 Authorization Code Flow — The dominant pattern in Goth; understanding request→redirect→callback→token exchange is essential for debugging auth issues and adding new providers.
  • OpenID Connect (OIDC) — Goth has generic OIDC support (via auto-discovery); many enterprise providers (Azure AD, Okta) use OIDC, not plain OAuth2, so understanding the ID token and UserInfo endpoint is vital.
  • Session State & CSRF Protection — Goth uses the 'state' parameter to prevent CSRF attacks during OAuth redirect; gorilla/sessions cookie store implements this; misconfiguration is a common security bug.
  • JWT (JSON Web Token) Validation — Apple and Azure use JWT ID tokens instead of UserInfo endpoints; Goth uses lestrrat-go/jwx to verify signatures and extract claims; understanding exp, aud, iss is required for these providers.
  • Interface-Driven Design (Go Idiom) — Goth's entire architecture relies on the Provider and Session interfaces; mastering how to implement and satisfy these is the key to adding new providers without modifying core code.
  • OAuth1 (Legacy Protocol) — Twitter and Tumblr still use OAuth1 (not 2.0); Goth includes mrjones/oauth for these; understanding request signing and token secrets differs sharply from OAuth2.
  • HTTP Middleware Chains & gorilla/mux Routing — Goth handlers (gothic.BeginAuthHandler, gothic.CompleteAuthHandler) must be chained with session middleware correctly; order matters for state validation and cookie access.
  • ory/kratos — Full-featured identity & access management platform for Go; heavier than Goth but handles MFA, passwordless, and more IdPs out-of-the-box.
  • golang-jwt/jwt — Upstream JWT library used by Goth's Apple and Azure providers; understanding JWT claims is essential for debugging auth failures.
  • gorilla/sessions — Session store backing Goth; Goth uses it directly (gothic.Store), so cookie options and security settings are configured here.
  • golang/oauth2 — Canonical OAuth2 client library for Go; Goth wraps it for each provider, so token exchange and refresh flows originate here.
  • intridea/omniauth — Ruby predecessor that inspired Goth's design philosophy; similar multi-provider architecture if you want to understand the inspiration.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for gothic/gothic.go with multiple provider scenarios

The gothic package is the main entry point for the goth authentication system, but gothic_test.go likely has incomplete coverage for complex multi-provider scenarios. Contributors could add integration tests covering session management, provider switching, callback handling, and error cases across different OAuth2 flows. This is high-value because gothic is the primary interface users interact with.

  • [ ] Review existing gothic_test.go to identify missing test cases
  • [ ] Add tests for BeginAuthHandler with multiple providers
  • [ ] Add tests for CallbackHandler with session validation and user data extraction
  • [ ] Add tests for provider registration/unregistration edge cases
  • [ ] Add tests for malformed callbacks and security scenarios (CSRF, state mismatches)

Create missing session_test.go files for providers lacking test coverage

Examining the file structure, many providers have session.go files but the repository shows selective _test.go files. For example, providers/classlink/session.go, providers/cloudfoundry/session.go, and others likely lack dedicated session tests. Adding these tests ensures consistency and catches marshaling/unmarshaling bugs that commonly occur in session implementations across different OAuth2 providers.

  • [ ] Audit all providers/*/session.go files to identify those without corresponding session_test.go
  • [ ] For each missing test file, create test cases for GetAuthorizationURL()
  • [ ] Add test cases for Authorize() and token/user data parsing
  • [ ] Add test cases for session marshaling/unmarshaling edge cases
  • [ ] Test provider-specific quirks (e.g., different claim names, token response formats)

Add missing provider implementation tests and standardize test patterns across providers

While many providers have _test.go files, there's likely inconsistency in test coverage depth and patterns. The provider interface has specific contract requirements (GetAuthURL, FetchUser, etc.) that should be consistently tested. Adding standardized test fixtures and helper functions would improve test maintainability and catch behavioral deviations across the 30+ providers, reducing future bugs.

  • [ ] Create a test helper file (providers/provider_test_helpers.go) with common test fixtures and assertions
  • [ ] Identify providers with minimal test coverage (< 50% of methods tested)
  • [ ] Add specific test cases for FetchUser() error handling and response parsing
  • [ ] Add tests for RefreshToken() where applicable (OAuth2 providers)
  • [ ] Add parameterized tests to verify all providers properly handle missing/malformed scopes

🌿Good first issues

  • Add test coverage for gothic/gothic_test.go—files like providers/amazon/amazon_test.go show the pattern; extend to cover edge cases like missing state parameter or malformed tokens.
  • Document env var requirements per provider—create a providers/README.md listing which env vars each of the 50+ providers needs (e.g., AMAZON_KEY, APPLE_TEAM_ID, AUTH0_DOMAIN) with examples from examples/main.go.
  • Implement optional refresh token rotation—several providers (Google, GitHub) support refresh tokens in the Session; add automatic rotation logic to gothic.go when token is near expiry, with configurable callback for persistence.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 9c7a282 — Add CodeQL workflow for Go analysis (techknowlogick)
  • 4556f55 — Bump golang.org/x/crypto from 0.35.0 to 0.45.0 (#634) (dependabot[bot])
  • 4a3ac58 — Add Go 1.26.x check to CI (techknowlogick)
  • 15b24f5 — png instead of jpg (#400) (zivoy)
  • c9cc7cb — rm legacy gothic code (#623) (techknowlogick)
  • 44c60d8 — Add DingTalk provider (#607) (naokij)
  • 9133499 — go vet fixes (#622) (techknowlogick)
  • 5cda81b — Use updated Google user info endpoint (#621) (techknowlogick)
  • 6c7fc31 — Bump github.com/go-chi/chi/v5 from 5.1.0 to 5.2.2 (#619) (dependabot[bot])
  • eeef248 — Bump golang.org/x/crypto from 0.21.0 to 0.35.0 (#618) (dependabot[bot])

🔒Security observations

  • High · Outdated OAuth2 Library — go.mod - golang.org/x/oauth2 v0.30.0. The codebase uses golang.org/x/oauth2 v0.30.0, which may contain known vulnerabilities. OAuth libraries are critical security components, and outdated versions can expose the application to token theft, CSRF attacks, or other OAuth-specific vulnerabilities. Fix: Update to the latest stable version of golang.org/x/oauth2. Run 'go get -u golang.org/x/oauth2' and thoroughly test all authentication flows.
  • High · Outdated JWT Library — go.mod - github.com/lestrrat-go/jwx v1.2.29. The codebase uses github.com/lestrrat-go/jwx v1.2.29, which is an older major version. JWT libraries handle sensitive token validation, and outdated versions may have security flaws in signature verification, claims validation, or algorithm handling. Fix: Consider upgrading to v2.x of lestrrat-go/jwx or the more actively maintained golang-jwt/jwt library. Review the changelog for breaking changes and security patches.
  • Medium · Outdated Session Management Library — go.mod - github.com/gorilla/sessions v1.1.1. The codebase uses github.com/gorilla/sessions v1.1.1, which may not have recent security updates. Session libraries are critical for secure authentication token storage and cookie handling. Fix: Update to the latest version of gorilla/sessions. Check the GitHub repository for security advisories and ensure secure cookie configurations (HttpOnly, Secure, SameSite flags) are properly set.
  • Medium · Outdated Gorilla Mux Router — go.mod - github.com/gorilla/mux v1.6.2. The codebase uses github.com/gorilla/mux v1.6.2, which is significantly outdated (released in 2017). Older routing libraries may have security implications for request handling and URL validation. Fix: Update to the latest version of gorilla/mux (v1.8.x) to ensure proper routing security and bug fixes. Alternatively, consider using the modern chi router (already present in dependencies).
  • Medium · Deprecated OAuth Library Usage — go.mod - github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c. The codebase uses github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c for OAuth 1.0 support. This library appears to be unmaintained, and OAuth 1.0 has known security limitations compared to OAuth 2.0. Fix: Audit the codebase to identify which providers use OAuth 1.0. Plan migration to OAuth 2.0 providers or replace with actively maintained OAuth 1.0 libraries. Consider removing OAuth 1.0 support if possible.
  • Medium · Testing Mock Library in Production Dependencies — go.mod - github.com/jarcoal/httpmock. The codebase includes github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da in main dependencies. HTTP mocking libraries should only be used in test dependencies to avoid accidental production inclusion. Fix: Move httpmock to the test dependencies section. Run 'go mod tidy' and verify it's only imported in *_test.go files.
  • Medium · Potential Insecure Crypto Operations — go.mod (indirect) - golang.org/x/crypto v0.45.0. The dependency golang.org/x/crypto v0.45.0 is included indirectly. While present, ensure that all cryptographic operations (token generation, hashing, etc.) use secure random number generation and proper algorithm selection. Fix: Review provider implementations to ensure they use crypto/rand for token generation. Verify that weak algorithms (MD5, SHA1) are not used for sensitive operations.
  • Medium · Large Attack Surface with Multiple Providers — undefined. The codebase supports 50+ OAuth providers. Each provider Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · markbates/goth — RepoPilot