# Configuration

> Every setting a self-hosted Weald relay reads, what it defaults to, and the four values that decide whether the relay will accept a connection at all.

Source: https://getweald.com/docs/self-hosting/configuration
Last modified: 2026-08-03

---

## The environment file

Last updated 2026-08-03

A Weald relay reads three required environment variables and about ten optional ones. The required three are a hostname, a database URL and a storage URL; every other value has a default that works. The surface is small on purpose, because a configuration key that quietly widens a security boundary is more dangerous than a missing feature.

## Required

```sh
WEALD_RELAY_HOSTNAME       relay.example.com
WEALD_RELAY_DATABASE_URL   postgres://...
WEALD_RELAY_STORAGE_URL    s3://bucket  |  file:///var/lib/wealdrelay/blobs
```

The compose bundle fills the second and third in for you from the containers it starts, so on the default path the hostname is the only line you edit.

## Optional

*Optional settings and their defaults*

| Variable | Default | What it decides |
| --- | --- | --- |
| WEALD_RELAY_REDIS_URL | unset | Live fanout between processes. Unset means single-process mode |
| WEALD_RELAY_LISTEN | 0.0.0.0:8443 | The address the client WebSocket binds to |
| WEALD_RELAY_TLS | acme | acme, file or off, the last for a proxy that terminates TLS |
| WEALD_RELAY_MAX_STORAGE_GB | unlimited | A ceiling, after which writes are refused with a quota error |
| WEALD_RELAY_RETENTION_DAYS | unlimited | How long history is kept below a checkpoint |
| WEALD_RELAY_ACCESS_SET | enforce | Whether a revoked device can still open a socket |
| WEALD_RELAY_SMTP_URL | unset | Lets the relay send invite mail. Self-host only |
| WEALD_RELAY_WRITE_MODE | full | read_only refuses new durable writes and keeps reads working |
| WEALD_RELAY_OBSERVABILITY_LISTEN | 127.0.0.1:9090 | The private health and metrics listener |
| WEALD_RELAY_METRICS_GROUP_LABELS | off | Per-group envelope and byte counts in metrics |
| WEALD_RELAY_RELEASE_CHECK | on | A daily unauthenticated GET of the public release feed |

## The four that decide posture

WEALD_RELAY_ACCESS_SET. Leave it at enforce, which checks an authenticated connection against the group's published access set, so revoking a device disconnects it. Setting it to off means any well-formed key may open a socket, which is only reasonable on a relay with no public ingress, and a relay running that way says so in its readiness output and in every client's encryption panel.

WEALD_RELAY_SMTP_URL. Configuring it lets your relay send invite mail, which is convenient and means your relay now holds invitee email addresses. That is a list of humans inside the half of the system that is otherwise blind, so it is unset by default and refused outright on the hosted tier.

WEALD_RELAY_METRICS_GROUP_LABELS. Off by default. Turning it on breaks envelope counts and byte totals out per group, which helps a self-hoster debug their own instance and is never enabled on the hosted tier.

WEALD_RELAY_RELEASE_CHECK. The relay checks the public release feed once a day and reports the result on its readiness endpoint, so a client can tell an admin that a security release exists. It is an unauthenticated GET of a public file and nothing else, and turning it off is the right answer for an air-gapped install.

## What is deliberately absent

There is no admin password, no operator account, no web admin panel and no configuration key naming a billing system, a license server or a control plane. The complete required set is the three variables above.

A fourth required variable pointing at a hosted service would be a trust boundary change, because it would mean the hosted binary differs from the audited one and a self-hoster runs something else. A flag that silently widened enrollment was removed for the same reason.

Enrollment is invites. One path, no second mechanism, and no setting that turns a workspace into one anybody can join.
