# Connect SSH (bash)

An account of SSH (bash) is connected once, on the instance, by a person who then gives missions access to its resources; the agent never receives the credential. Shell commands on a host over SSH — inspection on a read allow-list, writes priced by class (destructive, package, service, sudo), lines that cannot be classified priced as all of them.

One account is one host reached over SSH with a key pair generated by this gateway and a pinned host key; that host is its single resource, labelled dev, staging or prod by its owner. The one tool runs a shell command line: inspection commands are reads, everything else is a write, and destructive commands, package changes, service control and sudo are permissions of their own.

Permissions, presets and tools of this service: [SSH (bash) plugin](/plugins/ssh).

## How to connect

On the instance: Accounts → Connect an account, then pick the service. A company app, when the service needs one, is registered once by an administrator under Settings → Administration → Company apps, or set in the configuration (`providers.<id>.*`, see [configuration keys](/docs/configuration/keys)). Every instance registers its own app: this gateway never uses an app shared with another one.

### The usual way: with a key pair the instance generates; you install its public key on the host

What the connect page asks:

- Host: Hostname or IPv4 address. It becomes the resource ref the agent cites.
- Port: SSH port, 22 when empty.
- Login user: The account whose authorized\_keys receives the public key shown after generation. Its sudoers entry bounds what the agent can escalate to.
- Host key fingerprint: Run \`ssh-keyscan -t ed25519 \<host\> \| ssh-keygen -lf -\` on a machine that already trusts the host and paste the SHA256 value. Any other host key is refused.

## Disconnecting

Remove the public key shown on this page from the authorized\_keys file of the login user on the host.

## Registration notes from the plugin

From the plugin's [README](https://github.com/vaubaan/gateway/blob/main/plugins/ssh/README.md), written for the people who register the app or create the token.

### Credential

Kind `ssh-key`, algorithm ed25519. The host generates the key pair, shows the
public key, and collects four non-secret fields:

| Field                  | Required | Pattern                    | Purpose                                                                                                                                                                                        |
| ---------------------- | -------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host`                 | yes      | hostname or IPv4, ≤ 253    | The resource ref the agent cites (`host[vps-1.example.com]`). IPv6 literals are not accepted. One grammar (`hostRef`) for the credential, the resource ref, the `host` argument and the slice. |
| `port`                 | no       | 1–65535                    | 22 when empty.                                                                                                                                                                                 |
| `user`                 | yes      | POSIX user name            | The account whose `~/.ssh/authorized_keys` receives the public key.                                                                                                                            |
| `host_key_fingerprint` | yes      | `SHA256:<base64>` (`=` ok) | The host's key, verified on every connection; no trust-on-first-use.                                                                                                                           |

Setting up a host:

```sh
# 1. On the target, as the login user, append the public key the interface shows :
echo 'ssh-ed25519 AAAA… vaubaan-gateway' >> ~/.ssh/authorized_keys
# 2. From a machine that already trusts the host, read its ed25519 fingerprint :
ssh-keyscan -t ed25519 vps-1.example.com 2>/dev/null | ssh-keygen -lf -
#    256 SHA256:9kd…Qo vps-1.example.com (ED25519)   ← paste the SHA256:… value
```

There is no company-registered app for SSH: the key pair _is_ the app. The
private key is stored encrypted by the host and never leaves the instance. A
host that presents another key is refused with `SshHostKeyMismatchError`
during the key exchange, before the key pair is offered — if the host was
legitimately re-keyed, the owner updates the connection. A target without a
well-formed pin never opens a socket (`SshHostKeyNotPinnedError`); `sshTarget()`
refuses to build one in the first place. An authentication failure is an
`UpstreamAuthError`: the host marks the connection `expired` and the owner
reconnects (a new key pair).
