Skip to content

Adopt a private key

What you'll have at the end: the endpoint's existing private key copied into its Scout's managed storage — so renewals with Reuse private key across renewals keep the key (and any published pin) instead of rotating it. The key never crosses the network; this is a one-time on-host copy.

Prerequisites:

  • The endpoint is adopted with a profile that has Reuse private key across renewals enabled, and the profile's key type matches the existing key (an rsa_2048 profile for a 2048-bit RSA key).
  • The Scout can see the directory holding the served certificate and key — it must be listed in the Scout's cert-dirs configuration. If it isn't, do Track a new endpoint → Step 4 first. Without this, nothing below works: the Scout can only adopt a key it can find, and it only looks under directories the operator listed.

Time: about 5 minutes.

The example endpoint is shop.example.com on Scout web-01, serving from /etc/nginx/ssl/ with the key at /etc/nginx/ssl/shop.key.


Step 1 — Record the key's fingerprint (so you can prove reuse later)

On the endpoint host:

$ openssl rsa -noout -modulus -in /etc/nginx/ssl/shop.key | openssl sha256
SHA2-256(stdin)= ab12cd34ef56...

Keep that digest. At the end of this guide — and after every future renewal — the same command must print the same value.

Step 2 — Click Renew Now and get refused (this is expected)

On Manage, click Renew Now on shop.example.com.

You should see the renewal refused before any order is created:

pre-flight refusal: key_reuse_adoptable

with the Activity feed carrying the full sentence — the key this endpoint serves is at /etc/nginx/ssl/shop.key, which this Hub does not manage — and the remedy: run Adopt key, or switch the profile to fresh generation (which would break any published pin).

The refusal is the feature. A key-reuse profile whose key is not yet under management has exactly two honest outcomes — refuse, or silently rotate the key the profile promised to keep — and the product picks refuse. Nothing has been ordered and nothing has been spent.

Step 3 — Adopt the key from the drawer

Open the endpoint's drawer (click the row) and find, under available actions:

Adopt key from /etc/nginx/ssl/shop.key

Click it. You should see the activity entry:

Key adoption requested for `shop.example.com` — the Scout will verify the served key before adopting it

The verification is real and happens on the endpoint, by its own Scout:

  • The Scout resolves the served key itself from its cert-dir scan — the Hub deliberately does not tell it which file to read, so a compromised or misconfigured Hub cannot use this to exfiltrate an arbitrary file.
  • It confirms the key matches what the endpoint is currently serving — a stray or stale key file is refused, not adopted.
  • It refuses to overwrite an already-managed key — rotation must always be explicit.

On success the key is copied to the Scout's managed path for the domain (/opt/cyphers/data/certs/shop.example.com/privkey.pem on a default install), directory 0700, file 0600, written atomically.

Step 4 — Verify the copy yourself

On the endpoint host:

$ sudo ls -l /opt/cyphers/data/certs/shop.example.com/privkey.pem
-rw------- 1 root root 1704 ... privkey.pem
$ sudo openssl rsa -noout -modulus -in /opt/cyphers/data/certs/shop.example.com/privkey.pem | openssl sha256
SHA2-256(stdin)= ab12cd34ef56...

You should see the same modulus digest as Step 1 — the managed copy is the served key, byte for byte.

Step 5 — Renew again

Click Renew Now once more. You should see the pre-flight pass the key-reuse check this time — the renewal proceeds with a CSR signed by the adopted key, and the "Adopt key" offer disappears from the drawer (the Scout now holds the key, so there is nothing left to adopt).

After the renewal closes, repeat Step 1's command: same digest, new certificate. That is the whole point.

If the refusal changes to key_reuse_diverged later

That means something else rotated the served key after adoption — typically another renewer (certbot) still active on the host. Reuse is refused rather than fighting over the key: stop the other renewer, then adopt the key it left in place. See Take over certbot-managed endpoints.

Where to next