App Credentials
Copy page
How app credentials authenticate end-users, including anonymous sessions, authenticated chat sessions with asymmetric key verification, domain validation, and Proof-of-Work protection.
App credentials are the auth mechanism for chat components. This page covers the underlying auth flow, security model, and advanced configuration.
How anonymous authentication works
When your widget loads, it authenticates through a two-step flow:
- Get a session token — the widget calls
POST /run/auth/apps/{appId}/anonymous-session. The server validates the requestOriginagainst the app's allowed domains and returns a JWT. - Use the token — subsequent chat requests include the JWT and App ID:
Each session gets a unique anonymous user ID (anon_<uuid>), enabling per-user conversation history.
To refresh a token while preserving the same anonymous identity, include the existing token as an Authorization: Bearer header when requesting a new session. If the token is valid, the server reuses the same user ID (sub claim) and issues a fresh token with a new 30-day expiry. If the token is invalid, expired, or belongs to a different app, a new anonymous identity is created as usual.
Authenticated chat sessions
In addition to anonymous sessions, apps can be configured for authenticated chat sessions. Your backend signs JWTs with a private key, and Inkeep verifies them using the corresponding public key you upload. This gives each session a verified user identity tied to your system's user IDs.
How it works
Generate a key pair — create an asymmetric key pair (RSA, EC, or EdDSA) on your infrastructure.
Upload the public key — register the public key with your app via the API or Visual Builder. Inkeep never sees your private key.
Sign JWTs on your backend — when a user starts a chat session, your server signs a JWT containing the user's identity.
Widget sends the signed JWT — pass a getAuthToken function in baseSettings that fetches a token from your backend route. The widget calls it automatically and includes the JWT as a Bearer token instead of requesting an anonymous session.
Inkeep verifies the signature — the server matches the kid header to a stored public key, verifies the signature, and extracts the user identity from the sub claim.
JWT requirements
| Field | Location | Required | Description |
|---|---|---|---|
kid | Header | Yes | Must match the kid of an uploaded public key |
sub | Payload | Yes | User identifier — becomes the userId for the session |
exp | Payload | Yes | Expiration time, max 24 hours from iat |
iat | Payload | Yes | Issued-at time, must be within 60 seconds of server time |
Supported algorithms
| Family | Algorithms |
|---|---|
| RSA | RS256, RS384, RS512 |
| ECDSA | ES256, ES384, ES512 |
| EdDSA | EdDSA (Ed25519) |
RSA keys must be at least 2048 bits. Private keys are rejected at upload time — only public keys are accepted.
Enforcing authentication
New apps require authenticated sessions by default. If a signed JWT is missing or verification fails, the request is rejected with a 401 Unauthorized response.
To allow anonymous sessions (e.g., for public-facing widgets that don't require user identity), disable Require Authentication in the app edit dialog. When disabled, requests without a valid JWT fall back to anonymous authentication instead of being rejected.
Verified claims
Non-standard claims in the signed JWT (beyond sub, iat, exp, aud, iss, jti, nbf) are extracted and made available as verified claims in the conversation context. These are cryptographically signed and kept separate from unverified userProperties sent by the client.
Verified claims are limited to 1KB. Tokens with custom claims exceeding this limit are rejected.
Key management
Manage public keys from the app edit dialog in the Visual Builder. Navigate to Apps → click the ⋯ menu on your Web Client app → Edit, then scroll to the Authentication Keys section.
From here you can add, view, copy, and delete public keys. Each key requires:
| Field | Description |
|---|---|
| Key ID (kid) | A unique identifier for this key (e.g. my-key-1). Must match the kid header in your signed JWTs. |
| Algorithm | Select from the available algorithms listed in the UI. Must match your key pair. |
| Public Key (PEM) | The PEM-encoded public key, starting with -----BEGIN PUBLIC KEY-----. |
You can register multiple public keys per app. Use this for key rotation — upload a new key before retiring the old one.
Below the keys section, the Audience (aud) field lets you require that signed JWTs include a matching aud claim. When set, tokens without a matching audience are rejected. See Enforcing authentication for the Require Authentication toggle.
Security Model
| Feature | Details |
|---|---|
| Domain allowlist | Origin header validated against the app's allowedDomains at token issuance |
| Scoped access | Each app is bound to a default agent via defaultAgentId |
| Captcha | Proof-of-Work challenges prevent automated abuse |
| Anonymous identities | Each anonymous session gets a unique user ID for per-user conversation history |
| Authenticated identities | User ID from verified sub claim when using signed JWTs |
| Auth enforcement | New apps require authentication by default; disable Require Authentication to allow anonymous sessions |
| Token expiry | Anonymous session tokens default to 30 days; authenticated tokens max 24 hours |
| Rolling refresh | Include existing anonymous token when requesting a new session to preserve identity with a fresh expiry |
| Verified claims | Non-standard JWT claims from authenticated sessions available in conversation context |
App Credentials vs API Keys
| App Credentials | API Keys | |
|---|---|---|
| Use case | Browser / client-side | Server-to-server |
| Exposed to end-users | Yes (App ID only) | No (secret) |
| Domain restrictions | Yes | No |
| Per-user identity | Yes (anonymous or authenticated) | No |
| Default agent | One agent (via defaultAgentId) | One agent per key |
Related
- Chat Components — widget setup and configuration
- Chat API — low-level streaming API details
- Apps API Reference — CRUD operations for app management
- Auth API Reference — session and PoW challenge endpoints