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

# Environment variables

> Every environment variable read by the r5d.chat control plane, with defaults and validation rules.

The control plane validates its environment at startup with a strict schema. An
invalid or missing required value stops the process immediately rather than
failing later at runtime.

In Kubernetes, most of these are set by the chart. You normally only manage the
secret values.

## Required

<ResponseField name="DATABASE_URL" type="string" required>
  PostgreSQL connection string. Also checked by `/api/health`.
</ResponseField>

<ResponseField name="BETTER_AUTH_SECRET" type="string" required>
  Signs session cookies. Minimum 32 characters. Changing it invalidates all
  active sessions.
</ResponseField>

<ResponseField name="SETTINGS_ENCRYPTION_KEY" type="string" required>
  AES-256-GCM key protecting provider API keys, custom headers, MCP headers, and
  OIDC client secrets. Minimum 32 characters.

  <Warning>
    Changing this value does not re-encrypt existing data. Every stored
    credential becomes unreadable. Treat it as part of your backup set, not as a
    rotatable key.
  </Warning>
</ResponseField>

## General

<ResponseField name="EDITION" type="string" default="self-hosted">
  `self-hosted` or `managed`. A self-hosted installation has no paywall, never
  contacts a payment provider, and keeps registration invite-only. `managed`
  enables subscription billing and open sign-up and is used only by the hosted
  r5d.chat service. The chart sets this from `edition`.
</ResponseField>

<ResponseField name="BASE_URL" type="string" default="http://localhost:3000">
  The external URL of the installation. Must be a valid URL. The chart sets this
  from `publicUrl`. A mismatch with the browser's address breaks cookies and
  auth redirects.
</ResponseField>

<ResponseField name="SETUP_CLAIM_TOKEN" type="string">
  Optional one-time token required to create the first administrator. Minimum 16
  characters when set. Once setup completes, the value is no longer consulted.
</ResponseField>

## Billing

Read only when `EDITION=managed`. Billing stays inert until the access token,
webhook secret, and product id are all present, so an incompletely configured
managed installation grants access rather than locking everyone out.

<ResponseField name="POLAR_ACCESS_TOKEN" type="string">
  Polar organization access token used to read subscriptions and open checkout
  and portal sessions.
</ResponseField>

<ResponseField name="POLAR_WEBHOOK_SECRET" type="string">
  Shared secret used to verify signatures on `POST /api/auth/polar/webhooks`.
</ResponseField>

<ResponseField name="POLAR_PRODUCT_ID" type="string">
  Product whose subscription grants access. Subscriptions to any other product
  in the same organization are ignored.
</ResponseField>

<ResponseField name="POLAR_SERVER" type="string" default="production">
  `production` or `sandbox`.
</ResponseField>

<ResponseField name="BILLING_GRACE_HOURS" type="integer" default="72">
  Hours a lapsed subscription keeps access after its last paid period ends.
</ResponseField>

## Outbound request guard

The control plane makes outbound requests to model providers, MCP servers, and
OIDC issuers. Every destination passes through a guard that blocks
credential-bearing URLs, unsafe redirects, and internal network addresses.

<ResponseField name="ALLOW_PRIVATE_EGRESS" type="'true' | 'false'" default="false">
  Allow requests to private, loopback, and link-local addresses. Required to
  reach a model server inside your own network. Enabling this makes SSRF against
  cluster-internal services possible.
</ResponseField>

<ResponseField name="ALLOW_INSECURE_HTTP" type="'true' | 'false'" default="false">
  Allow plain `http://` destinations. Credentials would travel unencrypted, so
  restrict this to trusted private networks.
</ResponseField>

<Warning>
  Metadata endpoints such as `169.254.169.254` are a standard cloud credential
  theft target. Leave both flags at `false` unless you have a specific need and
  compensating network policy.
</Warning>

## Workspace controller

<ResponseField name="WORKSPACE_MODE" type="'kubernetes' | 'local' | 'disabled'" default="local">
  How workspaces are provisioned. The chart always sets `kubernetes`. Use
  `local` for development and `disabled` to turn off workspace features
  entirely.
</ResponseField>

<ResponseField name="WORKSPACE_NAMESPACE" type="string" default="r5d-chat">
  Namespace where workspace objects are created. The chart sets this to the
  release namespace.
</ResponseField>

<ResponseField name="WORKSPACE_IMAGE" type="string" default="ghcr.io/ricsam/r5d-chat-workspace:latest">
  Image used for new and reconciled workspace pods.
</ResponseField>

<ResponseField name="WORKSPACE_IMAGE_PULL_SECRET" type="string">
  Pull secret attached to workspace pods. Needed for private images.
</ResponseField>

<ResponseField name="WORKSPACE_STORAGE_CLASS" type="string" default="rook-ceph-block">
  Storage class for per-user home PVCs.
</ResponseField>

<ResponseField name="WORKSPACE_STORAGE_SIZE" type="string" default="5Gi">
  Size requested for each new home PVC. Applies only at creation time.
</ResponseField>

<ResponseField name="WORKSPACE_RUNTIME_CLASS" type="string">
  Optional RuntimeClass, such as `kata` or `gvisor`, for a stronger isolation
  boundary.
</ResponseField>

<ResponseField name="WORKSPACE_IDLE_SECONDS" type="integer" default="1800">
  Idle seconds before a workspace with no active leases scales to zero. A
  reconciler evaluates this every 60 seconds.
</ResponseField>

<ResponseField name="WORKSPACE_CPU_REQUEST" type="string" default="200m">
  CPU request for workspace pods.
</ResponseField>

<ResponseField name="WORKSPACE_MEMORY_REQUEST" type="string" default="512Mi">
  Memory request for workspace pods.
</ResponseField>

<ResponseField name="WORKSPACE_CPU_LIMIT" type="string" default="2">
  CPU limit for workspace pods.
</ResponseField>

<ResponseField name="WORKSPACE_MEMORY_LIMIT" type="string" default="2Gi">
  Memory limit for workspace pods. Raise it if agents run builds or process
  large datasets; the kernel OOM-kills the container when it is exceeded.
</ResponseField>

## Local workspace mode

<ResponseField name="R5DCHAT_LOCAL_DAEMON_URL" type="string" default="http://127.0.0.1:7337">
  Address of the local daemon. Only used when `WORKSPACE_MODE=local`.
</ResponseField>

<ResponseField name="R5DCHAT_LOCAL_DAEMON_TOKEN" type="string" default="development-only-token">
  Bearer token for the local daemon. Only used when `WORKSPACE_MODE=local`.
</ResponseField>

## Optional integrations

<ResponseField name="AWR_BASE_URL" type="string">
  Base URL of an Agentic Web Research service. The `web_search`, `web_read`, and
  `web_research` tools appear only when this and `AWR_API_KEY` are both set.
</ResponseField>

<ResponseField name="AWR_API_KEY" type="string">
  API key for the web research service. Treat it as a secret.
</ResponseField>

<Card title="Enable web research" icon="globe" href="/configure/web-research">
  How the integration works and what it exposes.
</Card>

## Variables inside a workspace pod

The controller sets these on each workspace container. They are listed for
debugging; you do not configure them directly.

| Variable                    | Value                                        |
| --------------------------- | -------------------------------------------- |
| `HOME`, `R5DCHAT_HOME`      | `/home/r5d`                                  |
| `R5DCHAT_PORT`              | `7337`                                       |
| `R5DCHAT_USER_ID`           | The owning user's ID                         |
| `R5DCHAT_CONTROL_PLANE_URL` | The control plane's `BASE_URL`               |
| `R5DCHAT_DAEMON_TOKEN`      | Bearer token, from the identity Secret       |
| `R5DCHAT_WORKSPACE_TOKEN`   | Workspace identity, from the identity Secret |
