fix(server): require gateway secrets
This commit is contained in:
parent
84a9aeea25
commit
96efe21b50
@ -80,7 +80,10 @@ MCP endpoint (OpenCode connects here): http://127.0.0.1:4445
|
||||
|
||||
The MCP endpoint stays bound to `127.0.0.1` on purpose: `exec-lua` / `write-file` are
|
||||
as powerful as the linked computer, so only local processes (your OpenCode) reach them.
|
||||
Set `TRAPOS_SERVER_PASSWORD` in `.env` to require a shared secret on the gateway connection.
|
||||
`TRAPOS_SERVER_PASSWORD` (and `OPENCODE_SERVER_PASSWORD`) must be set in `.env`: the
|
||||
gateway connection requires this shared secret, and the server refuses to start if either
|
||||
is empty (run `just install` to generate them). An empty password would expose the gateway
|
||||
unauthenticated, so it is never allowed.
|
||||
|
||||
## 5. Link The Computer To The Gateway
|
||||
|
||||
@ -88,7 +91,7 @@ On the ComputerCraft computer, point it at the gateway and reboot:
|
||||
|
||||
```sh
|
||||
set cloud.url ws://<public-host>:4444
|
||||
set cloud.password secret # only if TRAPOS_SERVER_PASSWORD is set on the host
|
||||
set cloud.password secret # must match TRAPOS_SERVER_PASSWORD on the host
|
||||
reboot
|
||||
```
|
||||
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
# Serve the trapos-server gateway (port 4444) for remote/in-game attachment using
|
||||
# repo-local .env secrets. Mirrors `opencode-serve`, but auth is optional: an unset
|
||||
# TRAPOS_SERVER_PASSWORD means the gateway runs with auth disabled (warn, do not fail).
|
||||
# repo-local .env secrets. Mirrors `opencode-serve`. Both TRAPOS_SERVER_PASSWORD and
|
||||
# OPENCODE_SERVER_PASSWORD are required: an empty one would run the gateway
|
||||
# unauthenticated, so a missing secret is a fatal error (see also the guard in index.ts).
|
||||
[positional-arguments]
|
||||
serve *args:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
repo='{{justfile_directory()}}'
|
||||
if [ -f "$repo/.env" ]; then set -a; . "$repo/.env"; set +a; fi
|
||||
if [ -z "${TRAPOS_SERVER_PASSWORD:-}" ]; then
|
||||
printf '%s\n' 'serve: TRAPOS_SERVER_PASSWORD unset in .env — gateway auth disabled' >&2
|
||||
for var in TRAPOS_SERVER_PASSWORD OPENCODE_SERVER_PASSWORD; do
|
||||
if [ -z "${!var:-}" ]; then
|
||||
printf '%s\n' "serve: $var is empty or unset in .env — refusing to start (run \`just install\` to generate secrets)" >&2
|
||||
exit 1
|
||||
fi
|
||||
export TRAPOS_SERVER_PASSWORD="${TRAPOS_SERVER_PASSWORD:-}"
|
||||
export OPENCODE_SERVER_PASSWORD="${OPENCODE_SERVER_PASSWORD:-}"
|
||||
done
|
||||
export TRAPOS_SERVER_PASSWORD
|
||||
export OPENCODE_SERVER_PASSWORD
|
||||
export OPENCODE_URL="${OPENCODE_URL:-http://127.0.0.1:4242}"
|
||||
export TRAPOS_SERVER_HOST="${TRAPOS_SERVER_HOST:-0.0.0.0}"
|
||||
export TRAPOS_SERVER_PORT="${TRAPOS_SERVER_PORT:-4444}"
|
||||
|
||||
@ -3,11 +3,14 @@ import { createApp, type Config } from "./app.js";
|
||||
const config: Config = {
|
||||
host: process.env.TRAPOS_SERVER_HOST ?? "0.0.0.0",
|
||||
port: readPort(process.env.TRAPOS_SERVER_PORT, 4444),
|
||||
serverPassword: process.env.TRAPOS_SERVER_PASSWORD,
|
||||
serverPassword: requireSecret("TRAPOS_SERVER_PASSWORD", process.env.TRAPOS_SERVER_PASSWORD),
|
||||
requestTimeoutMs: readPositiveInt(process.env.TRAPOS_SERVER_REQUEST_TIMEOUT_MS, 600_000),
|
||||
opencodeUrl: process.env.OPENCODE_URL ?? "http://127.0.0.1:4242",
|
||||
opencodeUsername: process.env.OPENCODE_USERNAME ?? "opencode",
|
||||
opencodeServerPassword: process.env.OPENCODE_SERVER_PASSWORD,
|
||||
opencodeServerPassword: requireSecret(
|
||||
"OPENCODE_SERVER_PASSWORD",
|
||||
process.env.OPENCODE_SERVER_PASSWORD,
|
||||
),
|
||||
// MCP endpoint: on by default, bound to localhost. exec-lua / write-file are as
|
||||
// powerful as the linked computer, so the listener stays off the public gateway port.
|
||||
mcpEnabled: process.env.MCP_ENABLED !== "0",
|
||||
@ -53,6 +56,22 @@ function buildLogger(): Config["logger"] {
|
||||
return { level };
|
||||
}
|
||||
|
||||
// A non-empty password is mandatory: an empty TRAPOS_SERVER_PASSWORD disables auth
|
||||
// on the public gateway (resolveAccount maps any secret to "local"), and an empty
|
||||
// OPENCODE_SERVER_PASSWORD drops the outbound Basic-auth header. Refuse to start
|
||||
// rather than run silently unauthenticated.
|
||||
function requireSecret(name: string, value: string | undefined): string {
|
||||
const secret = value?.trim();
|
||||
if (!secret) {
|
||||
process.stderr.write(
|
||||
`\n[trapos-server] ${name} is empty or unset. Set it in .env ` +
|
||||
`(run \`just install\` to generate secrets). Refusing to start.\n\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
function readPort(value: string | undefined, fallback: number): number {
|
||||
return readPositiveInt(value, fallback);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user