Not everything a workspace runs should get a public route. Databases, staging instances, admin ports, and half-finished services want native TCP access from a laptop or an agent sandbox without becoming an HTTPS endpoint. Mechanics 0.3.37 gives them exactly that, using a tool every client already has: OpenSSH local port forwarding.
ssh -N -L 5432:mydb-rw.x-alice:5432 mechanics.run
psql -h 127.0.0.1 -p 5432 -U app mydb Stock ssh -L, constrained destinations
Mechanics now handles direct-tcpip channels itself. The destination
is parsed as a Kubernetes DNS name (<service>.<namespace>,
<service>.<namespace>.svc, or
<pod>.<namespace>.pod) and authorized against the SSH
public key before anything is dialed. The namespace must be a workspace owned by
the connecting account. IP literals, foreign namespaces, headless Services, and
reverse forwarding are rejected, and Mechanics resolves the target itself instead
of dialing whatever address the client supplied.
This is a separate capability from the read-only user kubeconfig, which still
denies pods/portforward. Tunnels never expose a public TCP endpoint.
They exist only for the lifetime of the SSH connection.
Connect helpers print the command
Nobody should have to remember the destination grammar. app connect
and addon connect print a ready-to-paste forward for the app's live
instance Service or the addon's TCP endpoint (postgres to <name>-rw:5432,
valkey to 6379, NATS to 4222), plus a native client hint.
ssh -T mechanics.run -- app -a myapp connect
ssh -T mechanics.run -- addon -a mydb connect --local-port 15432
# prints: ssh -f -N -o ServerAliveInterval=30 \
# -o ExitOnForwardFailure=yes \
# -L 15432:mydb-rw.x-alice:5432 mechanics.run Tunnels are audited like commands
Every tunnel attempt, allowed or denied, is recorded separately from command
audit events: target, outcome, error, byte counts, and SSH metadata. Operators
inspect them with mechanics audit tunnels. Unknown keys get a signup
hint instead of a silent rejection, and the SSH username stays what it always was
in Mechanics: metadata, never identity.
Private things stay private. Reaching them takes one ssh -L that Mechanics authorizes, resolves, and audits.