mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 15:31:38 +02:00
docs: operator console guide + fix example recipes + document all env vars
- New docs/operations/CONSOLE.md: reaching /admin, NIP-98 login, the defaults->env->DB precedence model, per-section runtime-safe vs restart-required table, expected_versions concurrency, restart_apply_mode (with the systemd Restart=always requirement for auto), clearing a DB override. Linked from README + OPERATOR_SETUP. - All six example recipes gained an explicit chain-enablement block (FEATURE_XMR/WOW on, BTC/LTC/GRIN off) so they no longer hard-fail Config::validate in production (default-on chains with empty sources). - Documented all 16 previously-undocumented env vars in .env.example (RESTART_APPLY_MODE, TOR_ADMIN_ONION, DEPLOYMENT_MODE, TIP_SHARE_BASE_URL, ...); RELAY.md gained the premium-post policy + RELAY_WRITE_ALLOWLIST_NPUBS; ADMIN_PUBKEYS noted as reserved/inert.
This commit is contained in:
+85
-1
@@ -13,6 +13,19 @@ SERVER_PORT=8080
|
||||
# so every real deployment must replace it.
|
||||
PUBLIC_API_URL=https://backend.example.org/api/v1
|
||||
ENVIRONMENT=development
|
||||
# Deployment topology: single (default) permits in-process challenge/nonce state;
|
||||
# fleet means a load-balanced set of instances and requires shared/stateless
|
||||
# challenge state. Must be single|fleet or boot fails.
|
||||
DEPLOYMENT_MODE=single
|
||||
# Comma-separated CIDRs or bare IPs whose X-Forwarded-For is trusted for the
|
||||
# client IP (rate-limiting + audit). Empty (default) = always use the real TCP
|
||||
# peer. Set this to your reverse proxy's address(es) when it terminates TLS.
|
||||
TRUSTED_PROXIES=
|
||||
# Comma-separated browser origins allowed by CORS (e.g. the web wallet). Empty
|
||||
# (default) allows any origin — safe here because auth is a Bearer token, not a
|
||||
# cookie, so no ambient credentials ride a cross-origin request. Credentials are
|
||||
# never allowed.
|
||||
CORS_ALLOWED_ORIGINS=
|
||||
|
||||
# ── Database ──────────────────────────────────────────────────────────────
|
||||
DATABASE_URL=postgres://user:password@127.0.0.1:5432/smirk
|
||||
@@ -36,6 +49,10 @@ FEATURE_POW=false
|
||||
ALTCHA_HMAC_KEY=
|
||||
POW_REQUIRED=false
|
||||
ALTCHA_COST=100000
|
||||
# Testing aid: comma-separated lowercase pubkey hashes that ALWAYS require PoW,
|
||||
# even when POW_REQUIRED=false (opt-in, for exercising the gate). Requires
|
||||
# FEATURE_POW=true or boot fails closed. Leave empty in normal deployments.
|
||||
TEST_POW_REQUIRED_FOR_PUBKEYS=
|
||||
|
||||
# ── Registration gates (composable; each advertised via /capabilities) ────
|
||||
# Require an operator-minted invite code to create a NEW wallet. Mint codes with
|
||||
@@ -74,10 +91,32 @@ PAYMENT_EXPIRES_MINUTES=60
|
||||
# enabled the two modes are identical.
|
||||
REGISTRATION_GATE_MODE=all
|
||||
|
||||
# ── Chain enablement (each chain is independently feature-flagged) ─────────
|
||||
# All default to TRUE. FAIL-CLOSED RULE: in production, an ENABLED chain with no
|
||||
# source configured makes the server REFUSE TO BOOT — a chain that cannot be
|
||||
# served must not advertise itself as available via /capabilities. So set the
|
||||
# ones you do not run to false, or configure the source for each you keep on:
|
||||
# BTC / LTC — an electrum/Fulcrum URL (BTC_ELECTRUM_URL / LTC_ELECTRUM_URL) or
|
||||
# a fallback list.
|
||||
# XMR / WOW — the *_LWS_ADMIN_KEY (plus its LWS + daemon URLs).
|
||||
# GRIN — GRIN_OWNER_API_SECRET (plus the GRIN_* wallet/node wiring).
|
||||
# In development these are warnings rather than a hard boot error.
|
||||
FEATURE_BTC=true
|
||||
FEATURE_LTC=true
|
||||
FEATURE_XMR=true
|
||||
FEATURE_WOW=true
|
||||
FEATURE_GRIN=true
|
||||
|
||||
# ── Bitcoin (Electrum/Fulcrum only; the backend runs no Core RPC node) ─────
|
||||
BTC_NETWORK=mainnet
|
||||
BTC_ELECTRUM_URL=
|
||||
BTC_ELECTRUM_FALLBACKS=
|
||||
# Require CA-verified TLS (webpki + hostname) for ssl:// electrum servers. Applies
|
||||
# to BOTH BTC and LTC. Default false: public electrum servers are self-signed by
|
||||
# convention and their data is treated as hostile regardless, so accepting any
|
||||
# cert keeps the public fallbacks usable. Set true if you run your own CA-cert'd
|
||||
# Fulcrum and want to harden.
|
||||
ELECTRUM_STRICT_TLS=false
|
||||
|
||||
# ── Litecoin (Electrum/Fulcrum only; the backend runs no Core RPC node) ────
|
||||
LTC_NETWORK=mainnet
|
||||
@@ -142,8 +181,26 @@ WALLET_RESTORE_POW_MAX_BITS=24
|
||||
FEATURE_PRICES=true
|
||||
PRICES_PROVIDER=coingecko
|
||||
PRICES_FETCH_INTERVAL_SECS=300
|
||||
# Which assets the price feed quotes. UNSET = all supported (btc,ltc,xmr,wow,grin);
|
||||
# a subset like "btc,xmr" narrows it; PRESENT-BUT-EMPTY (PRICES_ASSETS= with no
|
||||
# value) means none. Leave commented to serve all.
|
||||
#PRICES_ASSETS=
|
||||
# Currency the feed quotes in. One of: usd, eur, gbp, jpy, cny, aud, cad, chf, btc.
|
||||
# A typo fails closed at boot (rather than serving an empty feed).
|
||||
PRICES_CURRENCY=usd
|
||||
# Nostr-native identity (NIP-98 login/link, NIP-05 directory). ON by default; when
|
||||
# on, PUBLIC_API_URL is required (and must be https in production).
|
||||
FEATURE_NOSTR_IDENTITY=true
|
||||
# Grin slatepack relay: a non-custodial encrypted store-and-forward mailbox for
|
||||
# interactive Grin transfers. ON by default; can be disabled independently of Grin
|
||||
# chain access.
|
||||
FEATURE_GRIN_RELAY=true
|
||||
# Tips are parked for the conditional-transfer redesign; off until that lands.
|
||||
FEATURE_TIPS=false
|
||||
# Base URL for public-tip share links (a tip's share URL is {base}/{tip_id}).
|
||||
# REQUIRED when FEATURE_TIPS=true (boot fails closed without it); never hardcode a
|
||||
# host, so federated/self-hosted instances build their own share links.
|
||||
TIP_SHARE_BASE_URL=
|
||||
|
||||
# ── Nostr relay (optional messaging plane; see docs/operations/RELAY.md) ────
|
||||
# Off by default. When on, the operator runs a relay (the packaged
|
||||
@@ -205,11 +262,21 @@ FEED_OWNER_NPUB=
|
||||
FEED_ALLOWLIST_NPUBS=
|
||||
FEED_EXTRA_RELAYS=
|
||||
|
||||
# ── Admin surface (see docs; default posture is loopback/Tor) ──────────────
|
||||
# ── Admin surface (see docs/operations/CONSOLE.md; default posture is loopback/Tor) ─
|
||||
# Admin auth is "Sign in with Smirk": only admin PUBLIC keys are stored here,
|
||||
# never a seed or private key. The allowlist is mutated CLI/loopback-only in v1.
|
||||
# When enabled, the embedded Operator Console SPA is served at /admin on this plane.
|
||||
ADMIN_ENABLED=false
|
||||
ADMIN_BIND=127.0.0.1:8081
|
||||
# Allow ADMIN_BIND to be a NON-loopback address. Default false: boot REFUSES a
|
||||
# public admin bind (confidentiality is by socket). Only set true if you front the
|
||||
# plane with Tor client-auth or a trusted proxy and firewall it.
|
||||
ADMIN_ALLOW_PUBLIC_BIND=false
|
||||
# Tor onion host you reach the admin plane at (e.g. <hash>.onion). REQUIRED for the
|
||||
# Tor-onion posture: it is added to the admin Host allowlist, so without it a
|
||||
# request whose Host header is the onion is rejected 403 (anti DNS-rebinding).
|
||||
# Never logged or surfaced publicly. Leave empty for the loopback/SSH-tunnel path.
|
||||
TOR_ADMIN_ONION=
|
||||
# Public absolute URL of THIS node's admin surface. The per-node id that binds
|
||||
# signed admin actions (so a challenge signed for one node can't be replayed to
|
||||
# another across a fleet) is DERIVED from this value — give each node in a fleet a
|
||||
@@ -221,6 +288,17 @@ ADMIN_JWT_SECRET=
|
||||
ADMIN_KEY_INTEGRITY_SECRET=
|
||||
ADMIN_MAX_KEYS=8
|
||||
ADMIN_PENDING_KEY_TTL_DAYS=7
|
||||
# RESERVED / inert: ADMIN_PUBKEYS is parsed but NOT consumed anywhere in this
|
||||
# version — it does not gate admin access. Authorization is the MAC-protected key
|
||||
# allowlist in the database (managed via `smirk-admin` and the console Keys tab),
|
||||
# never this variable. Leave it unset; setting it has no effect.
|
||||
ADMIN_PUBKEYS=
|
||||
# How the Operator Console applies a RESTART-REQUIRED config change (see CONSOLE.md):
|
||||
# manual (default) — persist + flag; you apply it with a graceful restart.
|
||||
# auto — the instance self-restarts after saving. REQUIRES a
|
||||
# supervisor that brings it back (systemd Restart=always);
|
||||
# otherwise it goes down and stays down.
|
||||
RESTART_APPLY_MODE=manual
|
||||
|
||||
# ── Public landing page (OFF by default; full + per-field tunable when on) ──
|
||||
PUBLIC_LANDING_ENABLED=false
|
||||
@@ -234,9 +312,15 @@ PUBLIC_STATS_ENABLED=false
|
||||
PUBLIC_STATS_CACHE_HOURS=24
|
||||
|
||||
# ── Data retention / erasure ──────────────────────────────────────────────
|
||||
# When ERASURE_ENABLED=true, self-service erasure needs ADMIN_KEY_INTEGRITY_SECRET
|
||||
# (its audit trail is the integrity-MAC'd hash chain) and PUBLIC_API_URL (its
|
||||
# proofs bind that URL); boot fails closed otherwise.
|
||||
ERASURE_ENABLED=false
|
||||
ERASURE_PURGE_LOGIN_EVENTS=true
|
||||
ERASURE_EXPORT_PER_DAY=3
|
||||
# Grace window (hours) between a confirmed erasure and its execution. Max 87600
|
||||
# (10 years).
|
||||
ERASURE_GRACE_PERIOD_HOURS=72
|
||||
# Log retention (auto-deletion); 0 = keep indefinitely.
|
||||
RETENTION_LOGIN_EVENTS_DAYS=90
|
||||
RETENTION_AUDIT_DAYS=365
|
||||
|
||||
Reference in New Issue
Block a user