Configure

The server is configured by environment variables, all prefixed RIM_ except DATABASE_URL and the log filter RUST_LOG. In development an untracked .env file works too. This page is generated from rim_server/src/config.rs, cross-checked with the variable block of the Dockerfile; the compose stack's own settings are in deploy/.env.example.

Listening #

Where the server listens, the origin clients reach it at, and how it treats the proxy in front of it.

VariableWhat it does
RIM_SERVER_HOSTdefault 0.0.0.0

Bind address.

No doc comment in config.rs; described from the Dockerfile.

The container image sets 0.0.0.0.

RIM_SERVER_PORTdefault 8080

Listen port.

No doc comment in config.rs; described from the Dockerfile.

The container image sets 8080.

RIM_PUBLIC_BASE_URLunset by default

e.g. https://rim.example.com. Required to build clickable reset-password/invite links; without it, emails fall back to including the bare token/no link.

Dockerfile: https origin; turns server-to-server traffic on. This or RIM_KEY_LOGIN_AUDIENCES is required: the server binds 0.0.0.0 and refuses to start without an audience for key logins.

RIM_CORS_ALLOWED_ORIGINunset by default

one browser origin accepted besides the server's own (optional); the own origin is RIM_PUBLIC_BASE_URL's, else the request's Host.

No doc comment in config.rs; described from the Dockerfile.

RIM_TRUST_FORWARDED_HEADERSdefault false

When true, the server reads X-Forwarded-For / Forwarded headers to determine the real client IP for rate-limiting. Only enable this when a trusted reverse proxy (Nginx, Caddy, Traefik, …) is the sole entry point; enabling it without a proxy lets attackers spoof their IP and defeat the rate limiters.

Dockerfile: Read the client address from X-Forwarded-For / Forwarded when true; only behind a reverse proxy that is the sole way in.

RIM_FORCE_SECURE_COOKIESdefault false

When true, all session and CSRF cookies are issued with Secure=true regardless of the incoming request scheme or X-Forwarded-Proto header. Use this for direct-HTTPS deployments where the reverse proxy does not forward the X-Forwarded-Proto header.

Dockerfile: Mark session and CSRF cookies Secure whatever the request scheme when true.

RIM_KEY_LOGIN_AUDIENCESunset by default

Comma-separated host[:port] values a key login proof may name as its audience.

The audiences a key login proof may name: this server's host[:port] as clients reach it. A proof naming another server is refused, so a server that receives a proof cannot replay it elsewhere.

RIM_KEY_LOGIN_AUDIENCES when set; otherwise the host of RIM_PUBLIC_BASE_URL; otherwise localhost:PORT and 127.0.0.1:PORT, but only for a server bound to a loopback address. Lowercased.

Refused at boot with a message naming both variables when neither is set and RIM_SERVER_HOST accepts connections from other machines.

Dockerfile: comma-separated host[:port] clients reach this server at.

Database and data #

PostgreSQL, the data directory, uploaded files and the key files. The data directory holds the server's identity: back it up.

VariableWhat it does
DATABASE_URLrequired

PostgreSQL connection string.

No doc comment in config.rs; described from the Dockerfile.

RIM_DATABASE_MAX_CONNECTIONSdefault 10

Largest number of Postgres connections the server's pool opens; unset keeps the driver's default of 10.

Unset, it keeps the driver's default of 10.

Dockerfile: Size of the PostgreSQL pool.

RIM_DATA_DIRdefault ./data

Data directory.

No doc comment in config.rs; described from the Dockerfile.

The container image sets /app/data.

RIM_STORAGE_LOCAL_PATHdefault $RIM_DATA_DIR/files; this image sets /app/data/uploads

Directory of uploaded files (attachments, custom emoji, plugin bundles), created when missing; unset uses files under RIM_DATA_DIR.

Unset, it uses `files` under `RIM_DATA_DIR`.

Dockerfile: Directory of uploaded files.

The container image sets /app/data/uploads.

RIM_MAX_WORKSPACE_STORAGE_BYTESdefault 1073741824

Bytes one workspace may store: its attachments, uploads in progress included, and its plugin bundles; an upload past it is refused. Default 1 GiB (1073741824).

Dockerfile: Bytes of attachments and plugin bundles one workspace may store.

RIM_SERVER_KEY_FILEdefault <RIM_DATA_DIR>/server-key.json

Path of the server key file. Default <RIM_DATA_DIR>/server-key.json.

Dockerfile: Server key file; keep the data directory on a volume, the key is the server's identity.

RIM_FRANKING_KEY_FILEdefault <RIM_DATA_DIR>/franking-key.json

Path of the franking key file. Default <RIM_DATA_DIR>/franking-key.json.

Dockerfile: Franking key file.

Signups and sessions #

Who may sign up and how, the names nobody may take, the probation of new accounts, the workspace every new account joins, how long a session lasts and how long a deleted account waits before its purge. The default is invite-only; invites come from the command line.

VariableWhat it does
RIM_OPEN_REGISTRATIONdefault false

Set RIM_OPEN_REGISTRATION=true to enable open signup.

Dockerfile: Let anyone sign up, rate-limited, when true.

RIM_REGISTRATION_POW_BITSunset by default

Leading zero bits a key-only signup's proof-of-work needs; set, it turns on pow registration. 1 to 40.

Dockerfile: turns on proof-of-work signups with that many leading zero bits.

RIM_SIGNUP_REQUIRE_KEYSdefault true

Refuse every password signup, so new accounts sign up with a key only; unset is true. Password sign-in of existing accounts is unaffected.

Whether password signups are refused: RIM_SIGNUP_REQUIRE_KEYS, true when unset.

Dockerfile: Refuse every password signup, so accounts sign up with a key; password sign-in of existing accounts still works.

RIM_DEFAULT_WORKSPACEdefault none

The id of a workspace on this server that every new account joins as a member, with its public channels, whichever way it signs up. Unset keeps signups as they are: a new account joins only the workspace its invite names. The server refuses to start when the workspace does not exist here or is the direct space.

RIM_DEFAULT_WORKSPACE, trimmed; None when unset or blank. Whether the workspace exists is checked against the database at start.

Unset, it keeps signups as they are: a new account joins only the workspace its invite names.

Refused at boot with a message naming the variable when the value is not a workspace id.

Dockerfile: id of a workspace here every new account joins as a member; one that does not exist stops the server at boot.

RIM_RESERVED_NAMESdefault none

Comma-separated usernames and display names signups and profile edits refuse, with each followed by -, _, . or a space.

RIM_RESERVED_NAMES, compared case-insensitively after NFKC normalisation; nothing is reserved when it is unset or blank.

Refused at boot with a message naming the variable when an entry is empty, as in rim,,admin.

Dockerfile: comma-separated usernames and display names signups and profile edits refuse, also followed by -, _, . or a space; an empty entry stops the server at boot.

RIM_PROBATION_HOURSdefault off

Hours after its creation during which an account cannot create a workspace or send a DM request to a stranger; unset or 0 turns probation off.

Unset, it turns probation off.

Dockerfile: hours after creation during which an account creates no workspace and sends no DM request to a stranger.

RIM_SESSION_TTL_DAYSdefault 30

Session lifetime.

No doc comment in config.rs; described from the Dockerfile.

RIM_TERMS_URLdefault none

The terms of service every signup accepts, an absolute http(s) URL.

RIM_TERMS_URL, trimmed; None when unset or blank.

Refused at boot with a message naming the variable when the value is not an absolute http or https URL with a host.

Dockerfile: absolute http(s) URL of the terms of service; set, every signup must accept it; a malformed URL stops the server at boot.

RIM_ACCOUNT_DELETION_GRACE_DAYSdefault 14

Days between an account's deletion request and its purge, 0 to 30; default 14.

Refused at boot with a message naming the variable when the value is above 30.

Dockerfile: days between an account's deletion request and its purge, 0-30; outside the range stops the server at boot.

Roles and federation #

Whether the server is a relay, a host or both, which servers it talks to, who outside a shared workspace may start a DM, and the per-user quotas of a relay.

VariableWhat it does
RIM_ROLEdefault both

relay, host or both (default).

Refused at boot with a message naming the value when it is not relay, host or both.

Dockerfile: relay, host or both.

RIM_HOST_ALLOWED_RELAYSdefault any

Comma-separated server ids allowed on host endpoints; empty allows any relay.

Refused at boot with a message naming the first entry that is not a server id.

Dockerfile: Server ids allowed on host endpoints, comma-separated.

RIM_DM_INBOUNDdefault requests

DMs from people on other servers, and from people here who share no workspace with the recipient: open (no floor), requests (default: their first message is a request the recipient accepts), partners (only people on the servers RIM_DM_PARTNERS lists, and on this one, with a request; other servers get no identity or key package of anyone here) or none (nobody outside a shared workspace; other servers get no identity or key package). Members of a shared workspace follow the workspace's rules instead.

Refused at boot with a message naming the variable whose value is not one it takes, or the first partner that is not a server id.

Dockerfile: DMs from other servers, and from people here who share no workspace with the recipient: open, requests (their first message is a request the recipient accepts), partners (only people on the RIM_DM_PARTNERS servers and this one, with a request) or none; with partners or none other servers get no identity of anyone here.

RIM_DM_OUTBOUNDdefault allowed

DMs people here start with people on other servers: allowed (default), partners (only with people on the servers RIM_DM_PARTNERS lists) or none.

Dockerfile: DMs people here start with people on other servers: allowed, partners (only with people on the RIM_DM_PARTNERS servers) or none.

RIM_DM_PARTNERSdefault none

Comma-separated server ids the partners settings of RIM_DM_INBOUND and RIM_DM_OUTBOUND name.

Dockerfile: Server ids the partners settings of RIM_DM_INBOUND and RIM_DM_OUTBOUND name, comma-separated.

RIM_S2S_DENIED_PEERSunset by default

Comma-separated server ids refused on every server-to-server endpoint.

Refused at boot with a message naming the first entry that is not a server id.

Dockerfile: Server ids refused on every server-to-server endpoint, comma-separated.

RIM_S2S_PEER_RATE_PER_MINdefault 600

Server-to-server requests accepted per peer per minute, per node. Default 600.

Dockerfile: Server-to-server requests per peer per minute.

RIM_S2S_MAX_BODY_BYTESdefault 8388608

Largest server-to-server request body. Default 8 MiB.

Dockerfile: Largest server-to-server request body.

RIM_S2S_ALLOW_PRIVATE_ADDRESSESdefault false

Allow peers on loopback, private, link-local and unique-local addresses (development and tests only).

Dockerfile: Allow peers on private addresses when true; development only.

RIM_S2S_ALLOW_HTTPdefault false

Allow server-to-server traffic over plain http (development and tests only).

Dockerfile: Allow server-to-server traffic over http when true; development only.

RIM_S2S_DEVICE_RATE_PER_MINdefault 120

Forwarded requests accepted per device per minute. Default 120.

Dockerfile: Forwarded requests per device per minute.

RIM_S2S_SUBSCRIPTIONS_PER_PEERdefault 10,000

Active delegations one relay may hold on this host. Default 10,000.

Dockerfile: Delegations one relay may hold on this host.

RIM_RELAY_QUEUE_BYTES_PER_USERdefault 256 MiB

Bytes queued per local user before the oldest items are dropped. Default 256 MiB.

Dockerfile: bytes queued per local user before the oldest items are dropped, at least 1048576.

RIM_RELAY_RETENTION_DAYSdefault 30

Days queued items and DM requests are kept. Default 30.

Dockerfile: days queued items and DM requests are kept, 1-365.

RIM_RELAY_CARD_MAX_BYTESdefault 131072

Largest profile card, in bytes. Default and most 131072.

Dockerfile: largest profile card, 1024-131072.

RIM_RELAY_KEY_PACKAGES_PER_DEVICEdefault 100

Unclaimed one-time key packages per device and cipher suite. Default 100.

Dockerfile: unclaimed key packages per device, 1-1000.

RIM_RELAY_DEVICES_PER_USERdefault 32

Devices that are not revoked, per user. Default 32.

Dockerfile: devices per user that are not revoked, 1-64.

RIM_RELAY_FORWARDS_PER_USER_PER_DAYdefault 50000

Requests a user sends through /api/remote/… per day. Default 50000.

Dockerfile: requests a user sends through /api/remote per day.

RIM_RELAY_DM_REQUESTS_PER_DAYdefault 20

DM requests one sender principal files here per day, and invites a local user sends to people on other servers per day. Default 20.

Dockerfile: DM requests one sender files here, and invites a local user sends to other servers, per day.

Mail #

Transactional email. Without RIM_SMTP_HOST and RIM_SMTP_FROM mail is only logged and the email feature reports itself unavailable.

VariableWhat it does
RIM_NOTIFICATION_DIGEST_INTERVAL_SECSdefault 900

How often (seconds) the notification digest job looks for due digests. Default: 900 (15 minutes); values below 60 are raised to 60.

Dockerfile: Seconds between digest runs, at least 60.

RIM_SMTP_HOSTunset by default

SMTP server; without it or RIM_SMTP_FROM mail is only logged.

No doc comment in config.rs; described from the Dockerfile.

RIM_SMTP_PORTdefault 587

Defaults to 587 (STARTTLS) when unset.

Dockerfile: SMTP port.

RIM_SMTP_USERNAMEdefault none, unauthenticated

SMTP user name.

No doc comment in config.rs; described from the Dockerfile.

RIM_SMTP_PASSWORDdefault none

SMTP password.

No doc comment in config.rs; described from the Dockerfile.

RIM_SMTP_FROMunset by default

The From: address/mailbox, e.g. "RIM <noreply@example.com>".

Dockerfile: From address, e.g. RIM noreply@example.org.

RIM_SMTP_TLSdefault starttls

"starttls" (default) | "implicit" | "none" (dev/localhost only).

Dockerfile: starttls, implicit or none.

Operations #

Metrics, the audit log, features switched off on this instance, logging, the notice shown to people, and how many link preview fetches and password hashes run at once.

VariableWhat it does
RIM_METRICS_ADDRdefault off

host:port of the Prometheus listener serving GET /metrics; unset turns metrics off.

Unset, it turns metrics off.

Refused at boot with a message naming the variable when the value is not an ip:port address.

Dockerfile: ip:port of the Prometheus /metrics listener. In a container bind 0.0.0.0:9090 and do not publish it: keep it on an internal network, never behind the public proxy.

RIM_AUDIT_LOG_PATHdefault the working directory

Directory of audit.log

Read by rim_logging/src/logging.rs, not config.rs.

RIM_AUDIT_RETENTION_DAYSdefault forever

Days command audit log rows are kept before the daily purge exports and deletes them; unset keeps them forever. 1 to 3650.

Unset, it keeps them forever.

Refused at boot with a message naming the variable when the value is outside 1 to 3650.

Dockerfile: days command audit rows are kept, 1-3650; older rows are exported to $RIM_DATA_DIR/audit-exports and deleted daily.

RIM_FEATURES_DISABLEDdefault none

Comma-separated optional features switched off on this instance, e.g. attachments,custom_emoji; unset or empty keeps every feature on.

RIM_FEATURES_DISABLED as features; empty when unset.

Unset, it keeps every feature on.

Refused at boot with a message naming the variable and the first name that is not a feature, so a typo stops the server instead of leaving a feature on.

Dockerfile: comma-separated optional features to switch off: attachments, link_previews, email, custom_emoji, workspace_plugins, ai_commands; an unknown name stops the server at boot.

RUST_LOGdefault info

Log filter, e.g. info or rim_server=debug.

The logger reads it, not config.rs.

RIM_ENABLE_GRAPHIQLdefault false

Serve the GraphiQL explorer at GET /api when true.

No doc comment in config.rs; described from the Dockerfile.

RIM_INSTANCE_NOTICEdefault none

A short text shown to people on this instance, at most 500 characters.

RIM_INSTANCE_NOTICE, trimmed; None when unset or blank.

Refused at boot with a message naming the variable when the notice is longer than 500 characters.

Dockerfile: a short text shown to people on this instance, at most 500 characters; longer stops the server at boot.

RIM_PASSWORD_HASH_CONCURRENCYdefault the number of CPUs

Argon2 hashes and verifications the server runs at once, 1 to 64; default the number of CPUs.

RIM_PASSWORD_HASH_CONCURRENCY: the Argon2 computations run at once; the number of CPUs, within 1 to 64, when unset.

Refused at boot with a message naming the variable when the value is outside 1 to 64.

Dockerfile: Argon2 password hashes and checks run at once, 1-64; each holds 64 MiB while it runs, and a request that waits over 10 seconds for a turn answers UNAVAILABLE.

Limits and rate limits #

Request, mutation, message and connection limits of the API, and how often open WebSocket connections recheck their session. Each rate limit is off until set.

VariableWhat it does
RIM_API_MAX_BATCHdefault 20

Most GraphQL requests in one batch. Default 20.

Dockerfile: GraphQL requests in one batch.

RIM_WS_SESSION_RECHECK_SECSdefault 30

Seconds between rechecks of the sessions WebSocket connections run under; unset is 30, 0 turns the recheck off.

Dockerfile: seconds between rechecks of the sessions WebSocket connections run under, closing those that ended elsewhere.

RIM_RATE_REQUESTS_PER_MIN_PER_IPdefault off

Requests one client address sends to /api routes per minute, with a burst of the same size; unset or 0 sets no limit.

Unset, it sets no limit.

Dockerfile: requests per client address per minute to /api routes, with a burst of the same size; over it 429.

RIM_RATE_MUTATIONS_PER_MIN_PER_SESSIONdefault off

Mutation fields one session runs per minute, counted per GraphQL request; callers without a session count per address. Unset or 0 sets no limit.

Unset, it sets no limit.

Dockerfile: mutation fields per session per minute.

RIM_RATE_MESSAGES_PER_MIN_PER_USERdefault off

Messages one user sends per minute; unset or 0 sets no limit.

Unset, it sets no limit.

Dockerfile: messages per user per minute.

RIM_RATE_MESSAGES_BURSTdefault the per-minute number

Messages one user may send at once before the per-minute rate applies; unset uses the per-minute number.

Unset, it uses the per-minute number.

Dockerfile: messages a user may send at once.

RIM_RATE_WS_CONNECTIONS_PER_USERdefault off

WebSocket connections one user holds open at once; unset or 0 sets no limit.

Unset, it sets no limit.

Dockerfile: open WebSocket connections per user.

RIM_RATE_SUBSCRIPTIONS_PER_CONNECTIONdefault off

Subscriptions one WebSocket connection holds at once; unset or 0 sets no limit.

Unset, it sets no limit.

Dockerfile: subscriptions per WebSocket connection.

RIM_RATE_PROBATION_MESSAGES_PER_MINdefault the normal rate

Messages an account in probation sends per minute, with a burst of the same size, instead of the normal message rate; unset or 0 keeps the normal rate.

Unset, it keeps the normal rate.

Dockerfile: messages per minute of an account in probation, instead of the normal rate.

Instance limits #

How much of each thing the instance holds. Each is off until set, except the pending invitations to encrypted conversations; past one a write answers VALIDATION naming the cap, and clients read them from serverInfo.limits.

VariableWhat it does
RIM_LIMIT_WORKSPACES_PER_USERunset by default

Workspaces one user owns.

Dockerfile: workspaces one user owns.

RIM_LIMIT_MEMBERS_PER_WORKSPACEunset by default

Members of one workspace; the direct space has no cap.

Dockerfile: members of a workspace (the direct space has none).

RIM_LIMIT_CHANNELS_PER_WORKSPACEunset by default

Channels of one workspace, public and private.

Dockerfile: channels of a workspace, public and private.

RIM_LIMIT_DEVICES_PER_USERunset by default

Devices on one account; the stricter of this and RIM_RELAY_DEVICES_PER_USER applies.

Dockerfile: devices on one account; the stricter of this and RIM_RELAY_DEVICES_PER_USER applies.

RIM_LIMIT_DM_REQUESTS_PER_DAYunset by default

DM requests one user sends to strangers per day; the stricter of this and RIM_RELAY_DM_REQUESTS_PER_DAY applies.

Dockerfile: DM requests to strangers per user per day; the stricter of this and RIM_RELAY_DM_REQUESTS_PER_DAY applies.

RIM_LIMIT_MACROS_PER_WORKSPACEunset by default

Macros of one workspace.

Dockerfile: macros of a workspace.

RIM_LIMIT_PIPELINES_PER_WORKSPACEunset by default

Pipelines of one workspace.

Dockerfile: pipelines of a workspace.

RIM_LIMIT_PLUGINS_PER_WORKSPACEunset by default

Plugins of one workspace's registry.

Dockerfile: plugins of a workspace's registry.

RIM_LIMIT_INVITES_PER_USER_PER_DAYunset by default

Invites one user creates per day.

Dockerfile: workspace invites one user creates per day.

RIM_LIMIT_INVITE_MAX_USESunset by default

Uses one invite may have.

Dockerfile: the uses one invite may have.

RIM_LIMIT_MESSAGE_BYTESunset by default

Bytes of one message's text, at most 65536.

Dockerfile: bytes of a message's text, at most 65536; more stops the server at boot.

RIM_LIMIT_PENDING_INVITES_PER_USERdefault 50

Pending invitations to encrypted conversations one user holds; unlike the other caps it defaults to 50, and 0 turns it off.

Dockerfile: pending invitations to encrypted conversations one user holds; unlike the others it is on unless set to 0.

Command line #

Run without arguments, rim_server (/app/rim-server in the image) starts the server. The subcommands read the same configuration and exit:

rim_server --version
rim_server invite create [--email <address>] [--max-uses <1-50>] [--expires-in-days <1-30>] [--public-url <url>]
rim_server invite list
rim_server invite revoke <invite-id>
rim_server server-key show | rotate | recover --recovery-key-file <file> [--new-recovery-key]
rim_server peer reset | block | unblock <server-id>
rim_server franking-key show | rotate
rim_server principal block <principal-id> --reason <text> [--cascade]
rim_server principal unblock <principal-id>
rim_server principal show <principal-id>
rim_server principal list
rim_server abuse-reports list [--open]
rim_server abuse-reports add [--principal <principal-id>] [--server <server-id>] --reason <text>
rim_server abuse-reports resolve <report-id>
rim_server audit purge [--dry-run] [--older-than-days <1-3650>]
rim_server ip block <cidr> --reason <text> [--expires-in-days <1-365>]
rim_server ip unblock <cidr>
rim_server ip list
rim_server account purge [--dry-run]
rim_server operator grant <username>
rim_server operator revoke <username>
rim_server operator list

invite create prints a signup link; with --email the account it signs up gets that address. docs/server-identity.md explains the key and peer commands, docs/relay.md and docs/operations/relay-public.md the abuse tools, docs/operations/audit-retention.md the purge. ip block refuses an address or CIDR range, IPv4 or IPv6, on every route but /healthz (docs/self-hosting.md, "Limits and blocking"). account purge purges the accounts whose deletion grace period ended now instead of at the next hourly run (docs/self-hosting.md, "Deleted accounts"). operator grant lets an account run the abuse reports, principal blocks and IP blocks from the app (docs/api.md, "Instance moderation").