-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenv.example
More file actions
233 lines (209 loc) · 10.2 KB
/
Copy pathenv.example
File metadata and controls
233 lines (209 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# rhorizon, environment variables
# Copy to .env and fill in: cp env.example .env
# Or generate secrets: make secrets
# PostgreSQL
POSTGRES_DB=rhorizon
POSTGRES_USER=rhorizon
POSTGRES_PASSWORD= # openssl rand -hex 24
# PG TLS mode: disable | require | verify-full.
# verify-full (compose default) verifies the server cert against
# RH_DATABASE_CA_CERT (the postgres service auto-generates and
# pins a per-instance cert -- no action needed).
# require encrypts without verifying (relaxed single-host / loopback).
# disable is plaintext (only over a local unix socket).
# Bring your own CA: point RH_DATABASE_CA_CERT at it, keep verify-full.
# RH_DATABASE_SSL=verify-full
# RH_DATABASE_CA_CERT=/pg-certs/server.crt
# API + PG sizing, pick a row, set BOTH RH_WORKERS and
# POSTGRES_MAX_CONNECTIONS at the same level. Each worker holds 20 PG
# connections (pool_size=10 + max_overflow=10), so PG max_connections
# must cover `workers * 20` plus ~20 headroom for heartbeat / reaper.
#
# Profile | Workers | PG max_connections | Notes
# --------------------+---------+--------------------+---------------------
# normal | 5 | 200 | default, comfortable
# high (mid-size) | 8 | 200 | tight (165 used)
# very high (entrpr) | 12-16 | 400 | + pgbouncer recommended
#
# Do not undershoot : if `workers * 20 > max_connections`, you'll see
# `pool timeout` errors under load. Bump max_connections first, workers
# second.
POSTGRES_MAX_CONNECTIONS=200
# API
# RH_WORKERS=1 (home) is valid and smallest: one process, no Shamir; a
# crash re-seals, you re-unseal. 5+ adds single-host worker resilience (not HA);
# 2-4 floor to 5. Details: docs/SHAMIR.md.
#
# Each worker uses ~80-150MB at idle ; Argon2id derives at unseal use
# up to 256MB transiently on whichever worker handles /unseal.
RH_WORKERS=5
# Shamir share distribution. 0 = auto-derive from RH_WORKERS :
# total = max(5, RH_WORKERS)
# threshold = max(2, total // 2 + 1) # majority quorum
# Override only if you have an asymmetric quorum need. Larger total =
# more failover redundancy ; threshold = how many shares are required to
# reconstruct sub-keys after master loss.
# RH_CLUSTER_SHAMIR_TOTAL=0
# RH_CLUSTER_SHAMIR_THRESHOLD=0
# Failover timing. These three are only meaningful together, and rhorizon
# refuses to start on a combination that cannot work (watch interval must not
# exceed the timeout; the RPC deadline must exceed it).
#
# master timeout : how long a master may go silent before the survivors
# declare it lost and reconstruct from Shamir shares.
# watch interval : how often a follower checks. Half the timeout by default,
# so detection latency stays bounded without adding
# database load proportional to worker count.
# rpc timeout : per-call deadline on crypto ops sent to the master.
#
# The default was 5s, which bets that a silent master is a dead master. Under
# heavy IO that bet is wrong: a worker starved on iowait stops heartbeating
# while still holding its sub-keys, and a short deadline turns a recoverable
# stall into a full reconstruction -- more load, on a machine already
# collapsing. 120s waits for the box to come back instead.
#
# Raise further on storage that stalls for minutes. Lower only where a fast,
# clean failover matters more than surviving a stall (and remember the RPC
# deadline has to stay above the master timeout).
# RH_CLUSTER_MASTER_TIMEOUT_SECS=120
# RH_CLUSTER_MASTER_WATCH_INTERVAL_SECS=60
# RH_CLUSTER_RPC_TIMEOUT_SECS=180
# Where the crypto keys live.
#
# embedded (default) : the API workers hold the Shamir shares themselves.
# separated : a fixed custodian pool holds them and the API workers
# become disposable clients that never see key material.
#
# In separated mode the backend picks what a custodian IS:
#
# python : a full uvicorn process per slot, 160MB each
# rust : a small mlock'd daemon per slot, ~3MB each. Requires separated.
#
# Both pools run in the same container, so both count against RH_API_MEM.
# Sizing and the full tuning table: docs/docs/howto/capacity-planning.md.
#
# RH_CUSTODY_MODE=embedded
# RH_CUSTODY_BACKEND=python
# Custodian quorum size. Odd values only, so a majority is well defined.
# RH_CUSTODIAN_WORKERS applies to the python backend, RH_RUST_CUSTODIAN_SLOTS
# to the rust one; threshold 0 selects the majority.
#
# Preset | Workers | Rust slots | Quorum | Survives
# -------------+---------+------------+--------+---------------------------
# home | 1 | - | - | embedded, keys in-process
# smb | 5 | 5 | 3-of-5 | 2 lost custodians
# heavy | 10 | 7 | 4-of-7 | 3
# super-heavy | 20 | 9 | 5-of-9 | 4
#
# READ AT LAUNCH. A running pool cannot be reshaped, and a pool that already
# holds shares will not start under a different shape -- the launcher resolves
# the shape it actually holds and says so rather than obeying blindly. Changing
# these on a live deployment starts a topology change, it does not take effect
# immediately.
#
# NO SOFT LANDING: losing custodian share state below the quorum does not
# degrade the vault, it stops the API from starting, and the master password
# does not recover it. Back up RH_RUST_CUSTODIAN_KEY_DIR (transport keys AND
# share state, mode 0600) alongside your database.
#
# RH_CUSTODIAN_WORKERS=5
# RH_RUST_CUSTODIAN_SLOTS=3
# RH_RUST_CUSTODIAN_THRESHOLD=0
# RH_RUST_CUSTODIAN_KEY_DIR=/var/lib/rhorizon/custody
# Provider-neutral PostgreSQL HA health shown in the cluster management panel.
# Supported providers:
# Patroni: provider=patroni, endpoints are Patroni REST base URLs (:8008)
# pgha: provider=pgha, endpoints are pgha agent status base URLs (:8010)
# "auto" preserves old Patroni deployments and selects pgha when the generic
# status URLs are set. Unknown/grey database HA is rejected by K7.
# RH_DATABASE_HA_PROVIDER=patroni
# RH_DATABASE_HA_STATUS_URLS=http://pg-1:8008,http://pg-2:8008,http://pg-3:8008
# RH_DATABASE_HA_MAX_REPLICA_LAG_BYTES=16777216
# RH_DATABASE_HA_STATUS_MAX_AGE_SECS=15
#
# Deprecated compatibility aliases:
# RH_PATRONI_REST_URLS=http://pg-1:8008,http://pg-2:8008,http://pg-3:8008
# RH_PATRONI_MAX_REPLICA_LAG_BYTES=16777216
# Auto-seal after N minutes of inactivity (0 = disabled)
RH_AUTO_SEAL_MINUTES=0
# Enable Swagger UI + ReDoc at /docs and /redoc (default: disabled)
# RH_ENABLE_DOCS=true
# Auth failure log (fail2ban)
# Log path inside the container (mounted via audit_logs volume)
RH_AUTHFAIL_LOG=/var/log/rhorizon/authfail.log
# Audit retention. Every audited event is written twice: a signed, chained row
# in the database and a line in the daily archive file. Completed archive days
# are SEALED -- content digest, entry count and chain endpoints signed back
# into the chain -- which is what makes a truncated file or a deleted day
# detectable, and what makes pruning the database safe.
#
# retention_days compliance floor on the archive FILES. 365-3650.
# Nothing deletes a file before this.
# compress_days gzip archive files older than N days. 1..retention.
# db_retention_days how long the chain stays in the DATABASE -- a working
# set for querying and /audit/verify, NOT the evidence
# store. 1..retention. Rows are pruned only once their
# day is sealed and that seal still verifies.
#
# db_retention_days is ceilinged at retention_days on purpose: pruning a row
# whose archive file has already been deleted would put a hole in the record
# that nothing detects.
# RH_AUDIT_RETENTION_DAYS=365
# RH_AUDIT_COMPRESS_DAYS=1
# RH_AUDIT_DB_RETENTION_DAYS=30
#
# Pruning DELETES chain rows from the database once the archive provably holds
# them. On by default, and nothing is lost by it: a day goes only when it is
# past the window, sealed (its archive cross-checked against the database rows
# while both copies still existed), and its seal still verifies against the
# file. An anchor is written first so the surviving chain stays verifiable, and
# deleting anything beyond that anchor is still reported as a break.
#
# Set false to keep the entire chain in the database instead; raising
# RH_AUDIT_DB_RETENTION_DAYS says the same thing with a window.
# RH_AUDIT_DB_PRUNE_ENABLED=true
# Read-audit Merkle checkpoints. Read events stay in vault_audit_lite without
# per-row signatures; a background singleton periodically signs a Merkle root
# into the chained audit log.
# RH_AUDIT_LITE_CHECKPOINT_ENABLED=true
# RH_AUDIT_LITE_CHECKPOINT_INTERVAL_SECS=60
# RH_AUDIT_LITE_CHECKPOINT_MAX_ROWS=10000
# Rate limiting
# IPs that bypass rate limiting (comma-separated)
RH_RATE_LIMIT_WHITELIST=10.0.0.1,10.0.0.1
# Request size limits
# Nginx (frontend proxy)
MAX_BODY_API=1m # all API endpoints
MAX_BODY_BACKUP=100m # backup restore only
# FastAPI (defense-in-depth for direct API access)
RH_MAX_BODY_BYTES=1048576 # 1 MB
RH_MAX_BODY_BACKUP=104857600 # 100 MB
# TLS (optional, disabled by default)
# Enable HTTPS on nginx :8443
TLS_ENABLED=false
TLS_CERT=/certs/cert.pem
TLS_KEY=/certs/key.pem
TLS_CERT_DIR=./certs # host path mounted as /certs in container
# SSO proxy auth (Authelia / Authentik / Keycloak)
# Enable to trust Remote-User / Remote-Groups headers from reverse proxy
# RH_PROXY_AUTH_ENABLED=true
# RH_PROXY_USER_HEADER=Remote-User
# RH_PROXY_GROUPS_HEADER=Remote-Groups
# RH_PROXY_SESSION_TTL_HOURS=8
#
# RH_PROXY_TRUSTED_IPS, comma-separated CIDRs serving two roles:
# 1. SSO header trust (when proxy_auth_enabled=true)
# 2. X-Forwarded-For parsing for audit-log client IP recovery
# Default (all RFC 1918 + IPv6 ULA + loopback) makes audit IPs work
# out-of-the-box on any private infra. Tighten if you run on a shared
# / multi-tenant network. Editable at runtime via Cluster → SSO in the
# UI, no restart needed.
# RH_PROXY_TRUSTED_IPS=127.0.0.0/8,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7
# Network
# VPN IPs (machine-to-machine + admin)
WG1_IP=10.0.1.1
WG_IP=10.0.0.1
# Domain for Traefik (HTTPS + Authelia SSO)
VAULT_DOMAIN=vault.example.com
# Authelia middleware name in Traefik
AUTHELIA_MIDDLEWARE=authelia@file