# SSH credentials

Generate a key in Opafra, install its public half, and attach it to as many servers as you like. The private half is shown once and never again.

Source: https://opafra.com/docs/access/ssh-credentials

---

An SSH key in Opafra is a named, reusable object. Create `prod-deploy` once, attach it to
twenty servers, and rotate it in one place.

Generating a key is the default and importing one you already have is supported. The
difference matters more than it looks.

## Before you begin

You need the **Operator** role or above to create or import an SSH key.

## Generate rather than upload

Uploading an existing key usually means uploading the key you already use, which is
usually your personal one. That key opens everything it was ever trusted for, and now a
copy of its private half has travelled from your laptop, through a browser, to a server.

A generated key starts with no trust at all. You decide which hosts accept it, and
revoking it affects exactly those hosts and nothing else.

## 1. Create the key

Open **Inventory**, then **SSH keys**, and choose **Generate key**. Give it a name that
says what it is for, because the name is what you will pick from when registering
servers.

Opafra generates an Ed25519 keypair, keeps the private half encrypted, and shows you:

- The **public key**, to install on your hosts
- The **`authorized_keys` line**, ready to paste
- The **private key**, once

> **Danger**
>
> The private half is shown exactly once, at creation. There is no endpoint that returns it
> a second time, and that is a design decision rather than an omission: a secret that can
> be fetched again is a secret with an ongoing exposure. If you lose it, generate a new key.

You do not need to save the private key at all if Opafra is the only thing using it,
which is the common case. Save it only if you also need to connect with it yourself.

## 2. Install the public half

Any way you already distribute keys works. The line is ordinary and nothing about it is
Opafra-specific:

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

For a fleet, put the line in your image, your cloud-init template, or whatever
configuration management already manages `authorized_keys`.

## 3. Attach it to servers

When registering or editing a server, pick the key by name. One key can serve any number
of servers, which is the point: the alternative is a credential per host and no way to
rotate them together.

Setting a key clears any other credential on that server, so there is never ambiguity
about which one is live.

## Importing a key you already have

Some teams have a provisioning key already trusted across a fleet, and re-keying
everything to adopt Opafra is not reasonable. Import is there for that.

Two things happen on import that are worth knowing:

- **The public half is re-derived from the private key** rather than trusted from what
  you paste. Pairing private-A with public-B would otherwise misrepresent what you are
  authorising on a host.
- **A duplicate is rejected** by fingerprint, so the same key cannot quietly exist twice
  under two names.

Passphrase-protected keys are not supported. Storing the passphrase alongside the key it
protects is theatre, so Opafra declines rather than pretending. Remove it first:

```bash
ssh-keygen -p -f ./id_ed25519
```

## Deleting a key

A key in use cannot be deleted. Opafra names the servers still using it and refuses,
rather than leaving those servers with no credential and an authentication failure
discovered mid-run.

Detach it from those servers first, then delete.

## Rotating

Generate the new key, install its public half alongside the old one, move servers to it,
then remove the old public half from the hosts and delete the old key.

Doing it in that order means no window where a host trusts neither key. The reusable-key
model is what makes this a handful of steps rather than one per host.

## The other credential types

Keys are the common case. Servers can also authenticate by password, by SSH certificate
from a CA you run, or through Vault SSH. All four are described under
[registering servers](/docs/inventory/servers).

Whichever you use, the credential is stored encrypted or as a
[reference](/docs/access/secret-references), and never appears in a plan, a log, or an
API response.

## Verify it worked

Open **Inventory**, then **SSH keys**. The key is listed with its type and fingerprint,
and the server you attached it to shows a key-count of at least one:

```text title="ssh keys"
prod-deploy    ed25519    SHA256:9f2a...c41d    2 servers
```

Then open one of those servers and run its connection check. `auth accepted` passing is
the proof the public half is installed correctly on that host.

## Next steps

- [Registering servers](/docs/inventory/servers) for attaching a key to a host
- [Secret references](/docs/access/secret-references) for how credentials are stored
