Auth Container Overview
The Auth container is the runtime boundary for Authlance identity flows. It fronts Ory Kratos/Hydra, exposes API endpoints, runs the mail callbacks, and relays lifecycle events across Stripe and NATS. The service is distributed as a binary inside the Docker image and is deployed alongside Ory Kratos, Ory Hydra, MySQL, and NATS. Identity CRUD, consent, and OAuth token issuance are delegated to Kratos/Hydra while the Auth Container focuses on dashboard integration, session exchange, Stripe alignment, and emitting events that unblock worker fleets.
Architecture at a glance
+-------------+
| Dashboard |
+-------------+
|
| /authlance/**
v
+---------+ +---------------------+ +-----------+
| Kratos |<->| |<--->| NATS |
+---------+ | Auth Container | +-----------+
| Hydra |<->| - loopToken JWT | |
+---------+ | - mail relay | v
| - Stripe webhooks | +------------------+
+---------^-----------+ | Downstream |
| | Postmain/workers |
| +------------------+
|
+---------+
| Stripe |
+---------+
Requests coming from the dashboard land on /authlance/** routes, get authenticated, and fan out to Kratos/Hydra for identity guarantees. Stripe webhooks flow in the opposite direction, hitting the Auth Container first so it can persist data, emit NATS events, and notify downstream workers. Mail requests are published to Postmark via the relay so template rendering is centralized.
Core responsibilities
- Session exchange – Validates Kratos sessions and issues the short-lived JWT loopToken consumed by Authlance dashboards.
- Tenant bootstrap – Seeds users, groups, and subscriptions on first login (when autoCreateGroup is enabled) and enforces profile completeness toggles (gender/birth-date extras).
- Mail relay – Kratos courier posts to the internal
/authlance/identity/emailroutes exposed on themailAuth.port, and Authlance publishes those payloads to NATS for downstream delivery. The router is only reachable from within the cluster; it is not a public endpoint. - Payment webhooks – Accepts POST /authlance/payments/api/v1/stripe/webhook, validates signature headers, fan-outs events to the async workers, and publishes payment.success / payment.declined.
- Commands & automation – Ships CLI sub-commands (serve, backup, load-backup, stripe-webhook) for day-two tasks such as MySQL dumps and webhook provisioning.
- Event emission – Publishes user logins, subscription transitions, payment states, and license notifications to NATS so downstream services can react without polling.
Key routes
| Route | Method | Description |
|---|---|---|
/authlance/identity/me | POST | Exchanges a Kratos session ID for the Authlance JWT and sets the loopToken cookie. |
/authlance/identity/me/logout | GET | Clears the loopToken cookie and invalidates the browser session. |
/authlance/payments/api/v1/stripe/webhook | POST | Stripe webhook endpoint used to forward events into the async payment pipeline. |
All routes are mounted under the NGINX configuration shipped in the docker container, so the public paths match what the dashboard expects (/authlance/...).
Operational checklist
- Configuration – Populate
/app/config/config.yamlwith database credentials, Kratos/Hydra URLs, JWT signing key, NATS URL, Stripe webhook secret, and S3 settings. See the configuration guide for details. - Commands – Familiarize yourself with the CLI workflows (
serve,backup,load-backup,stripe-webhook) documented in the Auth Container Commands reference. - Events – Subscribe to the subjects described in Auth Container NATS Events to automate provisioning, billing, and observability.
- Secrets – Store sensitive values (JWT key, database password, Stripe credentials, S3 keys) in a secret manager or
.envfile consumed by the compose templates. - Monitoring – Tail the
authlancecontainer logs, monitor/healthz, and trackuser.authenticatedorsubscription.*events for real-time health signals.
Mail relay examples
Kratos courier (or any other internal system) issues basic-auth requests against http://authlance:<mailAuth.port>/authlance/identity/email. Those JSON payloads are validated, logged, and published to the mail.send subject on NATS. Downstream workers (e.g., Postmark relays) expect the SendEmailMessage contract:
{
"to": "sam@example.com",
"from": "Authlance <team@example.com>",
"templateId": "password-reset",
"templateModel": {
"email": "sam@example.com",
"name": {
"first": "Sam",
"last": "Wright"
},
"recovery_url": "https://dashboard.example.com/reset?token=abc",
"verification_url": "",
"recovery_code": "",
"verification_code": ""
}
}
Templates are React components in the authlance/mails repository. Each key inside templateModel becomes an injected prop so designers can preview emails locally and deploy them alongside the binary. Postmark delivers the final message, while Auth Container logs each relay and the subsequent NATS events for audit trails.
NATS event examples
Events are emitted to subjects like subscription.updated and payment.success. Consumers should subscribe with durable queue groups so retries are handled by NATS instead of reprocessing Stripe webhooks. Representative payloads:
// subscription.updated
{
"tierName": "pro",
"group": {
"id": 42,
"name": "redfruit"
},
"status": "active"
}
To know more details about all the events emitted check the NATS Events documentation.
Downstream workers typically hydrate these events with tenant metadata and trigger provisioning, feature unlocks, or license file regeneration. Keep handlers idempotent so replays are safe.
loopToken details
- Claims – Issued as a JWT that embeds the normalized user payload (identity ID, email, first/last name, roles, group memberships, verification state). It intentionally omits tenant metadata and feature flags so downstream services always re-fetch those from the API.
- Purpose – Used by UI widgets and API requests to prove a Kratos session was validated by Authlance. It is not a replacement for Hydra-issued OAuth tokens.
- Renewal – The dashboard silently calls
/authlance/identity/mewhen the cookie is close to expiring; Kratos sessions stay long-lived while loopToken rotates. - Third parties – Only first-party dashboards and services behind Authlance should rely on loopToken. External apps should use OAuth2/OIDC via Hydra or Personal Access Tokens.
Kratos and Hydra integration
Registration, login, password recovery, and OAuth consent all live inside Kratos/Hydra. The Auth Container fronts these services by validating browser sessions, owning the /authlance/** routes, and performing session exchange to mint loopToken plus dashboard-ready claims. This keeps the Kratos/Hydra APIs private while still letting the dashboard and workers rely on a consistent Authlance surface.
Personal access tokens
Automation can call the REST API using personal access tokens (PATs) instead of loopToken cookies. Admins create them under /authlance/identity/api/v1/pats, and every request is scoped by the personalAccessTokens.routeScopes configuration. The middleware enforces scopes before hitting controllers, so only the paths you list in the config can ever be reached with a PAT. Tokens are verified via /authlance/identity/api/v1/pats/verify which returns metadata (owner, group, scope, expiry) for auditing.
Common flows
- Login → session → loopToken – User completes the Kratos login UI, the dashboard calls
/authlance/identity/mewith the Kratos session cookie, and Authlance returns loopToken + the normalized user object for rendering. - User signup → tenant bootstrap – On the first login (with
autoCreateGroup=true), Authlance seeds the tenant, adds the user to the default group, enforces extra profile fields, and subsequently emitsuser.authenticatedto NATS so workers can react. - Subscription → Stripe webhook → NATS event – Checkout flows hit Stripe, the webhook posts to
/authlance/payments/api/v1/stripe/webhook, Authlance verifies the signature, updates MySQL, and publishespayment.success/subscription.updatedso downstream workers can provision seats or licenses.
Deployment notes
- The container runs NGINX and the Go binary side by side.
start-authlance.shlaunches both and terminates cleanly on signals. /app/configis expected to be a read-only mount. Docker Compose templates render it viaory-templatesand share the volume with the runtime container.- When deploying on Kubernetes, using a nginx Controller you can configure to have multiple replicas.
Use this overview as a primer, then jump into the dedicated configuration, commands, and events guides to wire up the container for your environment.