Self-Hosting
Auth Mode (Multi-User)
Deploy Gamut as a multi-user instance for teams. Users sign in with email/password or OIDC, and per-agent roles control who can view, use, or manage each agent.
When to choose this option
- Multiple people share one Gamut instance.
- Per-user accounts and audit trails are required.
- Gamut runs as shared team infrastructure.
For single-user deployments without authentication, see Single-User Docker.
Published image
Auth mode requires a dedicated image with the authentication frontend compiled in. AUTH_MODE=true is a compile-time build argument that enables the login UI and session management in the client.
ghcr.io/skillfulagents/superagent:main-auth
The -auth suffix is the key difference from the single-user image:
| Tag | Description |
|---|---|
main-auth | Latest build from the main branch with auth enabled. |
0.4.8-auth | Pinned release version with auth. |
0.4-auth | Latest patch in the 0.4.x line with auth. |
Quick start
Create a .env file:
ANTHROPIC_API_KEY=sk-ant-...
BETTER_AUTH_SECRET=your-random-secret-at-least-32-charactersCreate a docker-compose.yml:
services:
superagent:
image: ghcr.io/skillfulagents/superagent:main-auth
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${HOME}/.superagent:${HOME}/.superagent
environment:
- SUPERAGENT_DATA_DIR=${HOME}/.superagent
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- PORT=47891
- AUTH_MODE=true
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-}Start the container:
docker compose up -dOpen http://localhost:47891 in a browser and sign up. The first account created becomes the admin.
Environment variables
In addition to the standard environment variables, auth mode uses:
| Variable | Required | Default | Description |
|---|---|---|---|
AUTH_MODE | Yes | false | Must be true to enable authentication. |
BETTER_AUTH_SECRET | Recommended | Auto-generated | Secret key for signing session tokens. If unset, a random secret is generated and persisted to .auth-secret in the data directory. Set it explicitly for reproducible deployments or multiple replicas. |
TRUSTED_ORIGINS | Conditional | None | Comma-separated list of allowed origins for CORS and CSRF protection (e.g. https://superagent.example.com). Required behind a reverse proxy or custom domain. When unset, all origins are allowed. |
AUTH_PROVIDERS_JSON | No | None | JSON array configuring OIDC providers. See OIDC / social login. |
Authentication methods
Email and password
Email/password authentication is enabled by default. Users create an account with an email address and a password that meets the password policy.
OIDC / social login
Gamut supports any OpenID Connect (OIDC) identity provider: Google Workspace, Microsoft Entra ID, Okta, Auth0, Keycloak, and others. Providers are configured through the AUTH_PROVIDERS_JSON environment variable.
AUTH_PROVIDERS_JSON='[
{
"id": "google",
"type": "oidc",
"displayName": "Google",
"discoveryUrl": "https://accounts.google.com/.well-known/openid-configuration",
"clientId": "your-client-id.apps.googleusercontent.com",
"clientSecret": "your-client-secret",
"scopes": ["openid", "email", "profile"]
}
]'Each provider entry supports:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier for this provider. |
type | Yes | Must be oidc. |
displayName | No | Label shown on the login button. Defaults to id. |
discoveryUrl | Conditional | OIDC discovery endpoint URL. Required if issuer is not set. |
issuer | Conditional | Token issuer URL. Required if discoveryUrl is not set. |
clientId | Yes | OAuth client ID from your identity provider. |
clientSecret | No | OAuth client secret. Not required for PKCE-only flows. |
scopes | No | OAuth scopes to request. Defaults to the provider's standard scopes. |
icon | No | URL or path to a custom icon for the login button. |
enabled | No | Set to false to disable without removing the configuration. Defaults to true. |
All OIDC flows use PKCE (Proof Key for Code Exchange). Multiple providers can be configured; each appears as a separate button on the login screen.
First user becomes admin
The first user to sign up on a fresh instance is automatically promoted to the admin role. The promotion is atomic: it applies only if the user table has exactly one row after account creation. No special setup is needed to bootstrap the initial admin.
Role-based access control
Auth mode has two layers of roles: app-level roles for global permissions and agent-level roles for access to individual agents.
App-level roles
| Role | Capabilities |
|---|---|
| Admin | Full access to everything. Can manage users (ban, unban, promote, set passwords). Can access all agents regardless of agent-level roles. Can configure auth settings, signup modes, and password policies. |
| User | Can access only agents they have been explicitly granted a role on. Cannot manage other users or global settings. |
Agent-level roles
Each agent has its own access control list (ACL). Users are granted one of three roles per agent:
| Role | Capabilities |
|---|---|
| Owner | Full control over the agent. Can modify its configuration, manage its ACL (grant or revoke access for other users), and delete it. |
| User | Can interact with the agent: send messages, view sessions, trigger tasks. Cannot modify settings or manage the ACL. |
| Viewer | Read-only access. Can view sessions and history but cannot send messages or trigger actions. |
The hierarchy is strict: owner > user > viewer. A check requiring "user" access also passes for "owner", and a check requiring "viewer" passes for both.
When a user creates an agent, they are automatically assigned the owner role on it.
Signup and access control
Admins configure how new users join through the admin settings panel:
| Signup mode | Behavior |
|---|---|
| Invitation only (default) | Only admins can create new accounts. The sign-up page is disabled. |
| Open | Anyone can create an account by visiting the sign-up page. |
| Domain restricted | Only email addresses from specified domains (e.g., yourcompany.com) can sign up. |
| Closed | No new signups of any kind. |
Admin approval
When enabled, new signups are automatically banned with the reason "Pending admin approval" and cannot log in until an admin unbans them. Combined with open or domain-restricted signup, this gives admins a review step before granting access.
Disabling auth methods
Admins can independently enable or disable:
- Email/password authentication: disable to force OIDC-only login.
- Social/OIDC authentication: disable to force email/password-only login.
Password policy
The default policy requires:
- Minimum 12 characters (configurable).
- Maximum 128 characters (configurable).
- At least one uppercase letter, one lowercase letter, one number, and one symbol (complexity requirement, can be disabled).
The policy is enforced on both sign-up and password change.
Session management
| Setting | Default | Description |
|---|---|---|
| Session lifetime | 24 hours | Maximum session duration before forced re-authentication. |
| Idle timeout | 60 minutes | Session expires after this period of inactivity. |
| Max concurrent sessions | 5 | Oldest session is revoked when the limit is exceeded. |
Account lockout
After 10 consecutive failed login attempts (configurable), the account locks for 30 minutes (configurable). The lockout is per-email and resets on successful login.
User management
Admins manage users through the admin panel in the UI:
- View all users: email, role, status, and creation date.
- Ban / unban: prevent a user from logging in.
- Promote / demote: change a user's app-level role between admin and user.
- Set password: force a reset; the user must change their password on next login.
- Approve pending users: when admin approval is required, approve or reject new signups.
Data directory considerations
Auth mode can only be enabled on a fresh data directory or one that already has auth tables. Startup validation rejects an existing single-user data directory that contains agents, preventing orphaned agent data that no user owns. When migrating from single-user to auth mode, start with a clean data directory.
Docker Compose example
A complete production-ready docker-compose.yml with auth mode, OIDC, and trusted origins:
services:
superagent:
image: ghcr.io/skillfulagents/superagent:main-auth
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /data/superagent:/data/superagent
environment:
- SUPERAGENT_DATA_DIR=/data/superagent
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- PORT=47891
- AUTH_MODE=true
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- TRUSTED_ORIGINS=https://superagent.example.com
- AUTH_PROVIDERS_JSON=${AUTH_PROVIDERS_JSON:-}Limitations
- Auth mode does not apply to the Electron desktop app. It runs in web/container deployments (Docker, Kubernetes) only. If
AUTH_MODE=trueis set in an Electron environment, it is ignored with a warning. - OIDC providers are configured at deployment time. Provider credentials are passed through environment variables, not the admin UI, keeping secrets out of the application database.
Next steps
- Single-User Docker: Simpler deployment without authentication.
- Electron Desktop App: Run Gamut as a native desktop application.