ssh lane is an SSH server with the Sidecar’s enforcement built into it. People reach a host with the clients they already use — ssh, sftp, scp, rsync — and what they do arrives as statements carrying a verified identity: a one-shot command in full, each file operation with its path. Guardrails allow or deny them, masking rewrites what comes back, and the audit trail records who did what.
Use it to put policy in front of the hosts people still need a shell on — a production box, a jump host, a bastion — without replacing the tooling they reach it with. Nothing changes on the client side; the credential does, because this lane accepts certificates and nothing else. There is no password to guess and no authorized_keys to manage.
It is also the one lane that does not relay. SSH is encrypted end to end, so nothing in a middle position can read it; to see a command at all, a component has to be one end of the connection. So an ssh lane terminates the handshake itself: it verifies the client’s certificate against a CA it trusts, resolves the requested login name to an account on the host, and spawns the shell or the command locally. There is no upstream to proxy to and no sshd behind it.
The one exception proves the rule. A listener carrying an ssh.relay block terminates the client’s session too — it just terminates it in the middle, then opens its own connection to a stock sshd. It still has to be one end of the client’s connection to read a command; what changes is that it is also one end of a second connection the client never makes.
config.yaml
ssh -p 2222 devuser@host, and the certificate, the account, the guardrail, the mask and the audit record all happen in that one process.
How it differs
The last two rows are the ones that surprise people. An
ssh lane runs processes, so the host it sits on needs accounts, groups and login shells lined up with the certificates your CA issues — see Host Configuration. And a masked byte stream cannot change length, so strategy: mask is the only strategy this lane accepts.
A lane that terminates the protocol also means there is no
authorized_keys, no password authentication and no PAM. Certificates are the only credential. That is what makes a listener on a public address defensible: there is nothing to brute-force.Topologies
The same end-hop configuration serves the first three. What changes is what sits in front of it, and the answer to “what is enforced” does not change with it.
Mode 4 is the exception to everything above: the endpoint moves to the middle, the bastion decrypts every session behind it, and file transfer is not available. It is the right answer for an appliance, a vendor-managed host, or an evaluation with no install budget — and the wrong one anywhere you could put the endpoint on the target. Bastion SSH Termination states the trade in full.
In modes 2 and 3, the client’s own
ssh -J runs two independent handshakes over one TCP path, presenting the same certificate to both. Nothing is re-signed in the middle, and no Sidecar anywhere holds a private signing key. Mode 4 is different: the bastion terminates the inner session and authenticates to the target with a credential it holds (or the client’s forwarded agent). Topologies has the sequence for each, and what config makes a listener a bastion instead of an end-hop.
Enforcement
In modes 1–3 every row above is enforced at the end-hop. On a listener with
ssh.relay, the same controls are enforced at the bastion for every destination the relay map covers, and the target’s stock sshd enforces only its own authentication. See Bastion SSH Termination.
And the honest other half: an interactive shell carries no guardrails. A keystroke stream has no statement boundary a rule could act on, and reconstructing one is unsound. A shell is admitted, its output is masked, and it is recorded as events — never as content. A deployment that needs every action to be a rule-readable statement drops shell from capabilities_allowed. Configuration states this in full.
Operations
An SSH statement is text, and what the text is depends on the operation — a command line forexec_line, a variable name for env_set, a path for every sftp_*. Scope every rule with operations:
Four rule types are refused at load on an
ssh lane, because nothing here produces what they read: table, http_resource, http_status and grpc_status. The full vocabulary, with what each operation matches, is in Guardrail Rules.
Try it locally
The repository carries a complete local stack — three topologies, six lanes, a minted CA, and a script that asserts every claim on these pages:ssh-stack on GitHub
Direct, hoop-bastion and stock-
sshd-bastion topologies against one end-hop, plus lanes for multi-account login, an exec-only listener and certificate-extension identity.Next
Topologies
The four topologies, what makes a listener a bastion, and why the end-hop enforces the same thing in three of them.
Bastion SSH Termination
Mode 4: the
ssh.relay block, upstream credentials, host-key checking, and inspecting a host that runs nothing.Configuration
Every attribute:
host_key, trusted_ca, the tri-state capabilities_allowed, destinations_allowed and identity.Certificates and Identity
What your CA must put in a certificate, which field decides what, and what refuses the whole certificate.
Host Configuration
Accounts, groups, login shells, home directories, and the root vs non-root trade.
OpenSSH Differences
The
sshd_config keyword mapping, every assumption to drop, and what is not implemented.File Transfer
sftp, scp both ways, rsync, and why masking and rsync cannot coexist.Known Limitations
What the lane does not do: guardrails on a shell, what the trail holds, and the boundary masking is applied on.