> ## Documentation Index
> Fetch the complete documentation index at: https://kaneo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> The environment variables are used to configure the application.

## 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](https://github.com/usekaneo/kaneo/blob/main/.env.sample).

The variables are split up into the following sections:

* [General URLs](#general-urls)
* [Database](#database)
* [Authentication](#authentication)
* [MCP](#mcp)
* [Object Storage](#object-storage)
* [Access Control](#access-control)
* [GitHub SSO](#github-sso)
* [GitHub integration](#github-integration)
* [Google SSO](#google-sso)
* [Discord SSO](#discord-sso)
* [Custom OAuth/OIDC](#custom-oauth-oidc)
* [Redis](#redis)
* [SMTP Configuration](#smtp-configuration)

## 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, Kaneo implicitly allows `kaneo-cli` and `kaneo-mcp` by default, so no extra configuration is required for the CLI or MCP. Override only when you need additional trusted clients, for example `kaneo-cli,kaneo-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

Kaneo 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`](https://github.com/ferdzo/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. Kaneo 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` |

<Warning>
  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.
</Warning>

### 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` |

<Warning>
  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.
</Warning>

### 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](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-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](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps). These variables do not enable GitHub sign-in; configure [GitHub SSO](#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

Kaneo 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](https://nodemailer.com/smtp#tls-options).         |
| `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](https://github.com/settings/developers) and set `GITHUB_OAUTH_CLIENT_ID` / `GITHUB_OAUTH_CLIENT_SECRET` (or the legacy `GITHUB_CLIENT_*` variables). See the [GitHub SSO guide](/docs/core/social-providers/github).
* If you use the GitHub repository integration, configure a GitHub App and set the integration variables in [GitHub integration](#github-integration). See the [GitHub integration configuration](/docs/core/integrations/github/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](https://console.cloud.google.com/). See the [Google SSO guide](/docs/core/social-providers/google).
* If you enable Discord SSO, you need to set up the Discord application which is used to authenticate users in the [Discord Developer Portal](https://discord.com/developers/applications). See the [Discord SSO guide](/docs/core/social-providers/discord).
* If you enable Custom OAuth/OIDC, you need to configure your identity provider with the appropriate redirect URI. See the [Custom OAuth/OIDC guide](/docs/core/social-providers/custom-oauth).
* 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.
