An SSH key that can reach a remote OpenClaw Gateway is easy to call administrator access. That label hides the useful questions: may the key open a shell, forward only the Gateway port, or reach every service on the host? Which operator used it? What happens to an already-open tunnel after the key is revoked?
This is a deployment-hardening guide, not a vulnerability bulletin. It makes no affected-version claim and reports no hands-on test. The commands are based on the opened OpenClaw and OpenSSH documentation; the validation steps are proposed tests for your own host.
The access path has two trust decisions
OpenClaw describes one Gateway as the host that owns sessions, authentication profiles, channels, and state. Clients connect to it. The Gateway WebSocket binds to loopback by default on port 18789, and the documented SSH pattern forwards that loopback port to the operator’s machine. See the OpenClaw remote-access documentation.
That creates two separate controls:
- Network reachability: the firewall and SSH daemon decide who can reach the host.
- Host authority: the SSH account and key decide whether the connection can open a shell, request forwarding, or use other SSH features.
- Gateway authority: the Gateway token, password, or trusted proxy decides whether the forwarded client can use the control plane.
- Process authority: the OS account running OpenClaw decides what the Gateway can read, change, or execute.
OpenClaw’s security model treats an authenticated Gateway caller as a trusted operator for that Gateway. It is not a hostile multi-tenant boundary. If several mutually untrusted people need access, use separate Gateways and credentials, ideally with separate OS users or hosts. A collection of individual SSH keys improves attribution, but it does not create separate OpenClaw tenants. The OpenClaw security guidance makes that boundary explicit.
There is another easy mistake. gateway.remote.token and gateway.remote.password are client credential sources; they do not configure server authentication by themselves. If several operators use one shared Gateway bearer token, SSH can tell you which host identity opened the tunnel, but the shared Gateway credential may not identify the person behind later control-plane activity. That is an editorial consequence of the documented trust model, not a promise that Gateway logs provide per-human attribution.
Write the access contract before changing anything
Record the intended path in a short register. For each operator or automation identity, write down:
- the remote host, OpenClaw state directory, OS account, bind mode, port, and Gateway authentication mode;
- the SSH public-key fingerprint and the device or person who owns the private key;
- the source address, private-network membership, or bastion through which SSH may arrive;
- the exact allowed action, such as “forward 127.0.0.1:18789” or “interactive maintenance for one approved account”;
- the log locations, review owner, expiry date, and exact revocation procedure;
- an out-of-band recovery path, such as a provider console or a second verified administrator.
If the revocation column is blank, the access is not ready. A temporary key should have an expiry even when the key is expected to be used only once.
Keep the Gateway on loopback and narrow the tunnel
For personal administration or a small trusted team, the simplest boundary is usually a loopback Gateway plus a local SSH forward. OpenClaw’s exposure runbook lists that pattern for admin access and debugging, and recommends keeping gateway.bind at loopback rather than publishing the Gateway port.
A client-side tunnel can look like this:
ssh -N -T -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 127.0.0.1:18789:127.0.0.1:18789 openclaw-gatewayIn the OpenSSH ssh manual, -N means that no remote command is executed and -T disables pseudo-terminal allocation. The LocalForward form of the same setting is documented in the OpenSSH client configuration manual. ExitOnForwardFailure catches a failure to establish the requested forward. The server-alive options help a client notice an unresponsive connection; they are not an access expiry or a revocation mechanism.
A named client entry keeps the destination visible during review:
Host openclaw-gateway
HostName gateway.example
User openclaw-tunnel
IdentityFile ~/.ssh/id_ed25519_openclaw
LocalForward 127.0.0.1:18789 127.0.0.1:18789
ExitOnForwardFailure yes
ServerAliveInterval 30
ServerAliveCountMax 3
StrictHostKeyChecking yesUse a different local port if 18789 is already occupied, then set the OpenClaw remote URL to that local port. Keep host-key verification enabled and provision the expected host key through a trusted channel. Never expose the Gateway port to the public internet just because the first tunnel attempt failed. OpenClaw’s network-exposure guidance treats bind mode, Gateway authentication, and firewall rules as separate controls.
Give the tunnel a narrower identity than a shell
Create an individual OS identity or a dedicated tunnel account. Do not give every operator the same username and key. At the server level, a restricted block can express the intended shape:
Match User openclaw-tunnel
AuthenticationMethods publickey
AllowTcpForwarding local
PermitOpen 127.0.0.1:18789
AllowAgentForwarding no
X11Forwarding no
PermitTTY noAllowTcpForwarding local permits local forwarding while excluding remote and dynamic forwarding. PermitOpen limits the destination to the literal host and port. Check the exact behavior on the installed OpenSSH version; the sshd_config manual documents both directives and their defaults. A global PasswordAuthentication no, KbdInteractiveAuthentication no, and PermitRootLogin no baseline is sensible when it fits the recovery plan. Use AllowUsers or AllowGroups to make the permitted account set explicit.
The public key itself can add another boundary:
from="198.51.100.24",restrict,port-forwarding,permitopen="127.0.0.1:18789" ssh-ed25519 AAAA... operator-device-labelReplace the example address and key. In the authorized-keys format, restrict disables forwarding, agent access, X11, PTY allocation, and the user’s SSH startup file; port-forwarding then re-enables the one forwarding capability needed here, while permitopen keeps its destination narrow. A source-address restriction makes a stolen key less useful, but it is not a substitute for key protection. NAT, travel, and IPv6 can also make a fixed source rule brittle.
ssh -N is a client request, not server enforcement. If the tunnel account must never run a command, add a forced command that rejects command requests, using the actual path on the host, and verify it in a disposable environment. OpenSSH notes that ForceCommand does not itself disable forwarding, so keep the forwarding restrictions as well.
Validate the effective policy before reloading
Keep the current working SSH session open. In a second session, test the configuration and inspect the result that applies to the tunnel user and source address:
sshd -t
sshd -T -C user=openclaw-tunnel,addr=198.51.100.24,host=gateway.example,laddr=203.0.113.5,lport=22
ssh -G openclaw-gatewayThe sshd manual documents -t for configuration and key sanity checks, -T for effective configuration output, and -C for applying matching connection criteria. Reload only after the output matches the register, and keep a provider console or second administrator available. A syntax check is not proof that the service manager, firewall, account permissions, and Gateway process all agree.
Proposed validation plan, not a claimed result: confirm the approved key can establish the local forward; confirm the Gateway rejects a connection without the required token; run openclaw gateway probe --url ws://127.0.0.1:18789 --token <token-from-a-safe-secret-source>; verify that a second destination cannot be forwarded; attempt a shell and a PTY with the tunnel identity; then repeat from a denied source and with the key removed. OpenClaw warns that an explicit --url does not inherit credentials automatically, so a successful SSH connection alone proves only host reachability.
Log the SSH session and the Gateway separately
OpenSSH and OpenClaw answer different questions. The SSH daemon normally records connection start, authentication, and termination in the system log. Its SyslogFacility controls the facility used by sshd, and LogLevel controls verbosity. The OpenBSD manual lists INFO as the default and warns that DEBUG-level logging can violate user privacy. Start with the normal level, increase it only for a defined investigation, and send the host’s authentication logs to the storage your operating system actually uses.
OpenClaw documents two log surfaces: console output and file logs. File logs are JSON lines; the default rolling location is under /tmp/openclaw, with logging.file and logging.level available in the Gateway configuration. The documented CLI tail is openclaw logs --follow. The Gateway logging documentation also describes rotation limits. My operational recommendation is to collect important logs outside a temporary directory before rotation, with permissions that let the Gateway write but do not let every operator rewrite evidence.
Keep a session record with the SSH identity, key fingerprint, source address, host, local forwarded port, start and end time, change reference, and approved action. Add the Gateway profile and endpoint used. Do not put Gateway tokens, message contents, or private tool output into the register. If an incident requires sharing logs, redact first. A timestamp can connect two records, but it does not prove that a particular Gateway action came from one SSH session when other clients or shared credentials were active.
Proposed correlation test: record the operator and time, open one approved tunnel, run one harmless read-only Gateway probe, close the tunnel, and compare the SSH start/end records with the Gateway JSON lines. Repeat with a missing token and a revoked key. No correlation test was run for this article.
Revoke the whole path, not only the key line
Removing a public key from authorized_keys prevents new authentication with that line. For central revocation, OpenSSH also supports a RevokedKeys file containing public keys or a key revocation list. The file must remain readable and should be replaced atomically; the manual warns that an unreadable revocation file causes public-key authentication to be refused for everyone. That is a useful fail-closed property, but it makes careless file permissions an outage.
Key removal does not retroactively destroy an established SSH connection. Stop the client tunnel or its supervisor as well. If the connection uses multiplexing, the SSH client supports control operations such as ssh -O exit -S <control-socket> openclaw-gateway. Otherwise stop the process, LaunchAgent, or service that owns the tunnel, then check that the forwarded local port is no longer listening.
SSH revocation and Gateway credential rotation are separate actions. If the device, private key, host, or tunnel process may have exposed the Gateway credential, rotate gateway.auth.token or gateway.auth.password, update every approved remote client, and verify that the old credential fails. OpenClaw’s network-exposure documentation notes that changing the authentication mode or process-environment credentials requires a Gateway restart. The operator incident-response runbook also calls for rotating remote client secrets and provider or API credentials when compromise is suspected.
For a suspected host compromise, contain the Gateway first: stop the process if necessary, return the bind to loopback, disable public or tailnet exposure, freeze risky channel access, preserve and redact relevant logs, review configuration and transcripts, then run openclaw security audit --deep. Do not assume that deleting one SSH key handles keys copied to another host or credentials already read from ~/.openclaw.
Failure paths and residual limits
The reload locks you out
Keep the known-good session open, use the out-of-band console, restore the last verified configuration, and test with sshd -t before trying again. A second administrator is more useful than a second copy of the same key.
The tunnel works but the Gateway rejects the client
That means SSH reachability succeeded while Gateway authentication did not. Check the forwarded port, bind address, auth mode, and explicit token or password. Do not respond by widening the Gateway bind.
The revoked key still appears active
Look for an existing tunnel, a multiplexed master connection, a supervisor that restarted it, or another authorized key. Revoke the key, close the current connection, stop the supervisor, and test again from the affected device.
The source restriction breaks legitimate access
Do not keep widening a public CIDR until the rule becomes meaningless. Use a managed private network or bastion, and time-box exceptions in the access register.
The SSH account is restricted but the host is not
Anyone who can become root or modify the Gateway state and process environment is inside the OpenClaw host trust boundary. SSH restrictions reduce exposure and improve attribution; they do not compensate for a compromised host or a shared administrator account.
Acceptance checklist
Call the setup ready when you can answer each question without guessing:
- Which person or device owns every SSH key?
- Which source and destination does each key permit?
- Does the Gateway remain loopback-only unless a documented exception exists?
- Can SSH logs and Gateway logs be correlated without exposing secrets?
- Can you revoke one identity and close its existing tunnel?
- Do you know how to rotate the Gateway credential separately?
- Can you recover after a bad SSH change through an independent path?
- Have you documented the OpenClaw and OpenSSH versions whose behavior you rely on?
The useful boundary is small enough to explain: one identity, one source, one forward, one Gateway credential path, and one tested way out.
Sources
- OpenClaw: Remote access (accessed 2026-09-13; publication date not listed).
- OpenClaw: Security (accessed 2026-09-13; publication date not listed).
- OpenClaw: Network exposure (accessed 2026-09-13; publication date not listed).
- OpenClaw: Gateway logging (accessed 2026-09-13; publication date not listed).
- OpenClaw: Operator incident response (accessed 2026-09-13; publication date not listed).
- OpenBSD: sshd_config(5) (accessed 2026-09-13; publication date not listed).
- OpenBSD: sshd(8) (accessed 2026-09-13; publication date not listed).
- OpenBSD: ssh(1) (accessed 2026-09-13; publication date not listed).
- OpenBSD: ssh_config(5) (accessed 2026-09-13; publication date not listed).
Reference Trail
Sources and further reading
- OpenClaw remote-access documentationdocs.openclaw.ai
- OpenClaw security guidancedocs.openclaw.ai
- OpenSSH ssh manualman.openbsd.org
- OpenSSH client configuration manualman.openbsd.org
- network-exposure guidancedocs.openclaw.ai