Atrium is a self-hosted identity server. It speaks OAuth 2.0 and OpenID Connect. One process serves the protocol, the browser sign-in pages, and the management API.
Run it with a SQLite file and no extra services. just run is enough for
local use. Administration is a client-credentials token with the
management scope, through /api and atrium-cli. Postgres, Redis, SMTP,
and traces turn on when you set them.
- Authorization code with PKCE, client credentials, device code, refresh tokens, token exchange, and on-behalf-of delegation to a registered agent
- A paste-the-code page for the out-of-band redirect URNs, and an optional
combined-code helper at
/oauth/oob - CIBA in poll mode, and pushed authorization requests
- OpenID Connect discovery, JWKS, UserInfo, and ID tokens
- Pairwise subjects, and nested encryption for ID tokens and UserInfo when a client opts in
- DPoP and mutual TLS client authentication
- TOTP enrollment, browser login, registration, consent, organization
choice, a signed-in profile at
/profile, and logout - Account APIs for the signed-in user, and management APIs for the management client
- Dynamic client registration and client ID metadata documents
- Social login, webhooks, audit, and login analytics
- An operator console at
/dashboardwhendashboard.enabledis true
Access tokens are opaque unless you set security.access_token_format to
jwt.
git clone https://github.com/bravo68web/atrium.git
cd atrium
just runWith no config.yaml, the server listens on http://localhost:8080. When
that file is present, just run uses its port and TLS settings.
A v* tag publishes release archives and the server image. The image
is bravo68web/atrium and ghcr.io/bravo68web/atrium, for amd64,
arm64, and arm/v7. See Deploy.
Postgres install:
docker compose -f deploy/compose.yaml up --buildChange management.client_secret in deploy/config.yaml before you use
that file anywhere but a laptop. just run still uses SQLite.
just build
./bin/atrium-cli initinit writes config.yaml and internal/hashalgo/algo.go. It leaves an
existing file in place unless you pass --force.
| Piece | Role |
|---|---|
| Go 1.26 | Server, atrium-cli, and atrium-mobile |
| chi | HTTP router |
| SQLite | Default database, one open connection |
| Postgres | Optional database, through database.dsn |
| Redis | Optional cache and approval queue |
| RabbitMQ | Optional retry queue for webhooks and mail |
| OpenTelemetry | Optional OTLP/HTTP traces |
| Docker | Images on GHCR and Docker Hub |
SQLite needs no extra service. Postgres, Redis, RabbitMQ, and traces stay off until you set them. See Deploy.
| Guide | What it covers |
|---|---|
| Configuration | Config file, keys, mail templates, hashing |
| Deploy | Process, TLS, Postgres, Redis, SMTP, traces |
| Branding | Login pages, assets, and HTML overlays |
| CLI | atrium-cli and atrium-mobile |
| Infrastructure | Process layout, SQL, Redis, signing keys |
| Testing | Go tests, Postgres, and the browser suite |
| API | Route map and the OpenAPI spec |
| Push devices | Authenticator registration |
| AAuth | Agent authorization discovery |
| Cross-app access | ID-JAG issuance and redemption |
| Contributing | Checks, hasher contract, and pull requests |
After the server is running, the Scalar UI is at http://localhost:8080/docs.
MIT. See LICENSE. Copyright (c) 2026 Jyotirmoy Bandyopadhayaya.