# Registering servers

Add a host by giving Opafra its address, a user to connect as, and a credential. Nothing is installed on the machine.

Source: https://opafra.com/docs/inventory/servers

---

Registering a server tells Opafra how to reach a host: its address, the user to connect
as, and which credential to use. Nothing is installed on the machine, and the host does
not need to know it has been registered until the first connection.

## Before you begin

You need the **Operator** role or above to register a server.

- A hostname or IP that resolves from where Opafra runs, and an SSH port
- A user account on the host
- A credential that user can authenticate with

If the account needs elevated privilege for the plans you intend to run, it also needs
`sudo` that does not prompt for a password. A run cannot answer a password prompt.

## 1. Add the server

Open **Inventory**, choose **Add server**, and fill in the name, host, user and port. The
name is how plans refer to the host, so it is worth making it the name your team already
uses rather than the raw address.

Then choose how it authenticates. There are four methods:

| Method | Use it when |
|---|---|
| **Managed key** | The default. Opafra generates a keypair, keeps the private half encrypted, and shows you the public half to install. |
| **Password** | The host only accepts passwords. Stored as a reference, never in a plan. |
| **SSH certificate** | You run a certificate authority and want short-lived certificates instead of long-lived keys. |
| **Vault SSH** | Vault issues the credential at connection time. |

> **Tip**
>
> Prefer a managed key generated by Opafra over uploading one you already have. A key you
> already use is usually your personal key, which opens far more than this one host. A
> generated key can be scoped to exactly the servers you attach it to, and revoked without
> touching anything else.

## 2. Install the public half

A managed key is generated as a keypair. Opafra keeps the private half; you install the
public half on the host, the same way you would for any other key:

```bash title="on your machine"
ssh-copy-id -i ~/Downloads/opafra-prod-deploy.pub ops@web-01.example.com
```

Or append the `authorized_keys` line Opafra shows you directly, if you already have a way
to push files to the host. Configuration management, a cloud-init template and a golden
image all work: the line is ordinary and there is nothing Opafra-specific about it.

> **Important**
>
> The private half is shown exactly once, when the key is created. There is no endpoint that
> returns it a second time, by design. If you lose it, generate a new key rather than trying
> to recover the old one.

## 3. Read the connection check

Saving a server runs a connection check immediately. It walks five stages in order and
reports each one, so a failure names the thing that actually broke rather than saying the
host is down:

| Stage | What it proves | If it fails |
|---|---|---|
| **DNS** | The name resolves | The name is wrong, or not resolvable from where Opafra runs |
| **TCP** | The port accepts a connection | A firewall, a security group, or sshd is not listening |
| **Auth** | The credential is accepted | The public half is not installed, or the user is wrong |
| **Sudo** | The user can elevate without a prompt | Plans needing privilege will fail; plans that do not are fine |
| **Facts** | The host answered basic questions about itself | Usually harmless |

The first three are hard failures and stop the walk. **Sudo and facts are warnings**: a
server that cannot `sudo` is still registered and still usable, because plenty of plans
never need it. Later stages that never ran are shown greyed rather than hidden, so the
ladder always has the same shape.

The whole check is capped at 30 seconds, so a hung host fails rather than hanging the page.

The check also reads current host metrics: CPU, memory and disk usage, and the one, five
and fifteen minute load averages. They are stored against the server and shown on it, so
a connection check doubles as a snapshot of how the machine is doing. Any
[alert rules](/docs/inventory/alerts) you have are evaluated against those numbers at the
same time.

## Hosts you cannot reach directly

A host on a private network can name another registered server as its **bastion**, and
Opafra connects through it. The bastion is itself a normal server in your inventory with
its own credential.

Chains are allowed up to **three hops**. Beyond that Opafra refuses the configuration
rather than attempting it, as does a chain that loops back on itself. If a connection
check reports that the bastion was unreachable, the target may be perfectly healthy: what
failed is the path to it.

An environment can also name a **default bastion**, which every host in it uses unless it
names its own. That is usually the right way to configure a whole private subnet once
instead of per host.

## What Opafra stores

The address, port, user, which credential to use, and what the last connection check
observed. Credentials are stored encrypted or as references to a secret provider. A
private key never appears in a plan, a command, a log, or an API response.

## Verify it worked

Open **Inventory**. The server appears in the list with a green status dot and its
detected OS family. Open it and the connection check shows all five stages:

```text title="connection check"
DNS resolves          ok
TCP :22 reachable     ok
auth accepted         ok
sudo available        ok
facts gathered        ok
```

`sudo available` and `facts gathered` may report a warning without the server being
unusable. The first three must pass, or the host is not reachable and the server cannot
run anything.

## Next steps

- [Agentless SSH](/docs/inventory/agentless-ssh) for what Opafra needs on the host, exactly
- [Environments](/docs/inventory/environments) for grouping hosts and attaching policy
