Integrated Auth

AI Chat is installed inside your ServiceStack App, so it doesn't need a separate user directory, a second login experience or a new identity silo. Existing users sign in with the account they already have, and every user-facing capability is scoped to that identity.

Choosing an AuthType

services.AddPlugin(new ChatFeature {
    RequireAuth = true,
    AuthType = ChatAuthType.Credentials,
});
ChatAuthType Sign-in experience Requires
Credentials (default) Username/password form rendered inside the Chat UI AuthFeature with CredentialsAuth(), or Identity Auth
OAuth Redirects to the host's Identity login page at SignInUrl ASP.NET Identity Auth
ApiKey GET /auth with an Authorization: Bearer header ApiKeysFeature

Credentials

The credentials extension replaces the stock sign-in component with a username/password form that authenticates through ServiceStack's Authenticate API - so it signs in against your existing ASP.NET Identity users and shares the App's auth cookie. User management stays with the host (Identity's Admin Users UI), not a separate users file.

OAuth

Use when your App already has a branded Identity login page and you'd rather send users to it:

services.AddPlugin(new ChatFeature {
    AuthType = ChatAuthType.OAuth,
    SignInUrl = "/Account/Login",
});

The identity extension swaps the sign-in component for a redirect, and the Chat UI then rides the host's Identity Auth cookie.

API Keys

Programmatic clients and MCP Assistants authenticate with a ServiceStack API key in the Bearer token:

services.AddPlugin(new ApiKeysFeature());
services.AddPlugin(new ChatFeature { AuthType = ChatAuthType.ApiKey });

API keys are resolved on every Chat request regardless of AuthType, because Chat UI routes bypass the ApiKeysFeature request filter - so an API key is always a valid way in, including to /chat/mcp. Each key carries its own roles, permissions and expiry. See API Keys.

Restricting access

services.AddPlugin(new ChatFeature {
    RequireAuth = true,
    RequiredRole = "Employee",
});

RequiredRole gates the entire Chat UI and its APIs. Users in the Admin role always satisfy RequiredRole.

Open access

services.AddPlugin(new ChatFeature { RequireAuth = false });

With auth disabled every request runs as the "default" user, all state is stored under App_Data/chat/user/default, and ctx.IsAdmin() returns true for everyone. This matches llms.py's behaviour with no auth extension installed and is appropriate for a single-user or trusted-network deployment only.

Per-user isolation

Authentication is the boundary for AI Chat's state. Everything below is scoped to the authenticated identity:

  • Conversation threads and history
  • Generated images, audio and media
  • Agent Profile customizations
  • Projects and their allowed directories
  • Personal Skills and preferences
  • Gemini File Stores and document catalogs
  • PDF Studio workspaces
  • Provider and model preferences

One user's working context never becomes another user's prompt history or project filesystem. Shared and administrator-managed capabilities are explicit rather than emerging from a common global workspace.

Database rows carry the username in a user column (ChatThread, ChatRequest, ChatMedia), and file storage is partitioned at App_Data/chat/user/{username}/.

Agents act as the signed-in user

This is the property that makes AI Chat safe to point at a real application. API Tools search, describe and invoke ServiceStack APIs within the current request and authenticated identity:

  • APIs the user cannot access are omitted from search results.
  • They cannot be described.
  • They cannot be called.
  • Existing authentication requirements, API-key rules, roles, permissions, claims and scopes remain enforced.

Calls are deserialized into the real Request DTO and executed through ServiceStack's in-process Service Gateway, so DTO validation, Service filters and business rules stay authoritative.

An Assistant cannot reach an API merely because the server process could.

Request validation

ValidateRequest runs before every Chat UI and API request, giving you one place to add quotas, tenancy checks or policy:

services.AddPlugin(new ChatFeature {
    ValidateRequest = async req => {
        var session = await req.GetSessionAsync();
        if (session.UserAuthId != null && await IsSuspendedAsync(session.UserAuthId))
            return HttpError.Forbidden("AI access suspended");
        return null;   // null = allow
    },
});

Anonymous routes

A small number of routes answer anonymously because the UI needs them before it knows whether anyone is signed in:

/chat/config exposes provider ids, their enabled/disabled state and default model names to anonymous callers. Everything else - threads, media, tools, API discovery - requires an authenticated request that satisfies RequireAuth and RequiredRole.

Administration

Admin users get system-wide visibility through role-protected Admin UIs at /admin-ui/chat, whilst ordinary users retain their own scoped experience. See Analytics & Admin.

Because AI Chat has no user store of its own, account lifecycle - password policy, lockouts, roles, deactivation - remains owned by your App and applies to AI Chat immediately.

The boundaries, stated plainly

Question Answer
Where does conversation data live? Your App's database via OrmLite, and App_Data/chat on your server
Who can reach /chat? Whoever RequireAuth and RequiredRole allow - enforced by your existing auth
Can one user see another's threads, media or projects? No. Admin cross-user access is explicit and role-gated
What can an Agent call? Only APIs the signed-in user is authorized to call
Can it write to the filesystem or run code? Only if you enable those tools, and only within configured project directories
What is exposed over MCP? Nothing until you name tool groups; tools needing interactive approval are rejected by default
Does any of it require an outbound AI provider? Only the providers you configure

Which providers see your prompts is entirely your decision - including "none outside this network" if you point AI Chat at a local Ollama or LM Studio endpoint.