# RELAY-PHASE1 ยท E (TASK E) โ€” control-plane (P3) systemd unit. STAGING TEMPLATE. # # Runs the P3 admin/registry/CA/pairing API (control-plane/src/server.ts, added in A2) on the # loopback admin port (CP_BIND_HOST/CP_BIND_PORT in the env file). It is NEVER exposed publicly โ€” # the security group keeps 8080 loopback-only; operators reach it via SSH tunnel. # # INSTALL (adjust the placeholder paths to your VPS): # 1) clone the repo to /opt/web-terminal (or edit --prefix below) # 2) install: sudo cp deploy/systemd/relay-control-plane.service /etc/systemd/system/ # 3) put the filled env at /etc/relay/control-plane.env (0600, owned by the service user) # 4) sudo systemctl daemon-reload && sudo systemctl enable --now relay-control-plane.service # # The env file supplies PG_URL/REDIS_URL/CAPABILITY_SIGN_PUBKEY_B64/CA_* /BASE_DOMAIN (see .env.example). [Unit] Description=web-terminal rendezvous-relay CONTROL PLANE (P3) Documentation=file:///opt/web-terminal/docs/PLAN_RELAY_PHASE1.md # Postgres + Redis run under Docker Compose (deploy/docker-compose.yml); wait for docker + network. After=network-online.target docker.service Wants=network-online.target Requires=docker.service [Service] Type=simple # Dedicated non-root service user (create once: sudo useradd --system --home /opt/web-terminal relay). User=relay Group=relay WorkingDirectory=/opt/web-terminal # Secrets/config come ONLY from the env file (INV9 โ€” no secrets inline in the unit). EnvironmentFile=/etc/relay/control-plane.env # /usr/bin/env resolves npm via PATH (works for NodeSource /usr/bin/npm and nvm shims alike). # Runs the "start" script (control-plane/package.json -> tsx src/server.ts). ExecStart=/usr/bin/env npm --prefix /opt/web-terminal/control-plane start Restart=always RestartSec=3 # Give in-flight requests / graceful SIGTERM (server.ts closes the http listener + pg/redis) time. TimeoutStopSec=20 KillSignal=SIGTERM # --- hardening (INV9: shrink the blast radius around the CA + capability material) --- NoNewPrivileges=true PrivateTmp=true ProtectSystem=full ProtectHome=true ProtectControlGroups=true ProtectKernelTunables=true RestrictSUIDSGID=true # The CA/capability material under /etc/relay is READ-ONLY to this service. ReadOnlyPaths=/etc/relay [Install] WantedBy=multi-user.target