Users, sessions and identity

Anonymous visitors, signed-in users through a host JWT, sessions, context and what the model gets to see.

End users

Every person who opens the chat is an end user in your project. There are two kinds.

  • Anonymous visitor. identifyAnonymous() creates a visitor id (anon_…) and keeps it in the client’s token store. The default store is in memory, so pass a persistent KletsoTokenStore (for example backed by shared preferences) if conversations should survive app restarts. Needs no backend work.
  • Signed-in user. Your backend issues a short-lived host JWT for the logged-in user and the app passes it to authenticate(token:). The runtime verifies it with the HS256 secret or the JWKS URL configured in Settings → End-user auth (alg=none rejected, exp and nbf enforced, iss and aud when configured). The JWT’s sub becomes the external user id; name, email, plan, locale and tier claims are copied to the user’s traits. Tools marked act as user forward this token to your APIs in a header you choose.

Anonymous and signed-in identities are separate end users; a visitor who signs in starts with a fresh conversation list.

Sessions

The SDK opens a session with the publishable key: POST /v1/sessions returns a signed session token (kst_…, Ed25519), the end user, the published agent (id, version, greeting, allowed components), the theme, the URL allowlist and the realtime URL. Tokens live one hour; the SDK refreshes them, and an expired token can still be refreshed for 24 hours. Every request re-checks that the session is not revoked.

The publishable key encodes the environment, so one build talks to development and another to production without code changes.

Context

Context is a small map of facts about the user and the moment: plan, currency, locale, current screen, cart size. The SDK sends it at session start and updates it with setContext / updateContext. It is used in three places:

  • Prompt templates: {{ context.currency }} in the system prompt.
  • Trigger conditions: fire a rule only when context.plan == 'free'.
  • Tools: templates may read {{ context.* }} as well as {{ input.* }}.

The agent’s Behaviour tab lists public keys (rendered into the prompt and shown to the model) and sensitive keys (available to tools and rules only). A key that is on neither list does not reach the model.

What reaches the model provider

Only what a turn needs: the rendered system prompt, the last N messages of the conversation, tool specs, tool results and the user’s message. Kletso does not send your users’ identifiers to the provider unless you put them in the prompt. Model calls use your key, stored encrypted as a project secret.

Last updated 2026-09-28 · Report an issue with this page