🚀 herald: production hardening — SOLARGOD_READONLY gates /snap; unit adapted to the tunnel topology (fable)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
monsterrobotparty 2026-07-16 17:34:24 +10:00
parent 03f1c009f2
commit a6538fee1c
2 changed files with 15 additions and 6 deletions

View File

@ -1,5 +1,7 @@
# HERALD — systemd unit for SOLARGOD. serve.py binds 127.0.0.1 only; nginx
# reverse-proxies the public domain to it (mirror of the godstrument.pro shape).
# HERALD — systemd unit for SOLARGOD on the botchat VPS. serve.py binds
# 127.0.0.1 only; the cloudflared tunnel's ingress rule for
# solargod.godstrument.pro forwards to it (same shape as godstrument.pro —
# no nginx in this topology; nginx-solargod.conf is the alternative shape).
# Install: sudo cp deploy/solargod.service /etc/systemd/system/ && sudo systemctl enable --now solargod
[Unit]
Description=SOLARGOD orrery — serve.py (static + JPL Horizons/SBDB/CAD proxy + disk cache)
@ -7,9 +9,10 @@ After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/solargod
ExecStart=/usr/bin/python3 /opt/solargod/serve.py 8147
User=humanjing
WorkingDirectory=/home/humanjing/solargod
Environment=SOLARGOD_READONLY=1
ExecStart=/usr/bin/python3 /home/humanjing/solargod/serve.py 8147
Restart=on-failure
RestartSec=3
# serve.py writes its disk cache under WorkingDirectory/cache — keep it writable.

View File

@ -32,6 +32,9 @@ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8147
ROOT = Path(__file__).resolve().parent
CACHE_DIR = ROOT / "cache"
CACHE_TTL_SEC = 24 * 3600
# Production (HERALD): SOLARGOD_READONLY=1 disables the dev-only /snap write
# endpoint — behind a public tunnel, the server must accept no writes at all.
READONLY = os.environ.get("SOLARGOD_READONLY") == "1"
UPSTREAMS = {
"horizons": "https://ssd.jpl.nasa.gov/api/horizons.api",
@ -182,7 +185,10 @@ class Handler(SimpleHTTPRequestHandler):
def do_POST(self):
# Dev-only screenshot sink: POST /snap?name=<n> with base64 PNG (or a
# data:image/png;base64,... URL) → docs/<n>.png. Bound to 127.0.0.1; the
# name is sanitized so the write can never escape docs/.
# name is sanitized so the write can never escape docs/. Disabled entirely
# in production (SOLARGOD_READONLY=1) — a tunneled deploy must not write.
if READONLY:
return self.send_error(403, "read-only deployment")
if not (self.path == "/snap" or self.path.startswith("/snap?")):
return self.send_error(404, "not found")
_, _, query = self.path.partition("?")