- Go 96.5%
- Go Template 1.8%
- CSS 1.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Discovery, the JWKS, authorisation with mandatory PKCE, the token endpoint's code, refresh and client-credentials grants, consent, and userinfo. burh now signs applications in, which is the point of it. The front channel lives with the hosted pages, which own sessions and templates; the back channel is pure protocol. Validation proves the client and its redirect before anything else, because until then a failure must not be delivered anywhere: sending an error onwards would hand it to whatever address the request invented. Only once the destination is proved may later failures travel by redirect. The consent page asks in plain words and remembers the answer per scope set; one new scope reopens the whole question. Trusted first-party clients skip it. A denied person gets a page naming the audit reference, so an administrator can find the exact moment. The default signing key is minted at start-up rather than at first sign-in, because relying parties fetch the JWKS when they are configured, which is before anyone has signed in. A replayed code ends the session it was bound to, and only that one: the first redemption's winnings die with the session at their next refresh, while ending every session would let a replayed code sign the person out of everything, a denial of service rather than a defence. The whole cascade is proved over live HTTP, replay to refusal to the untouched browser session. |
||
| cmd/burh-server | ||
| internal | ||
| .gitignore | ||
| .golangci.yml | ||
| .goreleaser.yaml | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
burh-server
burh is a small, self-contained identity provider. One static Go binary holds the OpenID Connect provider, the hosted login pages, the administration API and its own replicated store, so a homelab runs it from a single container and a business runs the same build clustered across three nodes.
There is no external database, no message broker and no JavaScript build chain to operate. Point a reverse proxy at it, or let it terminate TLS itself, and it works.
Status
Early development. The foundations are in place; the store, the directory API and the OpenID Connect provider are being built in that order. Nothing here is ready to hold real accounts yet.
What it does
- OpenID Connect and OAuth 2.0: authorisation code with PKCE, refresh with rotation and reuse detection, client credentials, the device flow, token exchange and dynamic client registration.
- Credentials: passwords hashed with Argon2id, TOTP, and passkeys usable as a passwordless first factor. Magic links exist for resets, invitations and address verification only; they never bypass a login.
- Directory: users, flat groups and administrator-defined typed attributes that can be mapped into token claims.
- Access control: each client is open to everyone or restricted to named groups, optionally demanding multi-factor authentication.
- Auditing: an append-only trail of every authentication decision and administrative change, queryable over the API, streamed live over server-sent events, and delivered to signed webhooks.
- Operations: Prometheus metrics, OpenTelemetry traces, health and readiness endpoints, consistent snapshots, and optional built-in ACME certificates.
Related repositories
| Repository | Purpose |
|---|---|
| burhctl | Terminal administration console and scriptable client |
| burh-self-service | Reference self-service portal |
| burhlib | The API description and its generated Go client |
Building
Go 1.26 or newer is required.
make build # bin/burh-server
make check # lint and tests
make test
Linting uses golangci-lint and releases
are cut with GoReleaser; both are expected
on PATH. The version string comes from the git tag at build time and
is not recorded anywhere in the source.
Releases
Tagged releases publish signed checksums alongside binaries for Linux, macOS and FreeBSD on amd64 and arm64:
make snapshot # local build, no publishing
Release signing expects GPG_FINGERPRINT in the environment.
Contributing
Patches are welcome. Please keep to the conventions already in the tree: guard clauses over nested conditionals, files well under 500 lines, lines wrapped at 72 columns, and behaviour landing with a test. Commit messages follow Conventional Commits.
Licence
Apache-2.0. See LICENSE.