Quick Start
This guide starts the full local stack from a checkout of nauthera-server: the server, PostgreSQL behind PgBouncer, Redis, Prometheus, Tempo and Grafana. It then walks a real OpenID Connect sign-in through it.
No release has been published yet (#307), so the stack is built from source. You need access to the nauthera-server repository.
Prerequisites
- Docker with Compose v2
- Go 1.27.3, the version pinned in
go.mod. It is used to generate the local certificates and to runnauthera-cli. Thejustrecipes run withGOTOOLCHAIN=local, so an older Go stops with an error. - just
curlandjq
1. Start the stack
just upjust up provisions a local TLS certificate into .certs/ and then runs
docker compose up --build. The certificate comes from mkcert when mkcert is installed
and its CA is trusted, and is self-signed otherwise. The same step writes the control
plane's development mutual-TLS set to .certs/grpc/: a CA, the server's key pair and a
nauthera-cli client certificate.
| Service | URL | Notes |
|---|---|---|
| nauthera-server | https://localhost:8080 | Public OAuth 2.0 / OIDC surface and sign-in UI |
| admin dashboard | https://localhost:8080/admin/ | Needs an account that holds an admin role; see Admin Dashboard |
| admin listener | http://localhost:9090/metrics, /healthz, /readyz | Internal only |
| gRPC AdminService | localhost:9091 | Mutual TLS; admits only the nauthera-cli certificate in .certs/grpc/ |
| Grafana | http://localhost:3000 | Server overview and audit-log dashboards |
| Prometheus | http://localhost:9092 | Scrapes the admin listener |
2. Check the issuer
# -k: the certificate is self-signed unless you ran `mkcert -install`.
curl -sk https://localhost:8080/.well-known/openid-configuration | jq '{issuer, grant_types_supported}'
curl -s http://localhost:9090/readyzThe issuer is https://localhost:8080. The advertised grant types are
authorization_code, refresh_token, client_credentials and
urn:ietf:params:oauth:grant-type:device_code.
3. Sign in to Grafana through Nauthera
The compose stack configures Grafana's generic OAuth login against Nauthera. Register
the matching client over the gRPC AdminService, which the script reaches with the client
certificate in .certs/grpc/:
just grafana-oidcThe script registers a confidential grafana client with
redirect_uri=http://localhost:3000/login/generic_oauth, PKCE required, and the
openid profile email offline_access scopes. It writes the client secret (printed only
once) to the git-ignored deploy/compose/grafana-oidc.env and restarts Grafana.
Open http://localhost:3000 and choose Sign in with Nauthera. Self-registration is
enabled in this stack (auth.registration.enabled: true), so you can create an account
on the hosted sign-in page. The stack also makes MFA mandatory (mfa.required: true).
After registering, you enrol a TOTP authenticator app and confirm you have saved your
recovery codes. Then you are sent back to Grafana.
4. Register your own client
nauthera-cli is a development tool for the gRPC AdminService. For clients, it uses the
same idempotent upsert the operator drives. Point it at the development certificate
first:
export NAUTHERA_CLI_TLS_CA_FILE=.certs/grpc/ca.pem
export NAUTHERA_CLI_TLS_CERT_FILE=.certs/grpc/client.pem
export NAUTHERA_CLI_TLS_KEY_FILE=.certs/grpc/client-key.pem
go run ./cmd/nauthera-cli create client my-app \
--display-name "My App" \
--redirect-uri http://localhost:5173/callback \
--scopes openid,profile,email,offline_accessA client secret is generated and printed once, by the run that mints it, which is normally the run that creates the client. Store it then. Running the command again never rotates it. To get a new one, delete the client and create it again:
go run ./cmd/nauthera-cli get client
go run ./cmd/nauthera-cli delete client my-appPass --public for a public client (no secret, PKCE required), or --jwks-uri for a
private_key_jwt client. Then point any OpenID Connect library at the issuer
https://localhost:8080.
5. Look around
- Audit log. Open
http://localhost:3000/d/nauthera-auditto see sign-ins and account registrations recorded inaudit_events. Client changes made over the gRPC AdminService are not recorded in the audit log yet (#301). That includes every client change in this guide. - Metrics and traces. The Grafana server overview dashboard
(
http://localhost:3000/d/nauthera-overview) reads Prometheus. Traces go to Tempo, which Grafana has as a datasource: search them in Explore. Nothing links a metric to its trace. Each request's own log line (http_request, orgrpc_callfor the AdminService) carriestrace_idandspan_id; most other lines logged while serving it do not.
Without Docker
To run the server with no external services at all:
just certs # once: the local TLS certificate
just web-build # once: the sign-in pages
just runThis uses config.dev.yaml: embedded SQLite with migrations applied on start, HTTPS on
:8080, self-registration on, and the gRPC API without TLS on 127.0.0.1:9091, so
nauthera-cli needs no TLS flags here. Use it for development only.
A fresh checkout embeds no sign-in pages, so /login and the other hosted pages show a
placeholder until just web-build has built them. just web-dashboard-build builds and
embeds the admin dashboard the same way. It needs bun; use the
version web/package.json pins in packageManager, the one CI and the image build use.
Next steps
- Installation: install on Kubernetes with the Helm chart.
- Clients: every way to register an application.
- Organizations: add tenants with their own issuers.