> ## 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)
* [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

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

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