go-auth

Introduction

What go-auth is, why it exists, what it does, and how it compares to rolling your own auth or using a hosted provider.

go-auth

A self-hosted authentication library for Go. You configure it in your own process, point it at your own database, and it gives you registration, login, sessions, password recovery, email verification, invite-only signup, OAuth, multi-tenant organizations, an admin surface, CSRF protection, rate limiting, and audit logging — as a package you import, not a service you depend on.

Pre-1.0 — expect breaking changes

go-auth is early and under active development. The public API (types, With* options, route paths, and JSON response shapes) can and will change without a deprecation period until a 1.0 release is tagged. Pin an exact version, read the changelog before upgrading, and don't treat this as a stable dependency yet.

Why it exists

Authentication is small enough that every project ends up writing its own, and sharp enough that most of those homegrown versions get something wrong — session fixation, missing CSRF checks, timing-safe comparisons skipped, refresh tokens that never rotate, password reset tokens that never expire. None of that is exotic; it's just a lot of detail to get right every single time.

The usual alternative is a hosted auth provider. That solves the correctness problem but introduces a different one: your user data now lives outside your infrastructure, you're billed per user or per login, and you're constrained to whatever the provider's API allows.

go-auth sits in between. It's a library, not a service — your data stays in your own PostgreSQL, MySQL, or SQLite database, there's no per-user cost, and no network hop to a third party on every request. In exchange, you own the deployment: you write the Go program that imports it, and you're responsible for running it.

What it does

Registration and login support email/password, OAuth (Google and GitHub built in, or any provider you implement), and invite-only signup, with optional required email verification. Sessions use two tokens — a short-lived session token and a longer-lived refresh token — with idle timeout, an absolute maximum lifetime, and transparent rotation. Password reset, change-password, and set-password (for OAuth-only accounts) are all handled, as is email verification with resend throttling.

Beyond individual accounts, it supports multi-tenant organizations with membership roles and invites, and an admin surface for listing, banning, role changes, and session revocation across users. Every request that mutates state passes through CSRF checks — origin/referer validation, with a double-submit cookie token on top that you can turn off but don't have to turn on — and every sensitive endpoint has a rate limit out of the box. Security-relevant events — logins, password changes, admin actions, org changes — can be recorded to an audit log, streamed to Kafka, NATS, a webhook, or any sink you write yourself, alongside the built-in one. Every internal component logs through a single structured slog.Logger you provide, so audit events, rejected requests, and startup warnings all land in your existing log pipeline.

Delivery of email (verification, invites, password reset) goes through a one-method interface, so plugging in Resend, Postmark, SES, or your own SMTP server is a small amount of glue code, not a fork. The templates themselves are replaceable too — if you want your own branding or copy instead of the built-in HTML/text templates, implement one interface and hand it your own renderer.

Comparison

Rolling your ownHosted auth-as-a-servicego-auth
Where your data livesYour databaseTheir serversYour database
Ongoing costYour timePer-user / per-login pricingFree — self-hosted
Setup timeWeeks, if done carefullyMinutesAn afternoon
Security review neededAll of it, on youHandled by the providerThe library's surface is reviewed; your deployment still needs review
Network dependency at runtimeNoneYes — auth calls leave your infrastructureNone
CustomizationTotal, but you built itLimited to what the provider exposesTotal — it's Go source you can read and, if needed, fork

Features

Authentication — email/password and OAuth registration and login, invite-only signup, optional required email verification, admin login separate from regular login.

Sessions — dual-token (session + refresh) with rotation, idle timeout, absolute max lifetime, configurable grace window for racing refresh requests, and a debounce on activity tracking.

Account lifecycle — forgot/reset password, change password, set password for OAuth-only accounts, change name, self-service and admin-initiated account deletion.

Organizations — multi-tenant orgs with owner/admin/member roles, invites, and an active-org concept per session.

Admin — list/detail/ban/unban/role-change/delete for users, per-user session listing and revocation, invite management, audit log viewing.

Security — CSRF origin checking plus a double-submit cookie layer, both on by default, per-route rate limiting, configurable password policy, tri-state cookie Secure and email-link http:// policy that default sensibly per environment.

Audit logging — off by default; opt in with one flag for an async, non-blocking event pipeline with a built-in database sink; add your own sinks (Kafka, NATS, a webhook, anything implementing one interface) to stream the same events elsewhere, with fail-open or fail-closed behavior your choice.

Logging — a single structured slog.Logger used everywhere in the library (sessions, CSRF, rate limiting, audit, admin actions) — bring your own handler (JSON, text, or a third-party slog backend) and everything shows up there.

Extensibility — every external dependency is a small interface you can replace: OAuthProvider for adding providers beyond the built-in two (Google, GitHub), Mailer for email delivery (Resend, Postmark, SES, your own SMTP client), TemplateProvider for replacing the built-in email templates with your own branding, ratelimit.Store for a distributed rate limiter, and audit.EventSink for custom audit destinations.

Storage — PostgreSQL, MySQL, or SQLite, with the schema embedded in the library.

Next

On this page