feat(nh3-svos): SVOS a737a06 refresh — app-terminal on its own mesh origin (svos-terminal.phasefinal.com), app-knowledge, app-postoffice units; quiesce hook covers the new units
This commit is contained in:
@@ -110,3 +110,90 @@ https://svos.phasefinal.com:443 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# app-terminal's own origin (svos-dev 2026-10-07, U8 + U10c "a pane needs its own origin"). The interface embeds this
|
||||
# page in a cross-origin iframe; the browser derives its URL from the registry's base_url
|
||||
# (instance.toml: base_url = "https://svos-terminal.phasefinal.com"), so the kernel's signed calls (/health, /verbs/*)
|
||||
# also arrive here, from the box itself, and pass to the connector on 127.0.0.1:8404.
|
||||
# - NO Basic auth and no identity header: Chromium cancels Basic prompts for cross-origin frames and subresources, so a
|
||||
# gate here kills the pane. The lease is the page's auth (GET / without one is a waiting page by ruling A105;
|
||||
# /terminal/session|stream|close refuse without the bearer); /verbs/* and /health refuse without the kernel's
|
||||
# Ed25519 signature. As defence in depth, /verbs/* and /health are refused unless they come from the box itself.
|
||||
# - The app sets Content-Security-Policy: frame-ancestors https://svos.phasefinal.com (its frame_ancestors config);
|
||||
# it passes through unmodified. /terminal/stream is a long-lived ndjson stream: no buffering (flush_interval -1)
|
||||
# and no write/idle deadline (none is set anywhere in this file). Same 1 MiB body cap.
|
||||
# - Mesh-only like the main site: headscale MagicDNS extra record -> 100.64.0.9; nh3-svos resolves it via /etc/hosts.
|
||||
(svos_terminal_upstream) {
|
||||
reverse_proxy 127.0.0.1:8404 {
|
||||
flush_interval -1
|
||||
}
|
||||
}
|
||||
|
||||
https://svos-terminal.phasefinal.com:443 {
|
||||
bind 100.64.0.9
|
||||
tls {
|
||||
dns cloudflare {env.CF_API_TOKEN}
|
||||
resolvers 1.1.1.1 8.8.8.8
|
||||
}
|
||||
route {
|
||||
request_header -Tailscale-User-*
|
||||
request_header -X-Forwarded-*
|
||||
request_header -Tailscale-Headers-Info
|
||||
request_header -X-Real-IP
|
||||
request_header -Forwarded
|
||||
request_header -X-SVOS-Peer
|
||||
|
||||
request_body {
|
||||
max_size 1MiB
|
||||
}
|
||||
|
||||
# The kernel's signed calls come from the box itself (its source on the mesh address); anything else is refused.
|
||||
@not_from_box {
|
||||
path /verbs/* /health
|
||||
not remote_ip 100.64.0.9 127.0.0.1
|
||||
}
|
||||
handle @not_from_box {
|
||||
respond 403
|
||||
}
|
||||
|
||||
# Exactly the paths the connector serves (svos-dev 2026-10-07), method-pinned; everything else is 404.
|
||||
@page {
|
||||
method GET HEAD
|
||||
path / /assets/*
|
||||
}
|
||||
handle @page {
|
||||
import svos_terminal_upstream
|
||||
}
|
||||
@lease_get {
|
||||
method GET
|
||||
path /terminal/session /terminal/stream
|
||||
}
|
||||
handle @lease_get {
|
||||
import svos_terminal_upstream
|
||||
}
|
||||
@lease_close {
|
||||
method POST
|
||||
path /terminal/close
|
||||
}
|
||||
handle @lease_close {
|
||||
import svos_terminal_upstream
|
||||
}
|
||||
@verbs {
|
||||
method POST
|
||||
path /verbs/*
|
||||
}
|
||||
handle @verbs {
|
||||
import svos_terminal_upstream
|
||||
}
|
||||
@health {
|
||||
method GET
|
||||
path /health
|
||||
}
|
||||
handle @health {
|
||||
import svos_terminal_upstream
|
||||
}
|
||||
handle {
|
||||
respond 404
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user