Connect the gateway
Let Chat stream through obleth as each signed-in person, using short-lived tokens the gateway verifies against Chat's public keys.
3 min readUpdated for Chat 0.5.2Edit on GitHub
Chat never holds a gateway API key. For each request it signs a five-minute RS256 token whose subject is the person's internal account ID, and only Chat's server sends it. The gateway checks the token against Chat's public keys and accounts for the request under that identity, so every person has their own usage and fairshare position. See Identity tokens for the gateway side.
Set it up
setup.sh makes the signing key, configures Chat and prints the gateway entry, so with it only the last two steps are left: trust Chat in the gateway and check it.
- 1
Make a signing key
Generate a dedicated RSA key outside source control:
umask 077 openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 \ -out /secure/path/obleth-chat-signing.pem - 2
Configure Chat
Set the gateway's origin (without
/v1) and the key file. Both are needed, or neither.OBLETH_CHAT_GATEWAY_URL=http://obleth-gateway:8080 OBLETH_CHAT_GATEWAY_SIGNING_KEY_FILE=/secure/path/obleth-chat-signing.pem OBLETH_CHAT_GATEWAY_ISSUER=https://chat.example.edu OBLETH_CHAT_GATEWAY_AUDIENCE=oblethThe issuer defaults to
OBLETH_CHAT_ORIGINand the audience toobleth. Restart Chat; it publishes its public key at/.well-known/jwks.json. - 3
Trust Chat in the gateway
Merge this entry into the gateway's existing
OBLETH_JWT_ISSUERSarray (Helm:obleth.jwtIssuers), keeping any other issuers:{ "issuer": "https://chat.example.edu", "jwks_url": "http://obleth-chat:8085/.well-known/jwks.json", "audience": "obleth", "algorithms": ["RS256"], "subject_claim": "sub", "identity_claims": ["username"], "tenant": "chat-users", "jit_provision": true }Pick an existing tenant that has the models, budgets and policy Chat's users should get. If the tenant doesn't exist, the gateway creates it on the first request with default policy and raises an Identity tenant created alert. The issuer and audience must match Chat's exactly, and the gateway must be able to reach the JWKS URL. Plain HTTP is fine for an in-cluster URL.
Start Chat before you restart the gateway with the new entry. The gateway's log then shows
jwks loaded issuer=https://chat.example.edu. - 4
Check it
Sign in to Chat. The model picker lists the gateway's models, and Settings › Administration › Models shows the catalog to publish. See Models, groups and limits.
The picker shows every chat model the tenant may use, including internal ones such as a router classifier or a test model. Narrow the tenant's model allowlist in the gateway, or hide those models in Models.
What Chat sends
- Discovery:
GET /v1/models, live, filtered by the models each person may use. - Generation:
POST /v1/chat/completionswith the stored history, streaming with usage chunks. Chat recordsx-obleth-session-idandx-obleth-request-idwith each reply, so you can find its trace in the gateway's request logs. - Effort: the thinking effort as
reasoning_effort. With Auto, Chat sendsmodel: "auto"and tells the router how hard the request is: None and Low sendx-obleth-effort: low, High sendshigh, and Medium leaves the router to judge. - Embeddings: for Knowledge,
POST /v1/embeddingswith the embedding model.
Stopping a response cancels the upstream request. Chat follows no redirects from the gateway, so a bearer token can't be sent somewhere unexpected.
To show administrators a link to the gateway's dashboard, set OBLETH_CHAT_ADMIN_GATEWAY_URL to its public URL.
Several replicas and key rotation
Every Chat replica must use the same signing key and issuer. Chat publishes one key at a time; staged rotation with two keys isn't implemented yet. Replacing the key also makes saved connection tokens unreadable, because they're encrypted with a key derived from it, so people then enter them again.
How Chat users map to tenants
All Chat identities share the tenant in the issuer entry. Distinct token subjects give each person their own identity and accounting inside it. Chat adds its own per-person and per-group model access on top; Auto is limited by the tenant's allowlist and the gateway's Auto-eligible models.
In the gateway's keys and usage, each person appears as an identity key named <Chat account ID>-cli, with their Chat username in its identity claims ({"username": "…"}). The account ID is a UUID, not a name, so match keys to people through that username claim. Accounts created by OIDC sign-in get a generated username of the form oidc_<id>.
