Hardening Open WebUI
Open WebUI is a self-hosted application built for private, trusted networks. It gives authenticated users access to powerful capabilities including model inference, tool execution, and code pipelines. The security model assumes that anyone who can reach the instance has been intentionally granted access by an administrator.
This guide covers the configuration options available for hardening your deployment. Each section explains what a setting does, what the default is, and how to change it. It is not an exhaustive security guide, and securing your deployment is ultimately your responsibility. Your environment and threat model will determine which of these are relevant to you.
Open WebUI is built for private, trusted networks. While it can be made accessible over the public internet, doing so means relying solely on application-level authentication to protect access to your models, tools, and data. If you do expose it publicly, at minimum you should place it behind a VPN (WireGuard, Tailscale), a zero-trust proxy (Cloudflare Access, Pomerium), or a reverse proxy with authentication and IP allowlisting.
DDoS protection and brute-force prevention (rate limiting on login endpoints, connection throttling, fail2ban) should also be handled at the proxy or network layer.
If you are deploying Open WebUI for the first time, start with the Quick Reference at the bottom of this page for a prioritized summary, then read the sections relevant to your setup.
Secret Key
The WEBUI_SECRET_KEY is used to sign JWTs (login tokens) and derive encryption keys for OAuth session data.
How the default works:
When running via Docker (start.sh) or open-webui serve, the application checks whether WEBUI_SECRET_KEY is set as an environment variable. If it is not, a random key is generated automatically and saved to .webui_secret_key inside the data directory. On subsequent restarts, the saved key is reloaded. This means that for single-instance deployments, no manual configuration is needed.
When you need to set it explicitly:
If you run multiple Open WebUI instances behind a load balancer, every instance must share the same key. Otherwise, a token signed by one instance will be rejected by another, causing login failures. Generate a key with openssl rand -base64 32 and pass it as an environment variable to all replicas.
Rotation: Changing the key invalidates all existing sessions. Users will need to sign in again.
Authentication and Signup
Registration
By default, signup is open and the first user to register becomes the administrator. After your admin account exists, you can control registration:
# Disable new signups entirely
ENABLE_SIGNUP=falseIf you want to allow signups but require manual approval, leave signups enabled and rely on the default user role:
# New users are placed in "pending" status until an admin approves them (this is the default)
DEFAULT_USER_ROLE=pendingPassword validation
Open WebUI does not enforce password complexity by default. To enable it:
ENABLE_PASSWORD_VALIDATION=true
PASSWORD_VALIDATION_REGEX_PATTERN='^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$'
PASSWORD_VALIDATION_HINT='Minimum 8 characters with uppercase, lowercase, number, and special character.'Passwords are hashed with bcrypt before storage. Bcrypt truncates inputs at 72 bytes, and Open WebUI enforces this limit.
Admin account from environment variables
For automated deployments, you can create the admin account at startup:
WEBUI_ADMIN_EMAIL=admin@yourcompany.com
WEBUI_ADMIN_PASSWORD=your-strong-password
WEBUI_ADMIN_NAME=AdminThis only takes effect when no users exist in the database. Once the admin is created, signup is automatically disabled.
SSO-only environments
If all authentication is handled by an OAuth/OIDC provider, you can hide the local login form entirely:
ENABLE_LOGIN_FORM=falseThis removes the email/password form from the UI, steering all users through your SSO flow. You can also disable local password authentication at the backend level:
ENABLE_PASSWORD_AUTH=falseSession and Cookie Security
Cookie settings
When serving Open WebUI over HTTPS (see HTTPS Configuration), configure cookies accordingly:
WEBUI_SESSION_COOKIE_SECURE=true
WEBUI_SESSION_COOKIE_SAME_SITE=strict| Variable | Default | What it does |
|---|---|---|
WEBUI_SESSION_COOKIE_SECURE | false | When true, cookies are only sent over HTTPS connections. |
WEBUI_SESSION_COOKIE_SAME_SITE | lax | Controls whether cookies are sent with cross-site requests. strict offers the most protection. |
These also apply to OAuth cookies unless overridden with WEBUI_AUTH_COOKIE_SECURE and WEBUI_AUTH_COOKIE_SAME_SITE.
Token expiry
JWTs control how long a user stays logged in. The default is 4w (4 weeks). You can shorten this:
JWT_EXPIRES_IN=24hSetting JWT_EXPIRES_IN=-1 disables token expiration entirely. Open WebUI will log a warning if this is set.
Token revocation
With Redis configured, Open WebUI supports per-token revocation. When a user signs out, their token is added to a revocation list that auto-expires. Without Redis, tokens remain valid until they expire naturally.
CORS
Cross-Origin Resource Sharing (CORS) controls which websites can make requests to your Open WebUI API from a browser. For example, if your Open WebUI instance is at https://chat.yourcompany.com, CORS determines whether a script running on a different domain can interact with it.
The default CORS_ALLOW_ORIGIN is *, which allows any origin. Open WebUI logs a warning at startup when this is the case.
To restrict it to your domain:
CORS_ALLOW_ORIGIN=https://chat.yourcompany.comMultiple origins are separated with semicolons:
CORS_ALLOW_ORIGIN=https://chat.yourcompany.com;https://internal.yourcompany.comIf you use a desktop app with a custom URL scheme, add it via:
CORS_ALLOW_CUSTOM_SCHEME=appSecurity Headers
Open WebUI includes a SecurityHeadersMiddleware that injects HTTP security headers into responses. None are set by default, so you opt in to each one via environment variables.
The following is a recommended starting configuration for production deployments:
# HTTP Strict Transport Security: tells browsers to only use HTTPS
HSTS=max-age=31536000;includeSubDomains
# Prevents the page from being embedded in iframes on other sites
XFRAME_OPTIONS=DENY
# Prevents browsers from MIME-type sniffing
XCONTENT_TYPE=nosniff
# Controls how much referrer information is sent with requests
REFERRER_POLICY=strict-origin-when-cross-origin
# Restricts access to browser features
PERMISSIONS_POLICY=camera=(),microphone=(),geolocation=()
# Content Security Policy
CONTENT_SECURITY_POLICY=default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'If you set a Content Security Policy, start permissive and tighten incrementally. An overly strict CSP will break the frontend. Browser dev tools will show you which resources are being blocked.
HTTPS and TLS
Open WebUI does not terminate TLS itself. Place it behind a reverse proxy (Nginx, Caddy, HAProxy) that handles HTTPS. See the HTTPS Reference for step-by-step proxy configurations.
Once HTTPS is in place:
WEBUI_SESSION_COOKIE_SECURE=true
HSTS=max-age=31536000;includeSubDomainsTrusted proxy IPs
Open WebUI uses --forwarded-allow-ips to determine which proxies are trusted to send X-Forwarded-For headers. By default, this is set to * (trust all), which is appropriate when Open WebUI is on an isolated network behind a single reverse proxy. If your network topology is more complex, restrict it to your proxy's IP:
FORWARDED_ALLOW_IPS=192.168.1.100OAuth and SSO
If you use an OAuth/OIDC provider for authentication, several options help you control access.
Domain and group restrictions
# Only allow users with email addresses from specific domains
OAUTH_ALLOWED_DOMAINS=yourcompany.com
# Block specific IdP groups
OAUTH_BLOCKED_GROUPS='["contractors-external", "temp-accounts"]'Role mapping
Map IdP roles to Open WebUI roles so access is managed at the identity provider:
ENABLE_OAUTH_ROLE_MANAGEMENT=true
OAUTH_ROLES_CLAIM=roles
OAUTH_ADMIN_ROLES=admin,superadmin
OAUTH_ALLOWED_ROLES=user,admin,superadminAccount merging
OAUTH_MERGE_ACCOUNTS_BY_EMAIL=falseWhen enabled, an OAuth login with an email matching an existing local account will merge the two. This is convenient but depends on your OAuth provider reliably verifying email addresses. If your provider does not guarantee email verification, a user who controls a matching email could gain access to the existing account.
Session limits
# Maximum concurrent OAuth sessions per user per provider (default: 10)
OAUTH_MAX_SESSIONS_PER_USER=5
# Enable IdP-initiated back-channel logout (requires Redis)
ENABLE_OAUTH_BACKCHANNEL_LOGOUT=trueTrusted Header Authentication
If your reverse proxy handles authentication (Authelia, Authentik, oauth2-proxy), you can pass the authenticated identity to Open WebUI via HTTP headers:
WEBUI_AUTH_TRUSTED_EMAIL_HEADER=X-Forwarded-Email
WEBUI_AUTH_TRUSTED_NAME_HEADER=X-Forwarded-NameWhen using trusted headers, your proxy must strip these headers from incoming client requests before injecting its own values. If the proxy does not strip them, any client can send a forged header and authenticate as any user. This is the most common misconfiguration with trusted header auth. Consult your proxy's documentation for how to strip upstream headers.
LDAP
When using LDAP for authentication, enable TLS to protect credentials in transit:
ENABLE_LDAP=true
LDAP_USE_TLS=true
LDAP_VALIDATE_CERT=true
LDAP_CA_CERT_FILE=/path/to/ca-cert.pemWithout TLS, LDAP credentials are transmitted in plaintext. You can restrict cipher suites with LDAP_CIPHERS if needed.
Database
PostgreSQL
For production deployments, PostgreSQL provides better concurrency and reliability than the default SQLite:
DATABASE_URL=postgresql://user:password@db-host:5432/openwebuiSee the Scaling Guide for migration details. Use strong, unique credentials and keep the database on an internal network.
SQLCipher
For SQLite deployments that need encryption at rest, Open WebUI supports SQLCipher:
DATABASE_TYPE=sqlite+sqlcipherConnection pool tuning
For PostgreSQL, tune the connection pool to match your usage:
DATABASE_POOL_SIZE=15
DATABASE_POOL_MAX_OVERFLOW=20
DATABASE_POOL_TIMEOUT=30
DATABASE_POOL_RECYCLE=3600Total connections across your deployment = pool size x number of instances. Keep this below your PostgreSQL max_connections limit (default 100).
API Keys
API keys provide programmatic access to Open WebUI with the same permissions as the user who created them.
# Enable API key creation (default: disabled for non-admin users)
ENABLE_API_KEYS=trueEndpoint restrictions
You can limit which API routes a key is allowed to call:
ENABLE_API_KEYS_ENDPOINT_RESTRICTIONS=true
API_KEYS_ALLOWED_ENDPOINTS=/api/chat/completions,/api/v1/modelsThis is useful when distributing keys to external services or automations, where you want to limit what a compromised key can access.
User permissions
By default, only admins can create API keys. To allow regular users:
USER_PERMISSIONS_FEATURES_API_KEYS=trueAccess Control
Open WebUI uses a layered permission system with roles, groups, and per-resource access grants.
Roles
| Role | Capabilities |
|---|---|
admin | Full system access, user management, all configuration |
user | Chat access, permitted models and resources |
pending | No access until approved by admin |
Key settings
# Default role for new users (default: pending)
DEFAULT_USER_ROLE=pending
# Whether admins bypass resource-level access control (default: true)
BYPASS_ADMIN_ACCESS_CONTROL=true
# Whether admins can view all user chats (default: true)
ENABLE_ADMIN_CHAT_ACCESS=true
# Whether all users can access all models regardless of group restrictions (default: false)
BYPASS_MODEL_ACCESS_CONTROL=falseData sharing and export
Several features control how data can be shared or exported:
# Allow users to share chats with other authenticated users (default: true)
ENABLE_COMMUNITY_SHARING=true
# Allow admins to bulk export all user chats from the database (default: true)
ENABLE_ADMIN_EXPORT=true
# Allow users to connect directly to model providers with their own API keys,
# bypassing the server-side proxy (default: false)
ENABLE_DIRECT_CONNECTIONS=falseENABLE_COMMUNITY_SHARING lets users generate share links for their chats. Any authenticated user with the link can view the chat. If your deployment contains sensitive conversations, consider setting this to false.
ENABLE_DIRECT_CONNECTIONS, when enabled, allows users to configure their own API keys and model endpoints in the browser. These connections are made from the backend, so the user's API key is sent to the Open WebUI server. This is off by default.
Workspace permissions
These settings control what regular users can do in the shared workspace:
USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS=false
USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS=false
USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS=false
USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS=falseAll default to false. Group-level overrides can enable specific permissions for specific user groups.