Skip to content

bodaay/SimpleAuth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

183 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” SimpleAuth

Enterprise authentication that fits in a single 10Β MB binary.
Active Directory Β· Kerberos SSO Β· a standard OIDC provider Β· signed JWTs β€” running in 3 commands.

License: MIT Made with Go Single binary No dependencies Security audited

Quick Start Β· API Reference Β· ADΒ +Β Kerberos Β· SDKs Β· Security Audit Log Β· Contributing


Setting up authentication shouldn't mean standing up a Java cluster, a database, a cache, and a weekend. SimpleAuth is the whole identity layer β€” Active Directory login, transparent Windows SSO, a standards-compliant OIDC provider, and RS256 JWTs β€” in one Go binary you can scp to a box and run.

No Java. No mandatory database. No config files after first run. Everything is managed from a built-in admin UI, and a domain-joined machine gets you to two-click Kerberos SSO. Drop it in, point your app at it, ship.

docker run -d -p 8080:8080 \
  -e AUTH_HOSTNAME=auth.example.com \
  -e AUTH_ADMIN_KEY=change-me \
  -e AUTH_REDIRECT_URIS="https://myapp.example.com/*" \
  -v simpleauth-data:/data \
  simpleauth
# β†’ admin UI at https://auth.example.com/sauth/admin. That's it.

✨ Why you'll like it

It's powerful. Everything a real identity provider needs, nothing watered down:

  • πŸͺͺ Active Directory & LDAP β€” bind login, attribute sync, group membership, auto-discovery.
  • 🎫 Transparent Kerberos / SPNEGO SSO β€” users on the domain are logged in without typing anything. SSO setup is a downloadable PowerShell script and one paste-back β€” no ktpass, no keytab files, no hand-edited LDAP.
  • 🌐 A standard OIDC provider β€” discovery, authorization-code flow with PKCE, token, userinfo, JWKS, introspection, end-session. Works with any OIDC client library, in any language.
  • πŸ”‘ RS256 JWTs β€” auto-generated RSA-2048 keys, a JWKS endpoint for offline verification, single-use refresh-token rotation with family replay detection.
  • πŸ‘₯ Roles, permissions & groups β€” resolved into the token your app already trusts.
  • 🏒 One directory, many apps β€” register multiple apps that each own their own roles, permissions, and allowed users. Users sign in once; tokens are audience-scoped, so a token minted for app A is rejected by app B. (details below)

It's simple. The kind of simple you feel in the first five minutes:

  • πŸ“¦ One ~10 MB binary. No runtime, no JVM, no sidecars. BoltDB is embedded β€” zero external dependencies to start.
  • πŸ–₯️ A real admin UI (dark mode included) β€” users, roles, LDAP, audit log, settings, database, all on a page. No XML, no kcadm.sh.
  • ⚑ 3 commands to running, and users are auto-created on first login from any provider β€” no import, no sync, no migration job.
  • 🧩 Embeddable β€” import "simpleauth/pkg/server" and your Go app is the auth server.
  • πŸ“š Official SDKs for JavaScript/TypeScript, Go, Python, and .NET, each with framework middleware.

SimpleAuth vs. the usual suspects

Keycloak ADFS SimpleAuth
Setup Hours (Java + Postgres + cache) Hours + Windows Server 3 commands
Footprint ~500 MB+ A domain controller ~10 MB binary
External deps Database + cache required Windows infra None (optional Postgres)
Kerberos SSO Manual, fiddly Built-in but rigid Two-click auto-config
OIDC provider Full Claims-based Full
Per-app authorization Realms + clients (heavy) Relying-party trusts Built-in, audience-scoped
Admin experience Steep Windows-only MMC One web page
REST API Sprawling None Clean JSON + JWTs

πŸš€ Quick start

Docker:

docker run -d -p 8080:8080 \
  -e AUTH_HOSTNAME=auth.example.com \
  -e AUTH_ADMIN_KEY=my-secret-admin-key \
  -e AUTH_REDIRECT_URIS="https://myapp.example.com/callback,https://myapp.example.com/*" \
  -e AUTH_CORS_ORIGINS="https://myapp.example.com" \
  -v simpleauth-data:/data \
  simpleauth

Binary:

./simpleauth init-config     # generates simpleauth.yaml
vim simpleauth.yaml          # set hostname, redirect URIs, admin key
./simpleauth                 # running

Open the admin UI at https://<hostname>/sauth/admin and sign in with your admin key. (Omit AUTH_ADMIN_KEY and one is generated on first run and printed to the logs.)

For any real deployment, set three things: AUTH_HOSTNAME, AUTH_ADMIN_KEY, and AUTH_REDIRECT_URIS. Without an allowlist, every login redirect is rejected β€” by design.

New to OAuth/OIDC? The Quick Start walks you from zero to a logged-in user, and the Integration Guide explains every term (JWT, redirect URI, CORS, the /sauth base path) in plain language.

πŸ”Œ Add it to your app

Pick whichever fits β€” you can mix them:

1. Direct REST β€” best for mobile, SPAs with a backend, and server-to-server.

curl -X POST https://auth.example.com/sauth/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"secret123"}'
# β†’ { "access_token": "eyJ…", "refresh_token": "eyJ…", "expires_in": 900 }

2. Hosted login page β€” best for web apps that don't want to build a login form. Redirect to …/sauth/login?redirect_uri=https://myapp/callback; SimpleAuth (or Kerberos SSO) authenticates the user and hands the tokens back on the callback.

3. Standard OIDC β€” best when you already use an OIDC client library or need an id_token. Point your library at the discovery URL and you're done:

https://auth.example.com/sauth/.well-known/openid-configuration

Then verify tokens offline against the JWKS endpoint (no network call per request), or call /sauth/api/auth/userinfo to introspect. Full walkthrough with every flow: docs/API.md.

Use an SDK instead of raw HTTP

Language Package Install
JavaScript / TypeScript @simpleauth/js npm install @simpleauth/js
Go github.com/bodaay/simpleauth-go go get github.com/bodaay/simpleauth-go
Python simpleauth pip install simpleauth
.NET SimpleAuth reference the project

Every SDK does login/refresh/userinfo, offline JWT verification with cached JWKS, role/permission helpers (HasRole, HasPermission, HasAnyRole), and ships middleware for Express, net/http, FastAPI/Flask/Django, and ASP.NET Core. See examples/.

🏒 One login, many apps β€” each with its own authorization

Most auth servers make you choose: one shared login or per-app control. SimpleAuth gives you both β€” one directory, one sign-in, but every app owns its own authorization.

  • Register an app β†’ it gets an app_id + app_secret. The root admin adds apps; existing single-app deployments auto-migrate to a default app, unchanged.
  • Tokens are audience-scoped. Every token carries aud = the app it was minted for, so a token for billing is rejected by analytics β€” the SDK's audience option enforces it. No more one-token-rules-them-all.
  • Each app owns its roles, permissions, and assignments. viewer in one app is unrelated to viewer in another. Flip on require_assignment and an app admits only the users it has explicitly assigned.
  • Apps manage themselves. An app configures its own roles and assignments using its app_id/app_secret (HTTP Basic or a short-lived management token) and an idempotent POST /api/app/bootstrap you can run on every deploy β€” no master admin key in your pipeline.
  • App-local users. An app can own users who aren't in your directory at all β€” perfect for a customer portal β€” scoped to that app and never shared across apps.

A developer's whole integration becomes: get an app_id/app_secret β†’ bootstrap your roles on deploy β†’ point the SDK at SimpleAuth with audience set β†’ verify(). All four SDKs ship the app-management helpers (appBootstrap, getAppAuthz/setAppAuthz, app-local user CRUD) β€” see the app-integration examples in examples/ and the Apps reference in docs/API.md.

Think Azure AD / Entra app registrations β€” one directory, many apps, per-app roles, audience-scoped tokens β€” without the cluster.

🧰 What's in the box

Authentication

  • Kerberos/SPNEGO transparent Windows SSO
  • Optional shared SSO session cookie (log in once, skip the login page across apps)
  • Auto-SSO with a countdown + cancel
  • LDAP bind login for non-domain users
  • Local passwords (bcrypt, policy, history)
  • Account lockout after repeated failures
  • Hosted login page + standard OIDC
  • Admin impersonation (fully audited)

Tokens & authorization

  • RS256 JWTs, auto-generated RSA-2048 keys
  • JWKS endpoint for offline verification
  • Refresh-token rotation + family replay detection + revocation
  • Roles, permissions, and roleβ†’permission mapping
  • Per-app authorization β€” audience-scoped tokens, per-app roles & assignment
  • App self-service + app-local users (apps own their own scope)
  • Default roles auto-assigned on first login
  • AD/LDAP groups surfaced in the token

Admin UI (dark mode, one page)

  • Users: CRUD, disable, merge, unlock, force reset
  • Roles & permissions
  • LDAP providers + AD setup script + Kerberos
  • Identity mappings & audit log
  • Runtime settings (redirects, CORS, policy, rate limits)
  • Database stats, migration, backend switching, restart

Ops & storage

  • BoltDB embedded by default β€” zero config
  • PostgreSQL optional (AUTH_POSTGRES_URL), migrate either way from the UI, auto-fallback if it's unreachable
  • Per-IP rate limiting with trusted-proxy support
  • CSRF protection on login forms; strict redirect allowlist
  • Live backup/restore via the API
  • Linux SSO setup script (krb5.conf + every major browser)

πŸ›‘οΈ Security is the whole point

SimpleAuth guards the front door, so security isn't a feature β€” it's the product. A few things we do differently:

  • A public, living audit trail. SECURITY-AUDIT.md logs every security review, finding, and fix β€” dated, with stable IDs, by different AI models and humans over time. Nothing is swept under the rug; even WONTFIX decisions are written down with rationale. It's unusual to publish your own audit log. We think a project that protects logins should.
  • Sane defaults that fail closed. Redirect URIs are a strict allowlist (empty = reject all). The confidential OIDC grants (password, client_credentials) and token introspection are disabled unless you set AUTH_CLIENT_SECRET. Trusted proxies default to trust none.
  • Modern token hygiene. RS256 only (no alg-confusion), JWKS with a stable key id, single-use refresh tokens with replay detection, an access-revocation kill switch, and authenticator-verified Kerberos with a replay cache and clock-skew enforcement.
  • Defense in depth. bcrypt password hashing with a configurable policy and history, account lockout, per-IP rate limiting, CSRF tokens, and security headers across responses.

Found something? Please open a security advisory (or a private report) rather than a public issue β€” see Contributing. Then add it to the audit log; that's exactly what it's for.

🀝 Contributing

This project is public on purpose. SimpleAuth protects authentication, and security software gets better with more eyes on it. If you've ever wanted to work on an auth server that's small enough to actually read end-to-end in an afternoon β€” this is that codebase.

Especially valuable:

  • πŸ” Security review. Read SECURITY-AUDIT.md, then audit a flow (login, refresh rotation, Kerberos, OIDC grants, the store layer) and send what you find β€” a PR, an issue, or a new audit pass appended to the log. The file even contains the prompt we hand to each reviewer.
  • 🧩 More SDKs & framework middleware. Rust, Java, PHP, Ruby β€” or deeper middleware for the four we already ship.
  • πŸ“– Docs & examples. A clearer explanation, a new framework example in examples/, a fixed typo β€” all welcome.
  • πŸ› Bugs & papercuts. Edge cases in LDAP/Kerberos against real directories are gold.

Get going in a minute:

git clone <your-fork>
cd SimpleAuth
go build ./...        # builds the single binary
go test ./...         # full suite (no external services needed)
go vet ./...

Open a PR with a focused change and a test, and keep the trio in sync β€” code, docs, and the SDKs/examples for any surface you touch. New features ship with all of it. First time here? Open an issue describing what you'd like to do and we'll point you at the right file.

πŸ“š Reference

OIDC endpoints

Discovery: GET /.well-known/openid-configuration

Endpoint Method Path
Authorization GET /realms/{issuer}/protocol/openid-connect/auth
Token POST /realms/{issuer}/protocol/openid-connect/token
UserInfo GET/POST /realms/{issuer}/protocol/openid-connect/userinfo
JWKS GET /realms/{issuer}/protocol/openid-connect/certs
Introspection POST /realms/{issuer}/protocol/openid-connect/token/introspect
End Session GET/POST /realms/{issuer}/protocol/openid-connect/logout

authorization_code and refresh_token are public flows (auth-code supports PKCE/S256). password, client_credentials, and introspection are confidential β€” disabled unless AUTH_CLIENT_SECRET is set, then require that secret.

Direct API
Method Path Description
POST /api/auth/login Login, get JWT tokens
POST /api/auth/refresh Rotate refresh token
GET /api/auth/userinfo Current user from the JWT
GET /api/auth/negotiate Kerberos/SPNEGO SSO
POST /api/auth/impersonate Token as another user (admin)
POST /api/auth/reset-password Change password (authenticated)
GET /login Β· /logout Β· /account Hosted pages
GET /.well-known/jwks.json JWKS public keys
GET /health Health check
Admin API (all require Authorization: Bearer <admin-key>)
Category Endpoints
Bootstrap POST /api/admin/bootstrap β€” idempotent: define roles, permissions, ensure users
Users CRUD /api/admin/users, merge/unmerge, disable, unlock, sessions
Roles & Permissions /api/admin/roles, /api/admin/permissions, /api/admin/role-permissions
LDAP CRUD /api/admin/ldap, auto-discover, import/export, test
AD / Kerberos GET /api/admin/setup-script, /api/admin/ldap/:id/setup-kerberos
Linux SSO GET /api/admin/linux-setup-script
Settings / DB / Ops runtime settings, migrate/switch backends, backup, restore, audit, restart

Full reference with request/response examples: docs/API.md.

Essential configuration
Variable Default Description
AUTH_HOSTNAME OS hostname FQDN for TLS cert and Kerberos SPN
AUTH_ADMIN_KEY auto-generated Admin API key
AUTH_BASE_PATH /sauth URL path prefix (every URL starts here)
AUTH_REDIRECT_URIS Allowed redirect URIs, comma-separated (* wildcards)
AUTH_CORS_ORIGINS Browser origins allowed to call SimpleAuth
AUTH_POSTGRES_URL Enables the Postgres backend
AUTH_TLS_DISABLED false Disable TLS (reverse-proxy mode)
AUTH_TRUSTED_PROXIES Trusted proxy CIDRs (default: trust none)
AUTH_CLIENT_SECRET Enables confidential OIDC grants + introspection
AUTH_JWT_ACCESS_TTL 15m Access token lifetime
AUTH_JWT_REFRESH_TTL 720h Refresh token lifetime
AUTH_ENABLE_SESSION_SSO false Shared SSO session cookie across apps
AUTH_AUTO_SSO false Auto-attempt Kerberos SSO on the login page

Everything else β€” password policy, lockout, rate limiting, audit retention β€” is in docs/CONFIGURATION.md. Behind nginx/Traefik/Caddy/HAProxy? See docs/REVERSE-PROXY.md (and mind the Kerberos header buffers).

πŸͺŸ Active Directory in two clicks

  1. Admin UI β†’ LDAP Providers β†’ AD Setup Script. Enter a service-account name, download the PowerShell script.
  2. Run it on any domain-joined machine β€” it creates the account, registers SPNs, and exports a config file. No ktpass.
  3. Paste the config back in the UI. SimpleAuth builds the keytab in memory and enables SSO immediately.

Full guide + troubleshooting: docs/ACTIVE-DIRECTORY.md.

🧱 Embed it in your Go app

cfg := server.Defaults()
cfg.Hostname = "myapp.example.com"
cfg.AdminKey = "my-secret-key"
cfg.DataDir  = "./auth-data"
cfg.BasePath = "/auth"

sa, err := server.New(cfg, ui.FS())  // pass nil UI for API-only
if err != nil { log.Fatal(err) }
defer sa.Close()

mux := http.NewServeMux()
mux.Handle("/auth/", http.StripPrefix("/auth", sa.Handler()))
// your app handles everything else
http.ListenAndServe(":8080", mux)

Your app and its auth server, one process, one deploy. See docs/ARCHITECTURE.md.

πŸ“– Documentation

Document What's inside
Quick Start Zero to a logged-in user in 5 minutes
API Reference Every endpoint, every term, with examples
Configuration All config options
Architecture How it works under the hood
Active Directory AD, Kerberos, troubleshooting
Reverse Proxy nginx, Traefik, Caddy, HAProxy
SDK Guide Client SDK usage
Security Audit Log Every review, finding, and fix

License

MIT β€” see LICENSE. Build something with it, and if it makes your auth simpler, ⭐ the repo so the next person finds it.

About

AD LDAP working with Kerberos/SPNEGO

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors