Configuration.
Every setting the server reads, what it does, and what happens if you leave it alone. Most deployments touch fewer than ten.
How settings are spelled
Configuration comes from appsettings.json under a Bakn
section, or from environment variables — which is what a container deployment uses.
The two spellings map onto each other: nesting becomes a double underscore.
Bakn:Oidc:ClientId (json)
Bakn__Oidc__ClientId (environment)
Arrays are indexed: Bakn__CorsOrigins__0,
Bakn__CorsOrigins__1. Environment variables win over the file.
Never put a secret in appsettings.json. That file ships inside the public
container image, so anything written there is shared by every operator of that image and
readable by anyone who pulls it. Secrets belong in the environment.
Core
| Setting | Default | What it does |
|---|---|---|
Database | — | Connection string. A postgresql:// URL or Npgsql keywords for Postgres; Data Source=/data/bakn.db for SQLite. Empty means in-memory, which loses everything on restart. |
DatabaseProvider | auto |
postgres, sqlite, or auto to infer from the connection string's shape. Say it explicitly in production: a malformed string then fails loudly instead of quietly starting on the other provider. |
FileStorePath | bakn-files |
Directory for attachments. Ignored when Spaces is configured. Must be on a volume that survives redeploys. |
SeedDemoData | false |
Creates a demo channel at startup. Development only. |
Accounts and access
| Setting | Default | What it does |
|---|---|---|
AllowSelfRegistration | unset | Operator override for POST /auth/register. Unset defers to the admin-editable setting in the app, which starts open. Set false to close it before the server ever accepts a request; an admin then cannot re-open it. Does not affect SSO. |
DefaultAdmin:UserName | Admin |
Name of the bootstrap admin account. |
DefaultAdmin:Password | — | Applied on the first start only, while that account has no password. Changing it later does nothing. No default ships, deliberately. |
AdminUserNames | empty | Usernames granted admin authority, resolved to user ids at startup. |
MinPasswordLength | 10 |
Minimum length for password registration and changes. |
TokenLifetimeDays | 7 |
Session token lifetime. |
AccessTokenLifetimeHours | unset | Shortens the access token independently of the session, if you want refreshes to happen more often. |
RefreshTokenLifetimeDays | 30 |
How long a client can stay away and still refresh rather than sign in again. |
MaxSocketsPerUser | 5 |
Concurrent realtime connections per account — roughly, devices. |
Single sign-on
Full walkthrough on the SSO page.
| Setting | Default | What it does |
|---|---|---|
Oidc:Authority | — | Issuer URL. Discovery is resolved from it. |
Oidc:ClientId | — | Client id at the provider. SSO enables once this and Authority are both set. |
Oidc:ClientSecret | — | For confidential clients. Omit for public ones; PKCE is always used. |
Oidc:Scopes | openid profile email | Scopes requested. |
Oidc:ProviderDisplayName | SSO | Label on the client's sign-in button. |
Oidc:PublicBaseUrl | request host | This server's external URL, used to build the redirect URI. Set it behind a proxy — otherwise the server derives an internal address the provider will reject. |
Oidc:AdminRoleClaim | — | Claim consulted for admin membership, e.g. roles. |
Oidc:AdminRoleValue | — | Value in that claim which grants admin. With both set, the provider is authoritative on every sign-in. |
Oidc:AllowedRedirectSchemes | bakn | URI schemes the post-login redirect into the app may use. Loopback is always allowed, for the desktop client. |
Network and TLS
| Setting | Default | What it does |
|---|---|---|
TrustedProxies | empty | Required behind a reverse proxy. Without it every request appears to come from the proxy, so per-IP rate limiting collapses into one shared bucket and failed-login lockout keys on the proxy — meaning anyone can lock out any account. 172.16.0.0/12 covers Docker's bridge ranges. |
RequireHttps | auto | Set false when a proxy terminates TLS and forwards plain HTTP; the proxy should issue the redirect instead. |
CorsOrigins | empty | Browser origins allowed to call the API. Not needed for the desktop and mobile clients. |
Calling
| Setting | Default | What it does |
|---|---|---|
Turn:Uris | — | TURN URIs handed to clients. Must be publicly resolvable — an internal Docker name yields zero usable candidates rather than an error. |
Turn:StaticAuthSecret | — | Shared secret with coturn. The server derives per-user, time-limited credentials from it, so coturn needs no user database. |
Turn:CredentialTtlMinutes | 60 | Lifetime of an issued TURN credential. |
IceServers | empty | Additional static ICE servers, if you are not using the derived-credential path. |
Files, retention and scanning
| Setting | Default | What it does |
|---|---|---|
PerUserDailyUploadQuotaBytes | 250 MB | Per-account upload allowance per day. |
AllowedUploadContentTypes | unset | Allow-list of MIME types. Unset permits anything the type sniffer accepts. |
Retention | unset | TTLs for messages, sessions and orphaned files. Unset keeps everything forever. |
ClamAv | unset | Address of a ClamAV daemon to scan uploads through. |
Spaces:* | unset | S3-compatible attachment storage — ServiceUrl, Bucket, AccessKey, SecretKey, Region, Prefix. Configuring it replaces the local file store. ServiceUrl is the regional endpoint and must not include the bucket. |
Observability and clients
| Setting | Default | What it does |
|---|---|---|
JsonConsoleLogs | false | Structured JSON logs, for a log collector. |
MetricsEnabled | false | Exposes a Prometheus endpoint. |
MetricsToken | — | Bearer token required to scrape it. Set one if the endpoint is reachable off-box. |
OtlpEndpoint | — | OTLP collector for traces. |
SignaturePolicy | AcceptUnsigned | How strictly message signatures are enforced. |
LatestClientVersion | — | Advertised by /api/v1/version so clients can offer an update. |
MinimumClientVersion | — | Oldest supported client. Advisory: the version arrives in a caller-supplied header, so it explains a failure rather than preventing one. |
Checking what took effect
Two anonymous endpoints report the settings that are visible from outside:
curl https://chat.example.com/api/v1/version
curl https://chat.example.com/api/v1/auth/config
/auth/config answers whether registration is open and whether SSO is
enabled — which is the fastest way to tell a server that is not configured from a client
that is not asking.