Keycloak-based authentication for the Gryt voice chat platform.
Centralized identity management, SSO, and token-based auth.
This repository is open source for transparency — you are not expected to host this yourself.
Gryt uses a single auth service at auth.gryt.chat. All users authenticate through it regardless of which server they connect to. This ensures identities are consistent and verifiable across the entire network — if anyone could run their own auth service, they could impersonate any user.
- Server hosts — Your server validates tokens against
auth.gryt.chat. No auth setup required. - Users — Sign up once, your identity works on every Gryt server.
- Contributors — This repo is open so you can audit and contribute. The dev setup below is only needed for working on auth itself.
| Component | Description |
|---|---|
| Keycloak | Identity provider with custom Gryt realm and themes |
| Identity | Certificate authority that binds Keycloak identities to client public keys (details) |
| HAProxy | Reverse proxy for production TLS termination |
| Bootstrap | One-shot containers that bring a fresh Keycloak into a usable state (details) |
| Ops | Backup/restore tooling for the Postgres database |
Only needed if you're contributing to the auth service itself.
cp .env.example .env
./up.shStarts a local Keycloak instance via Docker Compose — completely separate from production.
Four one-shot containers run around the Keycloak server, in this order. All of them exit immediately and are safe to re-run.
| Service | What it does |
|---|---|
keycloak-pre-import-backup |
Dumps Postgres to ./backups before an import can overwrite anything. Only when GRYT_IMPORT_REALM=1. |
keycloak-import |
Imports realm/gryt-realm.json, substituting SMTP settings. Only when GRYT_IMPORT_REALM=1. --override true deletes the realm first — every user in it goes too. Refuses to run while Keycloak is up; stop it first. |
keycloak-bootstrap-admin |
Creates the master-realm admin if there isn't one. |
keycloak-user-profile |
Applies bootstrap/gryt-user-profile.json through the admin API, once the server is up. |
Two things about this are worth knowing before you change any of it.
The import is an offline operation. kc.sh import rewrites the database directly, and a
running Keycloak goes on holding the realm id it started with — so importing underneath one
leaves it serving 500s until it is restarted, with every user in the realm already gone. It is
easy to do by accident, because docker compose up -d re-runs a one-shot whose config changed
without restarting keycloak, whose own definition did not. import_realm.sh checks for a
listening server and refuses. To import deliberately:
docker compose -f docker-compose.keycloak.yml stop keycloak
docker compose -f docker-compose.keycloak.yml up -dThe admin is not created by KC_BOOTSTRAP_ADMIN_* alone. Keycloak only does that
when start finds no master realm, and keycloak-import creates master as a side
effect of running first. On a genuinely fresh database that left a deployment with no
administrator at all, which is why keycloak-bootstrap-admin exists.
The user profile has to go through the admin API. A userProfile block in the
realm JSON is rejected on import and takes the whole stack down. Without the profile,
the realm falls back to Keycloak's built-in one, which requires firstName and
lastName — and since the realm sets registrationEmailAsUsername and the login theme
hides both fields, registration then fails on inputs nobody can see.
bootstrap/gryt-user-profile.json is the source of truth for what registration
collects. Editing the profile in the admin console works until the next time this runs.
Note that docker compose up -d will not re-run a one-shot that has already exited, so
after a realm import you need up.sh, or:
docker compose -f docker-compose.keycloak.yml up -d --force-recreate --no-deps keycloak-user-profileSee the architecture overview for how auth fits into the Gryt platform.
Please report bugs and request features in the main Gryt repository.