{ "_meta": { "status": "UNVERIFIED — derived from the repos, not from the estate", "why": "ppl/infra/ was written and never applied: no ~/.pulumi, no infra/venv, no stack state, files dated 'mar 6'. The estate was built in the console and the IaC is aspirational. B1's inventory is what replaces these values with observed ones; until it runs, every field here is a CLAIM.", "never_record": "credential values. Resource ids and settings only. nova's gateway secret is deliberately absent from this file even though it is committed in plaintext in ppl/gateway/nginx/conf.d/nova.conf — see services[].raw.", "sources": [ "ppl/infra/__main__.py", "ppl/ctrl/dns.sh", "ppl/ctrl/certs.sh", "ppl/gateway/docker-compose.yml", "ppl/gateway/nginx/conf.d/", "ppl/local/Caddyfile" ], "placement": { "box": "a container on the estate's own docker network — upstream is the container name", "local": "a rig cluster on a peer, reached over the overlay — upstream is that peer's address", "instance": "a dedicated cloud instance on the overlay — same rendering as `local`", "hosted": "a managed endpoint. Declared so moving to one is a one-line change; unused.", "_why": "A service says WHERE it runs. How it is reached follows from that, and the three properties of a static-upstream vhost — upstream{}, no resolver, no set $var — are one decision rather than three." } }, "domain": "mcrn.ar", "local_domain": "local.ar", "host": "mcrn", "host_admin": "mcrn-admin", "instance": { "type": "t3.small", "disk_gb": 30, "disk_type": "gp3", "image": "debian-12", "user": "mariano" }, "firewall": [ { "port": 22, "proto": "tcp", "desc": "SSH" }, { "port": 80, "proto": "tcp", "desc": "HTTP" }, { "port": 443, "proto": "tcp", "desc": "HTTPS" }, { "port": 3022, "proto": "tcp", "desc": "Gitea SSH", "note": "compose maps 3022:22 but GITEA__server__SSH_PORT=22, so gitea advertises :22 in clone URLs while listening on :3022. B1 confirms which is real." }, { "port": 51820, "proto": "udp", "desc": "WireGuard", "note": "ABSENT from ppl/infra/__main__.py's four rules — but the tunnel is live (ping 10.8.0.1 succeeds), so the real security group must already allow it. The code therefore does not describe the estate. Confirm in V1." } ], "network": { "docker_network": "gateway", "docker_network_note": "A fixed, externally-joinable bridge name. Every unrelated app stack on the box joins it so nginx can resolve them by container name. This is why the gateway compose declares 8 services while nginx routes 20+ hostnames.", "wireguard_moved": "superseded by the top-level `vpn` block" }, "vpn": { "_status": "CAPTURED 2026-09-14 — public keys, allowed-ips and keepalive read from `wg show`. Roaming endpoints deliberately not recorded.", "_never_record": "private keys. `wg show` prints 'private key: (hidden)' and is the safe capture command. `wg showconf` dumps PrivateKey= in clear — never use it.", "overlays": { "estate": { "purpose": "Connects the estate's machines across clouds without a shared VPC, and carries everything that does not need to be publicly reachable.", "subnet": "10.8.0.0/24", "listen_port": 51820, "peers": { "box": { "address": "10.8.0.1", "role": "hub", "note": "mcrn.ar. Has a public IP, so it is the peer others dial. Carries the registry (:5000) and woodpecker's gRPC (:9000), both bound to this address and therefore overlay-only.", "endpoint": "3.23.204.197:51820", "public_key": "zVYCmi3xucuX7k/aDhrOUPyN4GRk96ffSDD6dUFQjh4=", "allowed_ips": "10.8.0.0/24", "keepalive": 25, "listen_port": 51820 }, "nrft": { "address": "10.8.0.2", "role": "roaming", "note": "The dev box. Behind NAT, so it must initiate and needs PersistentKeepalive. Verified: wg0 UP at 10.8.0.2/24, ping 10.8.0.1 0% loss at 153ms.", "endpoint": null, "public_key": "zlIBGs4y5rt6uVdmFBasHpafht6ErxG+R3ySCg5rh3s=", "allowed_ips": "10.8.0.2/32, 192.168.1.0/24", "keepalive": null, "listen_port": 36145 }, "work": { "address": "10.8.0.3", "role": "roaming", "note": "A work computer, granted access when it was needed. Identified by the user at capture time, 2026-09-14 — it was NOT in the description before, and the wire is where it was found. No handshake and no transfer have ever been recorded for it, so it is a standing grant rather than a live peer: it can connect, and never has. Whether to keep or revoke it is the host's call.", "endpoint": null, "public_key": "ruSZwKt/p60GVsTLSAhcKBIXKkSZsf0gWSmSH1+UgE0=", "allowed_ips": "10.8.0.3/32", "keepalive": null } } } } }, "databases": [ "gitea", "woodpecker", "umami" ], "certs": { "issued": [ "mcrn.ar", "*.mcrn.ar", "*.spr.mcrn.ar" ], "issued_source": "ppl/ctrl/certs.sh:92 — the -d flags passed to certbot", "note": "What the cert ACTUALLY covers. estate_sans() derives what the services NEED. check.sh compares the two; the difference is the finding, not a restatement." }, "services": [ { "name": "gitea", "host": "git", "upstream": "gitea:3000", "targets": [ "aws" ] }, { "name": "woodpecker", "host": "ci", "upstream": "woodpecker-server:8000", "targets": [ "aws" ] }, { "name": "registry", "host": "registry", "upstream": "registry:5000", "targets": [ "aws" ] }, { "name": "umami", "host": "analytics", "upstream": "umami:3000", "targets": [ "aws" ] }, { "name": "docserve", "host": "docs", "upstream": "docserve:8020", "targets": [ "aws" ] }, { "name": "ghost", "host": "notes", "upstream": "ghost:2368", "targets": [ "aws" ] }, { "name": "deskmeter", "host": "deskmeter", "upstream": "dmweb:10000", "targets": [ "aws" ], "local_port": 10000 }, { "name": "sysmonstm", "host": "sysmonstm", "upstream": "sysmonstm-edge:8080", "targets": [ "aws" ], "local_port": 8020 }, { "name": "malvalava", "host": "malvalava", "upstream": "mlvclean-frontend:80", "targets": [ "aws" ], "local_port": 30090 }, { "name": "soleprint", "host": "soleprint", "upstream": "soleprint:8000", "targets": [ "aws" ], "local_port": 12000 }, { "name": "dlt", "host": "dlt.spr", "upstream": "dlt_spr:8000", "targets": [ "aws" ] }, { "name": "sample", "host": "sample.spr", "upstream": "sample_spr:8000", "targets": [ "aws" ] }, { "name": "mariano", "host": "mariano", "kind": "static", "targets": [ "aws" ] }, { "name": "rigui", "host": "rig", "kind": "static", "targets": [ "aws" ], "local_port": 20310 }, { "name": "unt", "host": "unt", "targets": [ "local" ], "local_port": 8040 }, { "name": "mpr", "host": "mpr", "targets": [ "local" ], "local_port": 30080 }, { "name": "nvi", "host": "nvi", "targets": [ "local" ], "local_port": 8060 }, { "name": "eth", "host": "eth", "targets": [ "local" ], "local_port": 8050 }, { "name": "amar", "host": "amar", "targets": [ "local" ], "local_port": 8030 }, { "name": "nova", "host": "nova", "upstream": "nova-ui:80", "targets": [ "aws" ], "raw": true, "raw_why": "Gated on an X-Gateway-Secret header whose value is committed in plaintext. The value is NOT recorded here. Worse: stellarair.conf proxies to the SAME nova-ui:80 upstream WITHOUT the check, so the gate is bypassable by hostname. Stays hand-written until that is decided." }, { "name": "stellarair", "host": "stellarair", "upstream": "nova-ui:80", "targets": [ "aws" ], "raw": true, "raw_why": "See nova. Same upstream, no header gate." }, { "name": "langfuse", "host": "langfuse", "local_host": "lng", "placement": "local", "peer": "nrft", "port": 3000, "targets": [ "aws", "local" ], "local_port": 3000, "note": "One service, one socket, two names. It was two entries with one flagged `raw`; placement is what made the exception expressible, so it is generated now." }, { "name": "legacy", "host": "*.soleprint", "upstream": "soleprint:8000", "targets": [ "aws" ], "raw": true, "raw_why": "A regex server_name with a named capture plus sub_filter injection — not expressible as a template. ALSO BROKEN: its /api/, /admin/, /static/ and / blocks proxy to 127.0.0.1, i.e. inside the nginx container where nothing listens, so every legacy room 502s. Only /wrapper/ uses the correct container-name form." } ] }