Hosts
SSH access matrix & security model (authoritative, 2026-10-18)
Young, 2026-10-18:
SSH access matrix & security model (authoritative, 2026-10-18)
Young, 2026-10-18:
"LAB is our central operation. Pulse can ssh to LAB and reverse. Pulse & LAB can ssh Production one way only and Production can't ssh connect to LAB."
1. Hosts and roles
| Host | Address | Role | Serves |
|---|---|---|---|
| Pulse | 192.168.4.34 | Pulse unit — investment/cashflow | eva, eve, tam; Pulse content, signals, cashflow |
| LAB | 192.168.4.60 | Brain + Heart — central operation | min, mira, sol (Brain) + Heart Fleet; canonical vault, A2A gateway, opencode ARMS |
| Production | 161.33.71.67 | Customer hosting + backup + serve | docs.youngle.au, pulse.youngle.au, per-tenant e-commerce, Heart Fleet |
LAB is the central operation: never serves publicly, holds the canonical vault, is the A2A gateway and opencode ARMS host. Production is the only billed/public node. Pulse is a separate owned host for investment/cashflow.
2. SSH access matrix (6 directions)
| From → To | Allowed | Mechanism | Notes |
|---|---|---|---|
| Pulse → LAB | Yes (bidirectional) | lab_ctrl_key + mesh tunnel (18301–18313) | Reverse forwards 18441–18443 (eva/eve/tam) answer on LAB |
| LAB → Pulse | Yes (bidirectional) | reverse forwards 18441–18443 | loopback-bound on the laptop (eva@localhost only) |
| Pulse → Production | Yes (one-way only) | tam_server_key → 161.33.71.67 | inbound to prod |
| LAB → Production | Yes (one-way only) | LAB's own key → 161.33.71.67 | inbound to prod; "LAB-to-PROD-OK" live-probed |
| Production → LAB | NO | structurally denied | 192.168.4.60 not routable from prod (public-only) — Connection timed out |
| Production → Pulse | NO | structurally denied | no route / no laptop pubkey path for prod outbound |
Rules:
- LAB is central; it may initiate outbound to Pulse and to Production.
- Pulse↔LAB is bidirectional (mesh tunnel + keys on both ends).
- Pulse and LAB may SSH to Production one-way only (inbound into prod). Two independent inbound keys (Pulse's + LAB's) — single-key compromise is recoverable from the other host.
- Production cannot initiate SSH to LAB (no inbound SSH to LAB from prod).
- Production cannot SSH to Pulse either (one-way only, inbound into prod).
- Production is structurally blind to both home hosts: it reaches the internet only; home-LAN addresses never answer it. Enforcement is network topology, not config.
3. Firewall rules
- Loopback-only binds: every tunnel binds
127.0.0.1both ends; the public face of any host is nginx/ssh only. No0.0.0.0binds for agent/A2A ports. - Production public IP only:
161.33.71.67; 100.x (Tailscale) addresses are decommissioned — do not re-add. - No inbound SSH to LAB from prod: prod has no route to
192.168.4.60; even with prod's key material compromised, home-LAN addresses do not answer. - No inbound SSH to Pulse from prod: prod cannot route to
192.168.4.34. - Production ufw: empty status (not the control point); iptables DOCKER chains (15 rules) govern container traffic; fail2ban runs for auth-abuse.
- A2A is the fleet plane, not SSH: fleet agents communicate over A2A (loopback tunnels), never over SSH. SSH is ops/admin only.
- Tenant isolation: tenants on prod reach services via nginx vhost (nginx + Authelia), never via SSH; no tenant holds prod's SSH key.
4. Tunnel design
- Laptop ↔ LAB mesh tunnel (
lab-mesh-tunnel.service, user unit @eva): autossh, key~/.ssh/lab_ctrl_key, targetlab@192.168.4.60. Enabled + linger (survives reboot); child auto-respawn proven.- Laptop → LAB:
127.0.0.1:18301–18305→8301–8305(ace/atlas/echo/nova);127.0.0.1:18311–18313→8311–8313(min/mira/sol); direct aliases8301–8305, 8311–8313. - LAB → laptop (Pulse agents):
127.0.0.1:18441→8441 (Eva),18442→8442 (Eve),18443→8443 (Tam).
- Laptop → LAB:
- Laptop → prod (
ubuntu@161.33.71.67, public IP — the ONLY prod address):tam-tunnel,laptop-tunnel,laptop-reverse-tunnel,eva-a2a-tunnel; forwards9906, 8447, 8448, 8442, 9222, 8443→8441, 9903→9901, 5902, 8765, 9904→192.168.4.28:8446; local8433, 8434. - Reboot survival pattern: user units +
systemctl --user enable+ linger on the owning user; autossh-M 0withServerAliveInterval=30,ExitOnForwardFailure=yes. - Loopback-only binds both ends; register every new tunnel in
fleet-ssh-tunnels.md. - Keys stay on the issuing host: prod's
id_ed25519is the key LAB uses to ENTER prod (trust flows inward), not a credential stored on prod for outbound use. Optional hardening: LAB'sauthorized_keysentry for prod's key may carryrestrict+from="161.33.71.67"+ command-limitation to the pull lane only.
5. Security model (blast radius)
- LAB as central = no triangle: a compromised prod cannot pivot into LAB (network-blind); blast radius of a prod breach = prod itself.
- Two independent inbound keys to prod → single-key compromise recoverable from the other host.
- Reverse forwards are loopback-bound on the laptop; the laptop never exposes agents to the internet, only to LAB through the tunnel.
- Tenants on prod cannot reach LAB or Pulse; even if a tenant compromises the prod node, our infrastructure is unreachable (network topology = enforcement, not config).
- Secrets: keys stay in
.env(mode 600), never in the vault; provider keys unset in Heart worker units (UnsetEnvironment), E5 boundary holds.
6. References
Docs/SolOS/hosts/host-topology-roles-2026-10-16.md— authoritative host topology and roles.Docs/Fleet/06-implementation/fleet-ssh-tunnels.md— tunnel registry.Docs/SolOS/hosts/secrets-isolation-fix.md— prod secrets isolation.Docs/SolOS/hosts/prod-census-decommission.md— prod census / decommission.
7. Open items
- Key hygiene: clean
prod:~/.ssh/backup keys (authorized_keys.bak*) + 7 live entries (keep current only). - Optional hardening:
restrict+from="161.33.71.67"+ command-limit on prod's key in LAB'sauthorized_keys(Sol's ruling). - Pulse→LAB SSH uses existing
lab_ctrl_key(confirmed by live probe); A2A bridge remains the recommended ops plane (Option B) to avoid adding a credential surface.

