SSH (remote host, read-only)
Connect a Linux host over SSH with a dedicated read-only user and key; what Connect and verify runs, what the agents can and cannot do with it today, and where approved commands run.
How-to · Updated 2026-10-23 · Describes release 0.1.164
Overview
An SSH connection reaches a server the platform has no API for: an on-premises VM, a bare-metal host, a jump box. The catalog lists it under On-prem / network. Two facts decide how to use it:
- The connection check is real: Connect and verify runs
uptimeon the host with the saved key, so reachability, the key and the login are proven before anything else depends on them. - In this release an investigation, a chat turn and an estate x-ray refuse every command through an SSH connection, read commands included. Only
kubectlhas the platform's verified read adapter; for any other binary the<name>_exectool answersInvestigation connections are read-only. This operation was not executed; prepare an incident change using a write connection and obtain approval.whatever read verbs the catalog lists. The connection's agent-facing value today is the inventory note and the check; the host's measurements reach the agent through a metrics or log backend the host reports to.
Where SSH does run commands is the write side: a second, write-role SSH connection bound to a cli remediation route runs the approved command after a human approval, through the Change executor and never through the investigation loop.
Setup
Before you start
- The
datasources.managepermission; the built-in owner and operator roles carry it. - An unencrypted private key for a read-only account on the host (Installation).
- The host's SSH port reachable from the platform, or a private-network agent on its network.
Installation
On a secure workstation create a dedicated, unencrypted key — the connector cannot answer a passphrase prompt — and give only its public key to the server administrator. Connect on-premises servers has the commands, and a forced-command wrapper that limits the key to uptime, df -h, free -m and uname -a. The administrator creates an account such as aiops-reader with no sudo, no application write permission and access only to the logs and host facts you intend to share, installs the public key in its authorized_keys, and confirms the host's fingerprint. The host must accept non-interactive key authentication on the port you enter.
Configuration
- Open Settings · Data in → Data sources and select Connect datasource.
- Under Type, choose SSH (remote host, read-only). Enter a Connection name; the connected list shows it, and per-connection agent tools are named after it.
- Fill the fields:
| Field (portal label) | API key | Value |
|---|---|---|
| Host (IP or DNS) | host |
10.2.0.15 or edge-01.example.com |
| SSH port (usually 22) | port |
22 |
| Read-only user | user |
aiops-reader |
| Private key (PEM) | private_key |
The whole key file, -----BEGIN line included; a secret, checked for its armor on save |
- Optionally, open Optional · describe this environment and fill What should AIOps know about it? with what runs on the host.
- Under Use this connection for, choose Investigate only and select Connect and verify.
The same connection through the API (POST /api/aiops/{tenant_id}/datasources, requires datasources.manage; the key goes in secret_values, and one posted in config is moved there):
{
"type_key": "ssh",
"name": "edge-01",
"description": "On-prem edge host running the checkout reverse proxy; nginx logs under /var/log/nginx.",
"config": {
"host": "edge-01.example.com",
"port": "22",
"user": "aiops-reader"
},
"secret_values": {
"private_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n<key>\n-----END OPENSSH PRIVATE KEY-----\n"
},
"role": "read",
"enabled": true
}
A key without its armor is refused at save time with 400 'private_key' does not look like a PEM key (missing -----BEGIN block) — paste the full key file.
Validation
Connect and verify, and Test on the row later, looks for ssh on the host's PATH, tries ssh --version, then runs the saved connection vector — ssh -i <key file> -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 -p <port> <user>@<host> uptime. The key is written to a private file for the call; BatchMode means no prompt is ever answered, accept-new records the host key on first contact and refuses a changed one afterwards, and the five-second connect timeout keeps a host that drops packets from hanging the check. You should see a dialog titled <connection name> is connected with Connected — verified from the control plane, and later in the row's Last test ok · binary found: /usr/bin/ssh — … — 'ssh uptime' ok (<the host's uptime line>). When a private-network agent serves the workspace, the platform does not dial the host: the row shows the check as queued, the agent runs it, and the result reads Connected — verified by your private-network agent.
If something fails
The dialog shows Needs a fix, what to fix and the check's own detail; the row is saved either way. Select Edit, correct the field the detail names and save again, or select Retry once a cause outside the form (network, vendor-side permission) is fixed. Every verdict this connector produces, and what to do about it, is in Troubleshooting below.
Data collected
Tools the agent gets
<name>_exec— registered for a read-role connection, with the connection vector preconfigured so the agent would pass only the remote command (args=["df", "-h"]). The catalog listscat,ls,ps,df,free,uptime,uname,tail,head,grep,netstat,ss,ip,hostname,id,du,vmstat,iostat,top,stat,last,wandwhoas its read verbs for the approval gate.
Read surface
The approval gate's verb list never comes into play: the investigation's read floor runs before it, and that floor verifies reads for kubectl only. Every call to an SSH <name>_exec tool — a listed read verb, an unlisted command, a chained df; rm -rf … — is refused with Investigation connections are read-only. This operation was not executed; prepare an incident change using a write connection and obtain approval., and the estate x-ray denies it the same way and counts the denial. Nothing is executed on the host by any agent. The full rule table is under The read/write gate in detail in Connections and remediation access.
Approved commands
Approved writes use a separate connection: connect the write-capable account and key as a second SSH connection, choose Approved changes only (separate credential) under Use this connection for, tick Allow use for approved plans, and save with Save remediation credential. Agents never see a write-role connection. A cli remediation route on it names the exact command; after approval the Change executor runs it over the same connection vector, records what ran, and validates afterwards. Keep the OS account's own permissions narrow as well — a sudoers rule for the one command, no unrestricted sudo — because the platform's gate is a floor and the host is the boundary. How approvals and tiers apply is in Set up write connections.
Troubleshooting
| What you see | Cause | What to do |
|---|---|---|
400 'private_key' does not look like a PEM key (missing -----BEGIN block) — paste the full key file |
The paste lost the armor lines or the line breaks. | Paste the complete key file into the multi-line field. |
failed · binary 'ssh' not found on PATH |
The host that runs the check has no ssh client. | Ask your platform operator; a private-network agent needs it in its image. |
failed · 'ssh uptime' failed (exit 255): …Permission denied (publickey)… |
The public key is not in the user's authorized_keys, the user is wrong, or the key is passphrase-protected. |
Install the public key for that user; use an unencrypted key. |
failed · 'ssh uptime' failed (exit 255): …Connection timed out… or …Connection refused… |
No route from the platform to the host, or the wrong port. | Check the port; for a host on a private network, install a private-network agent inside it. |
failed · 'ssh uptime' failed (exit 255): …Host key verification failed… |
The host key changed since the first contact; accept-new refuses a changed key. |
Confirm the change with the administrator; your platform operator clears the recorded key. |
failed · 'ssh uptime' timed out after 5s |
The host accepted the connection but did not answer. | A forced-command wrapper that does not allow uptime blocks the check; allow it. |
| The row shows the check queued for the private agent and never returns | No live agent, or the agent cannot reach the host. | Check the agent's heartbeat under Connect and its route to the host. |
Every command through <name>_exec answers Investigation connections are read-only. |
The investigation read floor verifies kubectl reads only. | Expected in this release; see Read surface. |
| An approved command runs but the host refuses it | The OS account lacks the permission. | Grant it with a narrow sudoers rule on the write account. |
The generic verdict strings are explained in Test a connection and read the failure. Every connection status word is in the status and error reference.
Next steps
- Read what an investigation may run through this connection today: Read surface.
- Run approved commands through a separate write connection: Approved commands.
- The on-premises walkthrough, key commands included: Connect an on-premises server.
- See what else each agent needs in Choose your connection.