-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy path.env.example
More file actions
426 lines (390 loc) · 21.3 KB
/
Copy path.env.example
File metadata and controls
426 lines (390 loc) · 21.3 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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# ============================================================
# Nora — Environment Configuration
# ============================================================
# Copy this file to .env and replace all <REPLACE_...> values.
#
# Generate secrets with:
# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# setup.sh keeps this file at mode 0600; setup.ps1 removes inherited access and
# grants only the current user, SYSTEM, and local Administrators on Windows.
# Production Compose and Helm mount core values under /run/secrets. Nora's
# production entrypoint also accepts the conventional *_FILE variables below
# for custom orchestrators; a non-empty direct value takes precedence.
# setup materializes Compose-only copies under this gitignored owner-only
# directory so read-only containers can mount them without inline secrets.
NORA_COMPOSE_SECRETS_DIR=.secrets/compose
# ============================================================
# ── Required ─────────────────────────────────────────────────
JWT_SECRET=<REPLACE_WITH_RANDOM_SECRET> # min 32 chars — used to sign JWTs
ENCRYPTION_KEY=<REPLACE_WITH_64_HEX_CHARS> # 32-byte hex key for AES-256-GCM (run the command above)
NORA_BACKUP_ENCRYPTION_KEY=<REPLACE_WITH_64_HEX_CHARS> # 32-byte hex key for managed backup archives; do not rotate casually
NORA_AGENT_HUB_API_KEY_HASH_SECRET=<REPLACE_WITH_RANDOM_SECRET> # setup/update auto-generates when missing; do not rotate casually
NORA_API_KEY_HASH_SECRET=<REPLACE_WITH_RANDOM_SECRET> # primary workspace/API token hash secret; setup preserves the legacy fallback value
# JWT_SECRET_FILE=/run/secrets/JWT_SECRET
# ENCRYPTION_KEY_FILE=/run/secrets/ENCRYPTION_KEY
# NORA_BACKUP_ENCRYPTION_KEY_FILE=/run/secrets/NORA_BACKUP_ENCRYPTION_KEY
# NORA_AGENT_HUB_API_KEY_HASH_SECRET_FILE=/run/secrets/NORA_AGENT_HUB_API_KEY_HASH_SECRET
# NORA_API_KEY_HASH_SECRET_FILE=/run/secrets/NORA_API_KEY_HASH_SECRET
# In production the backend refuses to boot when JWT_SECRET is missing/placeholder
# or ENCRYPTION_KEY is missing/invalid. To deliberately run without encryption at
# rest (e.g. a throwaway demo), set the explicit override:
# NORA_ALLOW_PLAINTEXT_SECRETS=true
# ── Bootstrap Admin Account (required for empty PaaS; optional for self-hosted) ──
# On an empty user database, hosted PaaS requires both values. Self-hosted installs may blank both
# to use first-account claim. Setting either value makes this a startup gate: placeholders,
# malformed email, short passwords, and default-derived passwords are rejected.
DEFAULT_ADMIN_EMAIL=<REPLACE_WITH_BOOTSTRAP_ADMIN_EMAIL>
DEFAULT_ADMIN_PASSWORD=<REPLACE_WITH_STRONG_BOOTSTRAP_PASSWORD> # min 12 chars; no insecure defaults
# ── Database (defaults work with Docker Compose) ─────────────
DB_HOST=postgres
DB_USER=nora
DB_PASSWORD=<REPLACE_WITH_YOUR_DB_PASSWORD>
# DB_PASSWORD_FILE=/run/secrets/DB_PASSWORD
DB_NAME=nora
DB_PORT=5432
# ── Redis (defaults work with Docker Compose) ────────────────
REDIS_HOST=redis
REDIS_PORT=6379
PORT=4000
BACKEND_API_PORT=4100 # host-only backend API port; setup auto-picks another free port when 4100 is busy
# Numeric group owner of /var/run/docker.sock. setup auto-detects it so the
# non-root API/workers can use the Docker API without running as root.
DOCKER_GID=0
# Stable Compose namespace used by setup for scoped starts, upgrades, and
# destructive clean-reinstall cleanup.
COMPOSE_PROJECT_NAME=nora
# Managed/external service connection options. DATABASE_URL/REDIS_URL take
# precedence over the host/port fields above. Verification modes fail closed
# when their CA is missing.
DATABASE_URL=
DB_SSL_MODE= # blank honors URL sslmode; or disable | require | verify-ca | verify-full
DB_SSL_CA=
DB_SSL_CA_FILE=
DB_SSL_CERT=
DB_SSL_CERT_FILE=
DB_SSL_KEY=
DB_SSL_KEY_FILE=
DB_POOL_MAX=20
DB_IDLE_TIMEOUT_MS=30000
DB_CONNECTION_TIMEOUT_MS=10000
DB_STATEMENT_TIMEOUT_MS=0
DB_MIGRATION_LOCK_TIMEOUT_MS=60000
DB_MIGRATION_STATEMENT_TIMEOUT_MS=600000
REDIS_URL=
REDIS_USERNAME=
REDIS_PASSWORD=
REDIS_DB=
REDIS_TLS=false
REDIS_TLS_CA=
REDIS_TLS_CA_FILE=
REDIS_TLS_CERT=
REDIS_TLS_CERT_FILE=
REDIS_TLS_KEY=
REDIS_TLS_KEY_FILE=
REDIS_TLS_INSECURE_SKIP_VERIFY=false
REDIS_CONNECT_TIMEOUT_MS=10000
# ── Deployment Queue / Provisioner throughput ──────────────
# Higher values reduce time spent in "queued" under bursty deploy load, but
# increase image-pull/bootstrap pressure on the host.
DEPLOYMENT_WORKER_CONCURRENCY=6
# ── Access / URL ─────────────────────────────────────────────
# Local default:
# NGINX_CONFIG_FILE=nginx.conf
# NGINX_HTTP_PORT=8080
# NEXTAUTH_URL=http://localhost:8080
# Public domain:
# NGINX_CONFIG_FILE=nginx.public.conf
# NGINX_HTTP_PORT=80
# NEXTAUTH_URL=https://app.example.com
# CORS_ORIGINS=https://app.example.com
NGINX_CONFIG_FILE=nginx.conf
NGINX_HTTP_PORT=8080
# Force the Secure flag on the session cookie for always-on-TLS public deploys.
# Set to 1 for https public modes; leave empty for local http. Without it the
# Secure flag relies on X-Forwarded-Proto, which an upstream proxy/CDN may strip.
NORA_FORCE_SECURE_COOKIES=
# ── API Request Rate Limits (per IP) ───────────────────────
# App-wide abuse protection. Defaults below are the production values; raise
# them only where many requests legitimately share one source IP (e.g. CI/E2E
# behind a single localhost address). Unset means the default applies.
GLOBAL_RATE_LIMIT_MAX=1000 # all requests per IP/window
GLOBAL_RATE_LIMIT_WINDOW_MS=900000 # 15 minutes
MUTATION_RATE_LIMIT_MAX=60 # POST/PUT/PATCH/DELETE per IP/window
MUTATION_RATE_LIMIT_WINDOW_MS=60000 # 1 minute
# ── OAuth (disabled by default until provider verification is completed) ──
# Password and OAuth login share this per-IP abuse-protection budget.
AUTH_RATE_LIMIT_MAX=20
AUTH_RATE_LIMIT_WINDOW_MS=900000 # 15 minutes
OAUTH_LOGIN_ENABLED=false
GOOGLE_CLIENT_ID=<REPLACE_WITH_GOOGLE_CLIENT_ID>
GOOGLE_CLIENT_SECRET=<REPLACE_WITH_GOOGLE_CLIENT_SECRET>
GITHUB_CLIENT_ID=<REPLACE_WITH_GITHUB_CLIENT_ID>
GITHUB_CLIENT_SECRET=<REPLACE_WITH_GITHUB_CLIENT_SECRET>
NEXTAUTH_URL=http://localhost:8080 # public base URL; kept for compatibility with existing deploy envs
# ── Public Signup Abuse Protection ──────────────────────────
# Signup stays public, but these app-level limits keep automated spikes bounded.
SIGNUP_RATE_LIMIT_BURST_MAX=5
SIGNUP_RATE_LIMIT_BURST_WINDOW_MS=600000 # 10 minutes
SIGNUP_RATE_LIMIT_DAILY_MAX=20
SIGNUP_RATE_LIMIT_DAILY_WINDOW_MS=86400000 # 24 hours
# Optional bot challenge. Leave provider as none for local/self-hosted default.
# Choose one provider at runtime: none | turnstile | recaptcha. The backend
# publishes only the selected provider and public site key to the signup page.
SIGNUP_BOT_PROTECTION_PROVIDER=none
SIGNUP_TURNSTILE_SITE_KEY=
SIGNUP_TURNSTILE_SECRET= # server-only; never exposed to the browser
SIGNUP_RECAPTCHA_SITE_KEY=
SIGNUP_RECAPTCHA_SECRET= # server-only; never exposed to the browser
# Deprecated NEXT_PUBLIC_SIGNUP_* aliases remain readable at runtime for
# existing installs, but new deployments should use the variables above.
# ── Marketing site analytics (optional, Plausible) ──────────
# Off by default — self-hosted deployments ship zero tracking. Set the domain
# to enable privacy-light analytics on the marketing site. Point ANALYTICS_SRC
# at a self-hosted Plausible instance instead of plausible.io if you run one.
NEXT_PUBLIC_ANALYTICS_DOMAIN=
# NEXT_PUBLIC_ANALYTICS_SRC=https://plausible.io/js/script.js
# ── Release Tracking / Admin Upgrade Banner (optional) ──────
# Set NORA_CURRENT_VERSION from your deploy pipeline. If NORA_GITHUB_REPO
# is set, Nora will fetch the latest published GitHub release automatically
# and compare it against the running version.
#
# Typical GitHub release notes URL:
# https://github.com/<owner>/<repo>/releases/tag/v1.2.3
#
# Typical source-based self-hosted upgrade command:
# ./setup.sh --update
NORA_CURRENT_VERSION=
NORA_CURRENT_COMMIT=
NORA_GITHUB_REPO=solomon2773/nora
NORA_GITHUB_TOKEN= # optional; helps with GitHub API rate limits
NORA_RELEASE_CACHE_TTL_MS=300000 # 5 minutes
NORA_LATEST_VERSION=
NORA_LATEST_PUBLISHED_AT=
NORA_RELEASE_NOTES_URL=
NORA_LATEST_SEVERITY=warning # info | warning | critical
NORA_UPGRADE_REQUIRED=false
NORA_AUTO_UPGRADE_ENABLED=false # opt-in one-click upgrades from Admin Settings
NORA_HOST_REPO_DIR= # absolute Linux host path to this Nora checkout; setup fills this
NORA_UPGRADE_REPO=https://github.com/solomon2773/nora.git
NORA_UPGRADE_REF=master
NORA_UPGRADE_RUNNER_IMAGE=docker:29-cli
NORA_UPGRADE_STATE_VOLUME=nora_upgrade_state
NORA_ENV_FILE=.env # deploy env file passed to docker compose
NORA_UPGRADE_COMPOSE_FILES= # colon-separated compose files; blank auto-detects current stack
NORA_UPGRADE_PUBLIC_HEALTH_URL= # optional public /api/health URL checked after rebuild
# Shared by setup post-start probes and one-click upgrade health checks.
# 221 attempts, 3s apart = 660s from the first to final attempt. Overrides
# must be positive integers with a first-to-final window no greater than 3900s.
NORA_UPGRADE_HEALTHCHECK_ATTEMPTS=221
NORA_UPGRADE_HEALTHCHECK_INTERVAL_SECONDS=3
NORA_INSTALL_METHOD=source # source | docker_image | custom
NORA_MANUAL_UPGRADE_COMMAND=./setup.sh --update
# Optional advanced override. Leave unset to use the built-in default steps.
NORA_MANUAL_UPGRADE_STEPS=
# ── System Banner / Testing Warning (optional) ───────────────
# Master switch for the admin-configured banner shown across /app and /admin.
# Banner copy and severity are managed from the admin settings page.
NORA_SYSTEM_BANNER_ENABLED=false
# ── Platform Mode ─────────────────────────────────────────────
# "selfhosted" (default) — operator sets max resource limits below;
# users pick vCPU/RAM/disk within those limits.
# "paas" — Stripe plans control agent-count and managed-backup
# entitlements; Admin deployment defaults supply one
# platform-wide vCPU/RAM/requested-disk profile.
PLATFORM_MODE=selfhosted
# ── Self-hosted resource limits (only when PLATFORM_MODE=selfhosted) ─
MAX_VCPU=16
MAX_RAM_MB=32768
MAX_DISK_GB=500
MAX_AGENTS=50
# ── Managed Backups ──────────────────────────────────────────
# NORA_BACKUP_STORAGE can be local, s3, r2, or ssh. Leave destination env
# values empty to use Admin Settings and the default local backup volume.
NORA_BACKUP_STORAGE=
NORA_BACKUP_DIR=
NORA_BACKUP_LIMIT_PER_AGENT=10
NORA_BACKUP_STORAGE_MB=51200
NORA_BACKUP_RETENTION_DAYS=30
BACKUP_WORKER_CONCURRENCY=2
NORA_BACKUP_JOB_TIMEOUT_MS=1800000
NORA_BACKUP_SCHEDULE_POLL_MS=60000
AGENT_PROVISION_LOCK_TIMEOUT_MS=30000
# S3-compatible storage. Use NORA_BACKUP_STORAGE=s3 for AWS S3.
NORA_BACKUP_S3_BUCKET=
NORA_BACKUP_S3_REGION=
NORA_BACKUP_S3_ENDPOINT=
NORA_BACKUP_S3_ACCESS_KEY_ID=
NORA_BACKUP_S3_SECRET_ACCESS_KEY=
NORA_BACKUP_S3_SESSION_TOKEN=
# Cloudflare R2. Set the account endpoint, for example:
# https://<account-id>.r2.cloudflarestorage.com
NORA_BACKUP_R2_BUCKET=
NORA_BACKUP_R2_REGION=
NORA_BACKUP_R2_ENDPOINT=
NORA_BACKUP_R2_ACCESS_KEY_ID=
NORA_BACKUP_R2_SECRET_ACCESS_KEY=
NORA_BACKUP_R2_SESSION_TOKEN=
# SSH/SFTP remote storage.
NORA_BACKUP_SSH_HOST=
NORA_BACKUP_SSH_PORT=
NORA_BACKUP_SSH_USERNAME=
NORA_BACKUP_SSH_REMOTE_PATH=
NORA_BACKUP_SSH_PRIVATE_KEY=
NORA_BACKUP_SSH_PASSWORD=
# ── Billing / Stripe (only when PLATFORM_MODE=paas) ─────────
BILLING_ENABLED=false
STRIPE_SECRET_KEY=<REPLACE_WITH_STRIPE_SECRET_KEY> # sk_test_... or sk_live_...
STRIPE_WEBHOOK_SECRET=<REPLACE_WITH_STRIPE_WEBHOOK_SECRET> # whsec_...
STRIPE_PRICE_PRO=<REPLACE_WITH_STRIPE_PRICE_ID> # price_...
STRIPE_PRICE_ENTERPRISE=<REPLACE_WITH_STRIPE_PRICE_ID> # price_...
# ── Cost reporting (optional; used by /app/cost) ─────────────
COST_PER_1K_TOKENS=0.002
# Optional per-model token rates. Keys may be model ids or provider/model ids.
# Split rates are used when Nora records input/output token metadata; per_1k
# is used when only total tokens are available.
COST_MODEL_RATES_JSON={"openai/gpt-5.5":{"input_per_1k":0.002,"output_per_1k":0.008},"claude-sonnet-4-5":{"input_per_1k":0.003,"output_per_1k":0.015},"gemini-3.1-pro-preview":{"input_per_1k":0.00125,"output_per_1k":0.01}}
# ── OpenTelemetry GenAI export (optional; off by default) ────
# Export per-exchange chat spans + token/cost/resource metrics under the OTel
# gen_ai.* semantic conventions. Disabled unless NORA_OTEL_ENABLED=true, and
# fully fail-open (a collector outage never affects request handling).
NORA_OTEL_ENABLED=false
# OTLP/HTTP push target for metrics AND spans (e.g. an OpenTelemetry Collector,
# Grafana Alloy, or a vendor endpoint). OTEL_EXPORTER_OTLP_HEADERS is read
# natively by the exporters for auth.
OTEL_EXPORTER_OTLP_ENDPOINT=
# OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer%20<token>
OTEL_SERVICE_NAME=nora-control-plane
# Prometheus pull endpoint for metrics (0 or empty disables). Defaults to
# loopback — the scrape surface is unauthenticated and its labels (agent id /
# model / provider) are operational intelligence, so widen the bind only behind
# an internal network or firewall. Spans are OTLP-only (Prometheus carries
# metrics, not traces).
NORA_OTEL_PROMETHEUS_PORT=9464
NORA_OTEL_PROMETHEUS_HOST=127.0.0.1
# ── Scheduled agent runs (recurring cron triggers) ──────────
# Minimum seconds between fires for any schedule — a guardrail so a too-frequent
# cron can't thrash an agent (and its budget). Default 60s.
NORA_SCHEDULE_MIN_INTERVAL_SECONDS=60
# Worker concurrency for executing due scheduled runs (default 5).
SCHEDULE_RUN_WORKER_CONCURRENCY=5
# ── Runtime families, deploy targets, and sandbox profiles ───
# High-level runtime contracts. Supported ids: openclaw, hermes.
ENABLED_RUNTIME_FAMILIES=openclaw
#
# Execution target ids. Supported ids: docker, proxmox.
# Local no-cluster fallback:
ENABLED_BACKENDS=docker
# Docker-published agent gateway/runtime ports bind to loopback by default.
# This governs ALL local Docker runtime families (OpenClaw gateway/runtime and
# Hermes runtime API 8642 + dashboard 9119). To let an external client — e.g.
# Hermes Desktop over Tailscale — reach an agent, set this to a routable host
# interface (your Tailscale IP, e.g. 100.71.115.105). Never use 0.0.0.0 without
# a firewall or authenticated reverse proxy in front.
DOCKER_AGENT_BIND_IP=127.0.0.1
# Kubernetes clusters are registered in Admin -> Kubernetes; enabled registry
# rows appear as execution targets like k8s:aks-eastus2.
#
# Sandbox profile ids. Supported ids: standard, nemoclaw.
ENABLED_SANDBOX_PROFILES=standard
# Kubernetes Compose overlay mounts kubeconfigs only. Provider, namespaces,
# exposure, annotations, source ranges, and load-balancer class are configured
# in Admin -> Kubernetes.
# Kubeconfigs should be readable by Docker Compose but must not be committed;
# .secrets/ is gitignored for this purpose.
#
# Mounted-path mode:
# mkdir -p ./.secrets/kubeconfigs
# cp ./.secrets/aks-kubeconfig ./.secrets/kubeconfigs/aks-eastus2
# cp ./.secrets/aks-westus2-kubeconfig ./.secrets/kubeconfigs/aks-westus2
# Then use /kubeconfigs/<file> as each Admin Kubeconfig path. For one
# cluster, put one file in this directory and register one Admin row.
NORA_KUBECONFIGS_DIR=./.secrets/kubeconfigs
# Docker and remote-Docker agents reserve published gateway ports from this
# range. Values must stay within 19000-19999, which is the default gateway-proxy
# security envelope. Local Docker also skips ports already published by running
# containers and retries bounded bind conflicts from non-Docker listeners.
DOCKER_AGENT_PORT_RANGE_MIN=19000
DOCKER_AGENT_PORT_RANGE_MAX=19999
# Gateway proxy SSRF guard overrides. Defaults allow OpenClaw's internal
# gateway port, Docker-published 19000-19999, and Kubernetes NodePort 30000-32767.
NORA_GATEWAY_PROXY_ALLOWED_PORTS=
NORA_GATEWAY_PROXY_ALLOWED_HOSTS=
# Active Remote Docker gateway, log, and terminal streams periodically re-check
# the agent owner's current host grant. Values below 250 ms are clamped to 250.
REMOTE_HOST_AUTH_RECHECK_MS=1000
# Serialize create, edit, Test, SSH-pin reset, delete, share, and unshare for
# one Remote Docker host id.
# A timed-out competing mutation returns 409 instead of racing trust state.
REMOTE_HOST_MUTATION_LOCK_TIMEOUT_MS=15000
# ── Proxmox LXC (experimental; opt in with ENABLED_BACKENDS) ────────────
# OpenClaw works with a stock Ubuntu LXC template. Hermes requires a prepared
# template. Run the real-host smoke before production use. NemoClaw on Proxmox
# remains blocked because LXC does not implement its OpenShell sandbox contract.
PROXMOX_API_URL=<REPLACE_WITH_PROXMOX_URL> # https://proxmox.local:8006/api2/json
PROXMOX_TOKEN_ID=<REPLACE_WITH_TOKEN_ID> # user@pam!tokenname
PROXMOX_TOKEN_SECRET=<REPLACE_WITH_TOKEN_SECRET>
PROXMOX_VERIFY_TLS=true
PROXMOX_CA_CERT=
PROXMOX_CA_CERT_PATH=
# Test-only escape hatch for isolated HTTP fixtures. Never use in production.
PROXMOX_ALLOW_INSECURE_HTTP=false
PROXMOX_NODE=pve
PROXMOX_TEMPLATE=local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst
PROXMOX_HERMES_TEMPLATE=
PROXMOX_ROOTFS_STORAGE=local-lvm
PROXMOX_BRIDGE=vmbr0
PROXMOX_SSH_HOST=<REPLACE_WITH_PROXMOX_SSH_HOST>
PROXMOX_SSH_USER=root
PROXMOX_SSH_PORT=22
PROXMOX_SSH_PRIVATE_KEY=
PROXMOX_SSH_PRIVATE_KEY_PATH=
PROXMOX_SSH_PRIVATE_KEY_PASSPHRASE=
PROXMOX_SSH_PASSWORD=
PROXMOX_SSH_HOST_FINGERPRINT= # ssh-keyscan + ssh-keygen -lf output, SHA256:...
# Test-only escape hatch. Production must pin PROXMOX_SSH_HOST_FINGERPRINT.
PROXMOX_SSH_INSECURE_ACCEPT_HOST_KEY=false
# One command name or absolute executable path; arguments are rejected.
PROXMOX_PCT_COMMAND=pct
# Leave empty for root SSH. Non-root defaults to sudo -n; an override must be
# exactly sudo -n or an absolute sudo path followed by -n.
PROXMOX_SUDO=
# Root SSH is the supported baseline. Non-root SSH users must install a
# separately audited, narrowly scoped stopped-LXC staging helper on the
# Proxmox host and configure its one absolute executable path here.
PROXMOX_OFFLINE_STAGE_COMMAND=
PROXMOX_NODE_MAJOR=24
PROXMOX_OPENCLAW_PACKAGE=openclaw@2026.6.11
PROXMOX_HERMES_BIN=/opt/hermes/.venv/bin/hermes
# Hermes dashboard stays loopback-only unless this explicit insecure opt-in is set.
PROXMOX_HERMES_ENABLE_INSECURE_DASHBOARD=false
# ── NemoClaw / NVIDIA (when ENABLED_SANDBOX_PROFILES includes nemoclaw) ──
NVIDIA_API_KEY= # from build.nvidia.com
NEMOCLAW_DEFAULT_MODEL=nvidia/nemotron-3-super-120b-a12b
# Default: Nora-built image layering tsx + sandbox-writable runtime dirs on
# top of the upstream OpenShell base (agent-runtime/Dockerfile.nemoclaw-agent).
# Defaults to the Nora-published GHCR image. For offline hosts or private
# clusters, build/preload nora-nemoclaw-agent:local and override this value.
NEMOCLAW_SANDBOX_IMAGE=ghcr.io/solomon2773/nora-nemoclaw-agent:latest
# Nora's validated OpenClaw package. Override only for a deliberate compatibility test.
OPENCLAW_DOCKER_PACKAGE=openclaw@2026.6.11
# ── Security ─────────────────────────────────────────────────
CORS_ORIGINS=http://localhost:8080 # comma-separated; use your public origin when exposed on a domain
# ── LLM Key Storage: database (default) | env ───────────────
KEY_STORAGE=database
# If KEY_STORAGE=env, set provider credentials directly in this file instead
# of using Settings. Microsoft Foundry also needs the per-resource URL and
# deployment name because Azure deployments are operator-defined.
# MICROSOFT_FOUNDRY_API_KEY=
# MICROSOFT_FOUNDRY_BASE_URL=https://<resource>.services.ai.azure.com/openai/v1/
# MICROSOFT_FOUNDRY_DEPLOYMENT=gpt-5.5-1
# MICROSOFT_FOUNDRY_API_VERSION=
# ── Backups & TLS (optional) ─────────────────────────────────
TLS_CERT_PATH=
TLS_KEY_PATH=
AWS_S3_BUCKET=<REPLACE_WITH_S3_BUCKET_NAME>
AWS_ACCESS_KEY_ID=<REPLACE_WITH_AWS_ACCESS_KEY>
AWS_SECRET_ACCESS_KEY=<REPLACE_WITH_AWS_SECRET_KEY>
# When true, the provisioner reconciler uninstalls ClawHub skills present in a runtime
# container but not tracked in the agents table. OFF by default — leaving it unset only
# surfaces such drift as "orphaned" in the UI; operators remove orphans explicitly.
CLAWHUB_PRUNE_ORPHANED_SKILLS=false