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:

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

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

  1. Open Settings · Data in → Data sources and select Connect datasource.
  2. 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.
  3. 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
  1. Optionally, open Optional · describe this environment and fill What should AIOps know about it? with what runs on the host.
  2. 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

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