Set up the file
The environment variables are used to configure the application. We will use a .env file to store the variables.
For the sample environment file, see the example .env file.
The variables are split up into the following sections:
Required variables
General URLs
This section will cover all the variables related to the general URLs.
| Name |
Description |
KANEO_CLIENT_URL |
The URL of the web application. |
KANEO_API_URL |
The URL of the API. |
Database
This section will cover all the variables related to the database.
| Name |
Description |
DATABASE_URL |
The full PostgreSQL connection string, in the format postgresql://[user]:[password]@[host]:[port]/[database]. Example: postgresql://kaneo:kaneo@localhost:5432/kaneo. The user/password/database must match the POSTGRES_* values below. |
POSTGRES_DB |
The name of the PostgreSQL database. Example: kaneo. |
POSTGRES_USER |
The username for the PostgreSQL database. Example: kaneo. |
POSTGRES_PASSWORD |
The password for the PostgreSQL database. Use a strong value in production. |
Authentication
This section will cover all the variables related to the authentication.
| Name |
Description |
AUTH_SECRET |
The secret key for the JWT token. Must be at least 32 characters long, use a long, random value in production. Example: use openssl rand -base64 32 to generate a secure key in Linux/macOS. |
DEVICE_AUTH_CLIENT_IDS |
Optional. Comma-separated list of allowed device authorization client IDs. When unset, Workboard implicitly allows workboard-cli and workboard-mcp by default, so no extra configuration is required for the CLI or MCP. Override only when you need additional trusted clients, for example workboard-cli,workboard-mcp,my-desktop-app. |
Optional variables
MCP
| Name |
Description |
Default |
KANEO_INTERNAL_API_URL |
API origin used only for server-side requests from the built-in HTTP MCP endpoint. Override it only if the API is not reachable at the default loopback address from its own process. |
http://127.0.0.1:1337 |
Object Storage
Workboard uses S3-compatible object storage for private uploads in task descriptions and task comments.
MinIO is the easiest local option and the primary tested target. You can also use other S3-compatible storage backends such as AWS S3, Cloudflare R2, or fs.
| Name |
Description |
Default |
S3_ENDPOINT |
The S3-compatible API endpoint used by the Kaneo API for presigned uploads. Example: http://minio:9000. |
|
S3_BUCKET |
The bucket Kaneo will use for uploaded files. |
|
S3_ACCESS_KEY_ID |
Access key used by the Kaneo API to create presigned upload URLs. Optional: leave unset (together with S3_SECRET_ACCESS_KEY) to use the default AWS credential provider chain (IAM role / IRSA / instance profile). |
|
S3_SECRET_ACCESS_KEY |
Secret key used by the Kaneo API to create presigned upload URLs. Must be set together with S3_ACCESS_KEY_ID, or left unset for IAM-role-based access. |
|
S3_REGION |
The storage region used for request signing. |
us-east-1 |
S3_PUBLIC_BASE_URL |
Optional public base URL for uploaded assets. Workboard does not require this for the current private asset flow. |
|
S3_FORCE_PATH_STYLE |
Use path-style S3 URLs. This should usually be true for MinIO and fs. |
true |
S3_MAX_IMAGE_UPLOAD_BYTES |
Maximum allowed upload size in bytes for images and other uploaded files. |
10485760 |
S3_KEY_PREFIX |
Optional prefix prepended to all S3 object keys. Useful for sharing a single bucket across multiple environments (e.g. staging/, prod/kaneo/). Trailing slashes are trimmed automatically. |
|
S3_PRESIGN_TTL_SECONDS |
How long presigned upload URLs remain valid. |
300 |
Access Control
| Name |
Description |
Default |
DISABLE_GUEST_ACCESS |
Disable anonymous/guest sign-in. When set to true, the guest access button will not be shown on sign-in and sign-up pages. |
false |
DISABLE_REGISTRATION |
Disable public user registration. When set to true, the sign-up option will not be shown on the sign-in page and new user creation is blocked (including via SSO). Note: Users with valid workspace invitations can still register even when this is enabled. |
false |
DISABLE_PASSWORD_REGISTRATION |
Disable password-based account creation. When set to true, email/password sign-up is blocked, but social/OIDC registration remains available unless DISABLE_REGISTRATION=true. |
false |
DISABLE_EMAIL_OTP_SIGN_IN |
When SMTP is configured, sign-in uses email verification codes by default. Set to true to use email/password sign-in instead. Workspace invitation emails still use SMTP. |
false |
DISABLE_LOGIN_FORM |
Hide the email/password login form on the sign-in page. When set to true, only SSO/OAuth buttons are shown. Useful when you want to enforce authentication exclusively through an external identity provider. |
false |
CUSTOM_OAUTH_AUTO_LOGIN |
Automatically redirect to the custom OAuth/OIDC provider instead of showing the sign-in page. When set to true, users are immediately redirected to your identity provider without seeing the login page. Requires a custom OAuth provider to be configured. |
false |
Before enabling SSO-only access with DISABLE_LOGIN_FORM=true or CUSTOM_OAUTH_AUTO_LOGIN=true on an existing installation, make sure existing local accounts have verified email addresses. OAuth/OIDC identities cannot be linked to an unverified local account, and affected users will receive error=account_not_linked. Keep the login form available until those users have signed in with an email OTP or magic link. If SSO-only access is already enabled, temporarily set both options to false, restart Kaneo, and let affected users complete an email sign-in before restoring the SSO-only settings.
Proxies
| Name |
Description |
Default |
TRUSTED_PROXIES |
Comma-separated IPs or CIDR ranges of the reverse proxies in front of Kaneo. The forwarded header chain is walked right to left, trusted hops are skipped, and the first untrusted address is taken as the client IP. Only set this if your proxies sit outside the default ranges; the default covers loopback and private networks, which is correct for the standard Docker Compose setup. |
127.0.0.0/8, ::1/128, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
Only list addresses you control. Any host in this range can set X-Forwarded-For and have it believed, so do not include a range that clients can reach Kaneo from directly. The client IP is used for rate limiting and session records.
Notifications
| Name |
Description |
Default |
KANEO_ALLOW_PRIVATE_WEBHOOK_DESTINATIONS |
Allow outbound notification destinations (ntfy, Gotify, generic webhooks) that resolve to private or non-routable addresses. Off by default to prevent SSRF; the http/https requirement still applies. Only enable on a trusted, isolated deployment. |
false |
GitHub SSO
Sign in with GitHub uses a GitHub OAuth App. Set GITHUB_OAUTH_CLIENT_ID and GITHUB_OAUTH_CLIENT_SECRET (or rely on the legacy variables below).
| Name |
Description |
GITHUB_OAUTH_CLIENT_ID |
OAuth client ID for GitHub sign-in. |
GITHUB_OAUTH_CLIENT_SECRET |
OAuth client secret for GitHub sign-in. |
GITHUB_CLIENT_ID |
Legacy fallback for OAuth client ID when GITHUB_OAUTH_* is not set. |
GITHUB_CLIENT_SECRET |
Legacy fallback for OAuth client secret when GITHUB_OAUTH_* is not set. |
GitHub integration
Repository sync and webhooks use a GitHub App. These variables do not enable GitHub sign-in; configure GitHub SSO separately if you want both.
| Name |
Description |
GITHUB_APP_ID |
The GitHub App ID. |
GITHUB_WEBHOOK_SECRET |
Secret used to verify GitHub webhook payloads. |
GITHUB_PRIVATE_KEY |
PEM private key for the GitHub App (JWT authentication). Accepts a real multi-line PEM, or a single line where every newline is replaced with the literal characters \n (useful when the host's env editor strips newlines, e.g. Portainer's form-based stack editor). |
GITHUB_PRIVATE_KEY_BASE64 |
(Optional) Alternative to GITHUB_PRIVATE_KEY: a base64-encoded PEM. Takes precedence when both are set. Convenient when your orchestrator can't carry newlines at all. |
GITHUB_APP_NAME |
(Optional) GitHub App slug, used for installation links in the UI. |
Google SSO
| Name |
Description |
GOOGLE_CLIENT_ID |
The Google client ID. |
GOOGLE_CLIENT_SECRET |
The Google client secret. |
Discord SSO
| Name |
Description |
DISCORD_CLIENT_ID |
The Discord client ID. |
DISCORD_CLIENT_SECRET |
The Discord client secret. |
Custom OAuth/OIDC
| Name |
Description |
CUSTOM_OAUTH_CLIENT_ID |
OAuth client ID from your provider. |
CUSTOM_OAUTH_CLIENT_SECRET |
OAuth client secret from your provider. |
CUSTOM_OAUTH_AUTHORIZATION_URL |
Authorization endpoint URL. |
CUSTOM_OAUTH_TOKEN_URL |
Token exchange endpoint URL. |
CUSTOM_OAUTH_USER_INFO_URL |
User info endpoint URL. |
CUSTOM_OAUTH_DISCOVERY_URL |
(Optional) OpenID Connect discovery document URL. |
CUSTOM_OAUTH_SCOPES |
(Optional) Comma-separated list of OAuth scopes. Default: profile,email. |
CUSTOM_OAUTH_RESPONSE_TYPE |
(Optional) OAuth response type. Default: code. |
CUSTOM_AUTH_PKCE |
(Optional) Enable/disable PKCE. Default: true. |
CUSTOM_OAUTH_LOGOUT_URL |
(Optional) Logout endpoint URL for your identity provider. |
Redis
Workboard supports Redis for horizontal scaling of WebSocket broadcasts. When any Redis mode is configured, multiple API instances can relay real-time updates via Redis Pub/Sub. When none are set, an in-memory adapter is used (single-instance only).
Three deployment modes are supported: Standalone, Sentinel, and Cluster. Only one mode should be configured at a time. If multiple are set, the priority is: Cluster > Sentinel > Standalone.
Standalone (single server)
| Name |
Description |
REDIS_URL |
Redis connection string (e.g., redis://localhost:6379). |
Sentinel (high-availability with automatic failover)
| Name |
Description |
Default |
REDIS_SENTINELS |
Comma-separated list of Sentinel nodes (e.g., sentinel-1:26379,sentinel-2:26379,sentinel-3:26379). |
|
REDIS_SENTINEL_MASTER_NAME |
Name of the Sentinel master group. |
mymaster |
REDIS_SENTINEL_PASSWORD |
Password for Sentinel instances, if different from the Redis password. |
|
REDIS_SENTINEL_TLS |
Set to true to enable TLS for Sentinel connections. |
false |
Cluster (horizontal sharding)
| Name |
Description |
REDIS_CLUSTER_NODES |
Comma-separated list of cluster seed nodes (e.g., node-1:6379,node-2:6379,node-3:6379). |
Shared (used by Sentinel and Cluster modes)
| Name |
Description |
REDIS_PASSWORD |
Password for the Redis data nodes (used by both Sentinel and Cluster modes, not for Sentinel auth itself; use REDIS_SENTINEL_PASSWORD for that). |
SMTP Configuration
| Name |
Description |
SMTP_HOST |
The SMTP host. |
SMTP_PORT |
The SMTP port. |
SMTP_SECURE |
Whether to use SSL/TLS. |
SMTP_USER |
The SMTP user. |
SMTP_PASSWORD |
The SMTP password. |
SMTP_FROM |
The SMTP from address. |
SMTP_REQUIRE_TLS |
Whether to explicitly force to use TLS. See more on. |
SMTP_IGNORE_TLS |
Ignore TLS certificate errors. Set to true for self-signed or invalid certificates. Default: false. |
Key points
- If you enable GitHub SSO, create a GitHub OAuth App in GitHub Developer Settings and set
GITHUB_OAUTH_CLIENT_ID / GITHUB_OAUTH_CLIENT_SECRET (or the legacy GITHUB_CLIENT_* variables). See the GitHub SSO guide.
- If you use the GitHub repository integration, configure a GitHub App and set the integration variables in GitHub integration. See the GitHub integration configuration guide.
- If you enable Google SSO, you need to set up the Google app which is used to authenticate users in the Google Cloud Console. See the Google SSO guide.
- If you enable Discord SSO, you need to set up the Discord application which is used to authenticate users in the Discord Developer Portal. See the Discord SSO guide.
- If you enable Custom OAuth/OIDC, you need to configure your identity provider with the appropriate redirect URI. See the Custom OAuth/OIDC guide.
- If you have enabled SMTP, sign-in uses email verification codes by default. Set
DISABLE_EMAIL_OTP_SIGN_IN=true to use email/password sign-in instead.
- If you need device authorization for clients beyond the defaults (
kaneo-cli, kaneo-mcp when DEVICE_AUTH_CLIENT_IDS is unset), set DEVICE_AUTH_CLIENT_IDS to the full comma-separated list of trusted client IDs for your deployment.