mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 07:21:32 +02:00
Adversarial review of the relay admission surface: - FAIL-SAFE on admission death: nostr-rs-relay fails OPEN if its gRPC admission server is unreachable, so a dead admission = an unrestricted relay. The backend now EXITS if the admission service stops (supervisor restarts a clean pair); documented in RELAY.md. Pin the relay image to a digest (compose note). - Registration-oracle protection: validate() now refuses a non-loopback RELAY_ADMISSION_BIND unless RELAY_ADMISSION_ALLOW_PUBLIC=true (+ test). - No N+1 on crafted events: recipient p-tags are capped (20, deduped) and resolved in ONE batched query (db.any_registered_npub) instead of one-per-tag. - Defence-in-depth size cap: admission denies events over max_event_bytes before any DB work (the relay enforces its own limit too). - Docs: RELAY.md Security section (fail-open, loopback oracle, default PoW=0 spam footgun, client sender-verification); config.toml relay port 8088 (not 8080); Docker Hub image; .env.example RELAY_ADMISSION_ALLOW_PUBLIC. Note: the client-side sender-impersonation blocker is fixed separately in the monorepo (verifying gift-wrap unwrap).
52 lines
1.9 KiB
TOML
52 lines
1.9 KiB
TOML
# nostr-rs-relay config for a locked-down Smirk messaging relay.
|
|
#
|
|
# REFERENCE TEMPLATE — the exact key set is version-specific; check it against the
|
|
# nostr-rs-relay release you pin. The load-bearing piece is [grpc]
|
|
# event_admission_server: it points at the Smirk backend's gRPC admission service,
|
|
# which enforces RELAY_WRITE_POLICY + the NIP-13 PoW gate per event. Do NOT also
|
|
# set a static [authorization] pubkey_whitelist — that would double-gate and
|
|
# break the inbox (gift-wraps from non-registered senders).
|
|
|
|
[info]
|
|
relay_url = "wss://relay.example.org/"
|
|
name = "Smirk relay"
|
|
description = "Locked-down Nostr relay for a self-hosted Smirk backend (DM inbox)."
|
|
# pubkey = "<operator x-only hex pubkey>" # optional contact identity
|
|
|
|
[database]
|
|
# SQLite is simplest for a single-node self-host; switch to postgres to share
|
|
# infra. Keep it on a persisted volume (see docker-compose.yml).
|
|
engine = "sqlite"
|
|
data_directory = "/usr/src/app/db"
|
|
|
|
[grpc]
|
|
# Smirk backend event-admission (nauthz). With host networking the backend's
|
|
# loopback RELAY_ADMISSION_BIND is reachable here. This is what enforces the
|
|
# write policy — keep it set.
|
|
event_admission_server = "http://127.0.0.1:8090"
|
|
|
|
[network]
|
|
address = "0.0.0.0"
|
|
# NOT 8080 — the Smirk backend uses that. Front this with your TLS terminator.
|
|
port = 8088
|
|
|
|
# Conservative, self-host-friendly resource ceilings (the anti-abuse floor even
|
|
# for the `open` policy). Tune to your box.
|
|
[limits]
|
|
messages_per_sec = 10
|
|
subscriptions_per_min = 60
|
|
max_event_bytes = 65536
|
|
max_ws_message_bytes = 131072
|
|
max_ws_frame_bytes = 131072
|
|
broadcast_buffer = 16384
|
|
event_persist_buffer = 4096
|
|
limit_scrapers = true
|
|
|
|
[options]
|
|
# Reject events dated too far in the future (clock-skew abuse).
|
|
reject_future_seconds = 1800
|
|
|
|
[authorization]
|
|
# Write restriction is enforced by the gRPC admission service above, NOT a static
|
|
# whitelist. Leave pubkey_whitelist unset.
|