Access control

Goauld server access control

Certain components should be accessible only by authorized users: the admin endpoints, the management endpoints, SSH access from the client, and SSH local port forwarding. Two independent mechanisms restrict this access, IP allowlisting and access tokens, described below.

For a public deployment:

  1. Restrict operator addresses with allowed-ips.
  2. Use separate random values for access-token and admin-token.
  3. Configure trusted-proxies only when a reverse proxy is in front of Goauld.
  4. Prefer HTTPS and keep the raw SSH listener private when the deployment does not require direct SSH access.

Access control is fail-closed. Test the configuration from an allowed operator address before removing the current working configuration.

IP allowlisting

The server accepts a list of authorized IPs to restrict access to:

  • The /admin/ endpoints
  • The /manage/ endpoints
  • The /ssh-ws/ endpoint, when --ssh-websocket is enabled
  • SSH access from the client (using password authentication)
  • SSH local port forwarding

Flags

  • --allowed-ips=192.168.1.1,192.168.2.0/24

Both individual IP addresses and CIDR ranges are matched. To allow all IPv4 addresses, set --allowed-ips=0.0.0.0/0; to also allow all IPv6 addresses, add ::/0: --allowed-ips=0.0.0.0/0,::/0.

Reverse proxy support

By default, --allowed-ips is matched against the direct TCP peer address of each request. If the server sits behind a reverse proxy or load balancer, every request’s peer address is the proxy’s own IP. The allowlist then either blocks every real client, or (if the proxy’s IP is added to the allowlist to make things work) effectively allows anyone reachable through that proxy, defeating the allowlist either way.

--trusted-proxies fixes this for the /admin/, /manage/, and /ssh-ws/ HTTP endpoints: X-Forwarded-For is only trusted when the immediate peer is itself one of the configured trusted proxies, and the real client IP is then taken from the rightmost entry in that header which isn’t itself a trusted proxy. This correctly handles a chain of several trusted hops (e.g. CDN → load balancer → Goauld) and is resistant to a client prepending spoofed entries ahead of the real trusted hops.

Flags

  • --trusted-proxies=10.0.0.1,172.16.0.0/12

Same format as --allowed-ips: individual IPs or CIDR ranges. Must include the reverse proxy’s own IP/CIDR. Once configured, the proxy’s IP itself is never matched against --allowed-ips, only whatever it puts in X-Forwarded-For is.

SSH over WebSocket

For SSH access (as opposed to /admin///manage/), there is no way to make a raw TCP connection carry a real client IP through a reverse proxy: --trusted-proxies cannot help it directly. Instead, --ssh-websocket lets SSH traffic tunnel through an HTTP(S) WebSocket endpoint, /ssh-ws/, which is one of the HTTP endpoints --allowed-ips/--trusted-proxies gates. Once inside the tunnel, the connection is handed off directly to the same sshd instance direct-TCP clients use, same password auth, same local-port-forwarding-to-agent mechanism, so nothing about the SSH protocol itself changes.

Flags

  • --ssh-websocket

Disabled by default. Also gated by --access-token (the same token used for /manage/) in addition to --allowed-ips/--trusted-proxies.

See SSH for the corresponding client-side --ws flag.

Access token

User access token

The user access token restricts:

  • The /manage/ endpoints

Flags

  • --access-token=token1,token2

Admin access token

The admin access token restricts:

  • The /admin/ endpoints

Flags

  • --admin-token=token1,token2

Admin token embedding

Access tokens cannot contain : (colon), which is reserved as a separator. This restriction only applies to access tokens; admin tokens may contain colons, since the full value after the first colon is always used as the admin token.

To include both access and admin tokens in a single Authorization header, format them as access-token:admin-token. The POST /manage/agent/{id}/kill endpoint supports this format:

Authorization: <access-token>:<admin-token>

API reference

/manage/ endpoints

Protected by the user access token (see Access token).

MethodRoutePurpose
POST/manage/agent/{id}/killKill an agent (accepts the embedded admin token, see above)
GET/manage/agent/{id}Get information about an agent by ID
GET/manage/agent/by_name/{name}Get information about an agent by name
GET/manage/agent/List all agents
POST/manage/clearport/Clear remaining connections for a port or an agent
GET/manage/version/Get the server version
POST/manage/agent/{id}/setClipboardSet the agent’s clipboard content (deprecated, but still reachable)
POST/manage/agent/{id}/getClipboardRead the agent’s clipboard content (deprecated, but still reachable)
POST/manage/agent/{id}/addWGPeerAdd a WireGuard peer to the agent (deprecated, but still reachable)

/admin/ endpoints

Protected by the admin token (see Admin access token).

MethodRoutePurpose
GET/admin/config/Get the running configuration (sanitized)
GET/admin/dump/Dump information for all agents
GET/admin/state/Get the full server state (config and agents)
GET/admin/dump/{id}Dump information for a single agent
POST/admin/loglevel/{level}Change the server’s log level
GET/admin/metrics/Get in-memory per-agent metrics