MyOwnPKI documentation Source on GitHub

Adding hosts

A host gets its certificate in one of two ways. Either it runs an ACME client that talks to the ACME server of MyOwnPKI, or it runs the agent, which uses ACME inside and adds deployment, reload, rollback and reporting. This page covers both and then the agent in detail. Ready-made settings for nginx, Postfix, Dovecot and Proxmox VE are on Recipes. Rolling the agent out to many machines is done with the Salt formula (since v0.3.6); it has its own page: Rolling out with Salt.

Which level for which host

  ACME client (level 1) Agent (level 3)
On the host certbot, acme.sh, lego, Traefik, Caddy, win-acme, cert-manager myownpki-agent, a systemd service (Linux)
Who renews The client, by its own schedule or with ARI The agent, at two thirds of the lifetime, or on Renew now in the UI
Deployment and reload You configure the client The agent writes the files, tests, reloads, and rolls back on failure
The server knows Issuances and renewals Also what is deployed, the serial, expiry, errors, and whether the host is alive
Good for Hosts that already run an ACME client; other operating systems Linux hosts with nginx or plain files that should be managed from one place

Level 1 needs no agent at all: point the client at the ACME directory and trust your root (operations guide §10). To have the server also check what such a host really serves (level 2), enter it as an endpoint: see TLS scan. The rest of this page is about the agent.

What the server needs first

The agent needs more than ACME. Check this once on the server (operations guide §12.1):

  1. ACME works, and a domain (ACME → Domains) covers every host name the agent may order, for example homelab.lan. The same domain is used to prove that a host controls its name when it enrolls.
  2. An agent CA: an intermediate directly below the root with the EKU limit clientAuth only, named for example agent-ca. It signs only the agents’ 7-day client certificates. Do not create it below an intermediate with pathlen: 0.
  3. The agent listener in /etc/myownpki/config.yaml:

    agent:
      base_url: https://pki.homelab.lan:8444
      listen: ":8444"
      tls_issuer: issuing   # issues the listener's server certificate
      ca: agent-ca          # signs and authenticates agent client certificates
    

    Check the file, restart and unseal; the server issues the listener certificate once it is unsealed. config check and the start verify the agent CA and its EKU limit.

  4. Port 8444/tcp from the agent hosts to the server is open.
  5. The package files are available: install.sh published them in /var/lib/myownpki/agent-dist (agent.package_dir); the container image has them in /opt/myownpki/agent-dist.

Add host: the guided installation

The default way, from a new host name to a deployed certificate. In the UI choose Agents → Add host (or the button on the agent list) and go through four steps:

  1. Your answers. The exact host name (an FQDN that resolves to the host and is covered by a domain), the service (nginx, Postfix, Dovecot, Proxmox VE, or certificate files only), how the host answers the enrollment check, standalone (the agent listens on port 80 for a moment) or webroot (a web server already answers port 80 and the agent writes a file into a directory it serves), up to four more certificate names (optional), and the package: deb, rpm, tarball with the architecture, or already installed. The Postfix, Dovecot and Proxmox VE choices are marked example recipe: see Recipes.
  2. Admission. The page checks every name against your domains (a name no domain covers, or a domain without http-01, is refused), names the tenant’s enrollment mode, and lists the ways to get the host admitted with the approval each one still needs: a single-use token for this host (admin and a fresh second factor), an existing enrollment pass that covers the host (shown by label and uses, never its secret), or no secret (one approval in the UI).
  3. Commands, shown once. The answer is the page with the commands; it is not cached and shows a token only now. Run the blocks as root on the target host, not on the PKI server: the token file (a here-document for a token, a prompt for a pass), the verified root and package download, the installation and myownpki-agent setup, then deployment add, and a last line, myownpki-agent deployment list.
  4. Progress. Add host: <name> follows the host and reloads itself every 10 seconds: Host enrolled (waiting for the host, checking, waiting for your approval with Approve and Refuse for an admin, admitted), Agent online (first report, last seen, silent) and one row per deployment (pending, deployed with serial and expiry, failed or rolled back with the agent’s last error). The page stops reloading when the certificate is deployed.

The result page shows, once, the independent values from the authenticated UI: the root certificate’s SHA-256 and the package’s SHA-256. These are what you compare against, because the downloaded files cannot vouch for themselves. The commands download the root over HTTP and check its fingerprint, download the package and checksums.txt over HTTPS with that root, check the package, install it and run setup. A single-use token is valid for exactly this host name (and the extra names), once, for 15 minutes; it goes to /root/myownpki-join-token with mode 0600 and never on a command line. If it has expired or was used, start the assistant again: there is no way to show it a second time.

Anyone who can read the PKI (viewer and up) can open the assistant and watch the progress, and can get the commands for no secret or an existing pass. Making a token, and approving or refusing an enrollment, need an admin with a fresh second factor.

The older page Agents → Install agent is still there. It does the same for the install and setup part, without the service and the progress page.

What happens at setup: it validates everything before it changes the host, then writes /etc/myownpki-agent/agent.yaml (an existing customized file is kept), the unit /etc/systemd/system/myownpki-agent.service and the drop-in 10-paths.conf (with 20-low-ports.conf for standalone mode), and enrolls before it enables or starts anything. deployment add then adds the deployment to agent.yaml and the sandbox, and --restart restarts the agent so that it asks for the first certificate.

Admission: token, check, approval

The server admits an agent according to the tenant’s enrollment mode (Administration → Tenant settings):

Mode Valid join token Control of the name proven (http-01) Result
verified (default) yes yes admitted
verified only one of the two   waits for an admin
auto yes, or the check passed   admitted
manual any any waits for an admin

An enrollment pass (below) is the exception: it admits only together with a passed check, in verified and in auto, and never in manual.

Changing the mode needs a fresh second factor, because auto admits a host without a person, and an API token can never do it. In the UI the form asks for the code and then saves; over the REST API a PUT /api/v1/settings with a different agent_enrollment answers 403 (step-up-required for a session without a fresh code, forbidden for a token). Saving other settings, or the same mode, needs no code.

A token is valid when it is unused, not expired, and its name patterns match the host. A token is marked used even when the agent then waits in the queue. A waiting agent leaves the service disabled and prints systemctl enable --now myownpki-agent for use after approval; an admin approves it under Enrollment requests (fresh second factor), then run setup again, which polls the pending request, or enable the service. The queue shows which of the two proofs failed.

Without a token you can still enroll: the agent lands in Enrollment requests and waits. The alternative flow Agents → Join tokens → Create token makes a token for exact names or patterns such as *.apps.homelab.lan, with a validity of your choice; it is still single-use. Store its secret in a file with mode 0600 and never in agent.yaml or on a command line.

The enrollment pass for roll-outs

A single-use token enrolls one host, and a person creates it with the second factor. To enroll many hosts from Salt, Ansible, a script or CI without anybody opening the UI for each one, an admin creates an enrollment pass once, in Agents → Join tokens → New enrollment pass, again with the second factor:

Field Rule
Label Required: what the pass is for (it is on the list and in the audit log)
Host names 1 to 5, each an exact name or *.suffix, each covered by a domain of this PKI
Hosts it may admit 2 to 25 (default 10); a larger fleet takes two passes
Valid for Up to 7 days (default 24 hours)

The pass is shown once; the server keeps only its hash. A host is admitted by a pass only when the pass is active (not revoked, used up or expired), the host name matches, the http-01 check passed and the host has no agent yet. The host gets its own name only, not the pattern. Every enrollment that presents a valid pass takes one use, also when it then waits in the queue. The list shows active 3 of 10, used up, expired or revoked, and the hosts each pass admitted. Revoke ends its use at once; hosts it already admitted stay, listed, for you to refuse or disable.

On the host the pass goes into the token file, exactly like a token, and setup --token-file uses it:

sudo /usr/local/bin/myownpki-agent setup \
  --server https://pki.homelab.lan:8444 \
  --ca-bundle root.pem \
  --root-sha256 AA:BB:CC:... \
  --token-file /root/myownpki-join-token \
  --webroot /var/www/html

With Salt you do not run this yourself: the formula keeps the pass in the pillar, writes the token file only while the host has no agent certificate and calls setup --token-file (see Rolling out with Salt).

When the pass does not count, the host is not lost: it waits in Enrollment requests and setup prints why (see Troubleshooting).

Warning: A pass admits hosts without a person looking at each one. A leaked pass admits at most as many more hosts as it has uses left, for names that match, only if the server can reach port 80 under that name, for at most its validity. Keep it in an encrypted store, make it short and small, remove it after the roll-out and revoke it at once if it leaks; then read the list of hosts it admitted and refuse or disable the ones you do not know.

An API token can never create or revoke a pass, whatever its role: that takes a person with a fresh second factor. Give automation a viewer token to read the result (GET /api/v1/agents?hostname=…, GET /api/v1/agent-enrollments?hostname=…, GET /api/v1/agent-join-tokens and GET /api/v1/agent-install), as in Rolling out with Salt.

Manual installation from a package

Use this when you cannot use the guided page, or when you install by script. Check the downloads exactly as the guided page does.

v=0.3.8
curl -fsSLO "https://github.com/Der-Felix/MyOwnPKI/releases/download/v$v/checksums.txt"
curl -fsSLO "https://github.com/Der-Felix/MyOwnPKI/releases/download/v$v/checksums.txt.sigstore.json"
curl -fsSLO "https://github.com/Der-Felix/MyOwnPKI/releases/download/v$v/myownpki-agent_${v}_linux_amd64.deb"
sha256sum --check --ignore-missing checksums.txt

Packages exist as myownpki-agent_<version>_linux_<amd64|arm64>.deb, .rpm and .tar.gz. With cosign check checksums.txt first, as in the README. Install the package:

sudo apt-get install ./myownpki-agent_0.3.8_linux_amd64.deb
sudo dnf install ./myownpki-agent_0.3.8_linux_amd64.rpm

A package puts the binary at /usr/local/bin/myownpki-agent, a pristine /etc/myownpki-agent/agent.yaml (kept on upgrades) and unit examples in /usr/share/myownpki-agent/examples. It has no maintainer scripts and never enables or starts the service. For a tarball, verify it, unpack it and install the binary as /usr/local/bin/myownpki-agent. All three formats run the same setup.

The root certificate is the independent trust anchor. Get root.pem (the trust page of the public listener, or the guided page), then compare its SHA-256 over the DER form with the value in the admin UI:

openssl x509 -in root.pem -outform DER | sha256sum

Then run setup as root. With a web server that already answers port 80, use webroot:

sudo /usr/local/bin/myownpki-agent setup \
  --server https://pki.homelab.lan:8444 \
  --ca-bundle root.pem \
  --root-sha256 AA:BB:CC:... \
  --package-format deb \
  --token-file /root/myownpki-join-token \
  --webroot /var/www/html
setup option Meaning
--server URL The agent listener, https://host[:port], without a path (required)
--ca-bundle FILE The root certificate in PEM form. It must be one self-signed CA whose SHA-256 matches --root-sha256.
--root-sha256 HEX The expected SHA-256 of the root’s DER form (required; colons allowed)
--token-file FILE A regular file with mode exactly 0600 that holds the join token or the enrollment pass. Deleted only when this run newly gets admitted.
--package-format deb, rpm or tarball (default); recorded and reported so the UI can suggest the right update
--webroot DIR An existing directory your web server serves on port 80. Without it, enrollment uses standalone http-01.
--hostname FQDN The name to prove. Default: the host’s fully qualified name.
--acme-directory URL The ACME directory, https://…/acme/directory. It is written into a new agent.yaml, so that the first deployment needs no hand edit. An existing file is kept as it is.
--low-ports Install the capability drop-in for ports below 1024 even in webroot mode
--config FILE Another agent.yaml path. Default $MYOWNPKI_AGENT_CONFIG, then /etc/myownpki-agent/agent.yaml.

setup is safe to run again: an already enrolled host keeps its configuration and the service is restarted. It also keeps what you added to the systemd drop-ins by hand (see The systemd sandbox and paths).

Adding a deployment: deployment add

deployment add writes a deployment into agent.yaml and makes the systemd sandbox allow what it needs, in one step. That replaces the two hand edits that used to be required and that showed up only as Read-only file system after the first failed renewal. Run it as root on the host (also with --dry-run); it needs agent v0.3.5. Look at the change first:

sudo /usr/local/bin/myownpki-agent deployment add proxy --recipe nginx --name minion-01.homelab.lan --webroot /var/www/html --acme-directory https://pki.homelab.lan/acme/directory --create-dirs --dry-run

--dry-run prints a diff of agent.yaml and both drop-ins and writes nothing. Run the same line without it, then restart the agent (or add --restart):

sudo systemctl restart myownpki-agent
Flag Meaning
--recipe nginx, postfix, dovecot or proxmox Defaults for the service, see Recipes. Every other flag overrides them.
--name FQDN (repeat) Certificate names. Default: the host name of agent.yaml.
--profile nginx or file, --dir DIR, --certificate, --chain, --fullchain, --key FILE Where the files go: --dir for the nginx profile, the file flags for the file profile
--challenge webroot, standalone or dns-01, --webroot DIR Default: what the enrollment uses. A wildcard name (--name '*.homelab.lan') needs dns-01, which needs no port 80 and no --webroot; see below.
--owner, --group, --key-mode Local ownership and mode of the key (no rights for others)
--hook NAME='CMD ARGS' (repeat), --test-hook NAME, --reload-hook NAME Hooks: no shell, the first element is an absolute path. An identical command line is reused, so deployments of one service share one reload and one rollback group.
--check HOST:PORT The local TLS check; implicit TLS only, so a STARTTLS port (25, 143, 587) cannot be checked
--check-name NAME The server name (SNI) of that check. Needed when every name is a wildcard: *.homelab.lan is not a name a server can be asked for. Default: the first name that is not a wildcard.
--dns-provider NAME, --dns-type rfc2136 or cloudflare, --dns-credentials FILE, --dns-nameserver HOST[:PORT], --dns-zone ZONE, --dns-resolver IP[:PORT] For --challenge dns-01 (since v0.3.7): which provider entry to use, and how to define a new one. All explained on dns-01 and wildcard certificates.
--sandbox-write DIR (repeat), --low-ports Directories the hooks may write (nginx: /var/log/nginx), and ports below 1024 for the hooks
--acme-directory URL Needed when agent.yaml has no acme_directory yet
--create-dirs, --restart, --dry-run, --config FILE Create missing directories; restart the agent afterwards; show the diff only; another file

It checks the result with the same rules as config check before it writes a byte, refuses a name that exists, and refuses system directories such as /, /etc, /var or /home for --dir, --webroot and --sandbox-write (a wide one such as /etc/nginx only gets a warning that names a narrower directory). It keeps the previous file as agent.yaml.bak, keeps your comments, reloads systemd (daemon-reload) and prints the restart command; it never restarts the agent by surprise.

sudo /usr/local/bin/myownpki-agent deployment list

lists name, profile, names, targets, hooks and check (it also runs without root). deployment remove NAME takes a deployment out again and recomputes the drop-ins; it keeps paths unless you pass --prune-paths, and it never touches deployed files or the agent’s state.

Use one owner for agent.yaml: either an admin with deployment add, or a configuration tool that renders the whole file and then runs sandbox sync. A rendered file overwrites what add wrote. The Salt formula offers both and refuses to mix them: the pillar has either deployments (it calls deployment add) or config_source (it renders the file and runs sandbox sync).

A wildcard or a host without port 80: dns-01

Since v0.3.7 a deployment can prove its names through a DNS TXT record instead of port 80. That is the only way to get a wildcard certificate, and it works for a service without port 80 and for a host behind NAT. The agent writes the record through RFC 2136 (BIND, Knot, PowerDNS with a TSIG key) or through the Cloudflare API, with the secret in a root-only file of its own that is never part of agent.yaml. Run deployment add by hand for it: the Add host assistant does not offer dns-01.

sudo /usr/local/bin/myownpki-agent deployment add wild --recipe nginx --name '*.homelab.lan' --name homelab.lan --challenge dns-01 --dns-provider homelab-dns --dns-type rfc2136 --dns-nameserver 192.0.2.53 --dns-credentials /etc/myownpki-agent/dns/homelab.yaml --check-name www.homelab.lan --dry-run

The agent’s Names it may order on the server must list *.homelab.lan and homelab.lan (a wildcard is covered only by the identical pattern), and the domain must allow wildcards. The whole procedure, the DNS server and Cloudflare settings and the errors are on dns-01 and wildcard certificates with the agent.

agent.yaml

The file is /etc/myownpki-agent/agent.yaml; the state (key, certificate, deployment history) is in /var/lib/myownpki-agent (mode 0700). After every edit:

myownpki-agent config check
systemctl restart myownpki-agent

config check names every problem at once and prints the effective sandbox. A first file from setup has no deployments; you add them with deployment add (above) or by hand. This is what an nginx host looks like after that, and the file deployment add --recipe nginx produces is similar:

server: "https://pki.homelab.lan:8444"
ca_bundle: "/etc/myownpki-agent/root.pem"
hostname: "minion-01.homelab.lan"
state_dir: "/var/lib/myownpki-agent"
log_level: "info"
acme_directory: "https://pki.homelab.lan/acme/directory"
enrollment:
  challenge: webroot
  webroot: "/var/www/html"
hooks:
  nginx-test: ["/usr/sbin/nginx", "-t"]
  nginx-reload: ["/usr/bin/systemctl", "reload", "nginx"]
paths: ["/var/www/html", "/etc/nginx/myownpki"]
deployments:
  - name: web
    profile: nginx
    names: ["minion-01.homelab.lan"]
    challenge: webroot
    webroot: "/var/www/html"
    dir: "/etc/nginx/myownpki/web"
    test_hook: nginx-test
    reload_hook: nginx-reload
    check: "127.0.0.1:443"

The agent writes fullchain.pem and privkey.pem into dir; reference those two files in the nginx server block.

Key Meaning
server, ca_bundle, hostname The agent listener, the root PEM (absolute path), the FQDN proven at enrollment
acme_directory The ACME directory URL, https://…/acme/directory; required as soon as there is a deployment
proxy An http:// or https:// proxy for both connections. The agent ignores HTTPS_PROXY and HTTP_PROXY; only this key sets a proxy.
state_dir, log_level State directory (absolute) and debug, info, warn or error
enrollment.challenge standalone or webroot for the enrollment check; enrollment.webroot is the directory for webroot
hooks Named commands. Each is a list; the first element is an absolute path. No shell, no sudo.
paths The only directories the agent may write to, apart from its state: web roots and the parents of deployment targets
sandbox.write Directories that only hooks write (nginx: /var/log/nginx); they go into the drop-in 10-paths.conf, not into paths. The agent itself does not get them.
sandbox.low_ports true: install 20-low-ports.conf; false: remove it; unset: install it for any standalone challenge, otherwise leave it as found
deployments[].name Lower-case letters, digits and -, unique
deployments[].profile nginx (writes fullchain.pem and privkey.pem into dir) or file (explicit target files)
deployments[].names 1 to 100 DNS names for the certificate. Each must be covered by the agent’s Names it may order on the server. A name that starts with *. (a wildcard, at least two labels after it) is allowed only with challenge: dns-01.
deployments[].challenge, webroot standalone or webroot for the ACME http-01 of this certificate; the webroot lies below paths. dns-01 (since v0.3.7) proves the names through a DNS TXT record: no port 80, no webroot, and it needs dns_provider.
deployments[].dns_provider With dns-01: the name of an entry in dns_providers
deployments[].files For file: key and certificate or fullchain, optionally chain
deployments[].owner, group, key_mode Local ownership and an octal mode without rights for others (for example "0600" or "0640")
deployments[].test_hook, reload_hook Names from hooks: run before the reload (for example nginx -t) and the reload itself
deployments[].check host:port of the local TLS endpoint. After the reload the agent connects with SNI and compares the served certificate with the deployed one.
deployments[].check_name The SNI of that check, a concrete host name. Needed when every name is a wildcard; default: the first name that is not a wildcard.
dns_providers A map from a name to how the agent writes the TXT record of a dns-01 challenge: type (rfc2136 or cloudflare), credentials_file (absolute path of a root-only file with the secret), nameserver, zone, ttl, resolver, propagation, propagation_wait, propagation_timeout. It holds no secret. Every key is in dns-01 and wildcard certificates.

For files you manage yourself, use the file profile:

  - name: web
    profile: file
    names: ["minion-01.homelab.lan"]
    challenge: webroot
    webroot: "/var/www/html"
    files:
      fullchain: "/etc/nginx/myownpki/web.fullchain.pem"
      key: "/etc/nginx/myownpki/web.key"
    key_mode: "0600"
    test_hook: nginx-test
    reload_hook: nginx-reload
    check: "127.0.0.1:443"

Deployments that share a non-empty reload hook are staged, tested, reloaded and, on failure, rolled back together. A first-time failure removes the new files. If a rollback itself fails, both errors are reported and the agent does not retry in a loop.

Warning: A hook must not write secrets to stderr. The last lines of a failed hook’s stderr go into the agent log and into the deployment’s last_error on the server, filtered and cut to 1 KiB, but still.

The systemd sandbox and paths

The unit runs as root, because setting owners and systemctl reload need it, but under ProtectSystem=strict, NoNewPrivileges=yes, a private /tmp, restricted address families and the @system-service system calls. Only the state directory is writable. Everything else must be allowed twice: in paths of agent.yaml (what the agent may write) and in the drop-in /etc/systemd/system/myownpki-agent.service.d/10-paths.conf (what systemd lets the unit write).

Since v0.3.5 the agent writes that drop-in for you. setup, deployment add, deployment remove and sandbox sync derive it from agent.yaml: the state directory, every entry of paths, and the directories of the optional sandbox.write list, which are the ones only a hook writes (nginx opens its log files, so /var/log/nginx):

sandbox:
  write: [/var/log/nginx]
  low_ports: true

The drop-in then looks like this, and you do not have to touch it:

[Service]
ReadWritePaths=/var/lib/myownpki-agent /var/www/html /etc/nginx/myownpki /var/log/nginx

What the agent does with a drop-in that already exists:

sudo /usr/local/bin/myownpki-agent sandbox sync --dry-run

shows what would change in both drop-ins; sandbox sync without --dry-run writes it, and you then restart the agent. config check prints the effective list and whether the drop-ins on disk match it. If nginx -t says Read-only file system for a temporary directory, add that directory with --sandbox-write (for example below /var/cache/nginx or /var/lib/nginx). Never make /etc, /var or / writable; the commands refuse it.

If you do edit 10-paths.conf by hand, run systemctl daemon-reload and restart the agent afterwards. Updating a host from v0.3.4 or earlier: run setup once (the Update commands of the agent page). It keeps a hand-made /var/log/nginx and an installed 20-low-ports.conf; earlier versions rewrote the first and removed the second.

The sandbox contains mistakes; it is not a boundary against code that runs as root in the agent. The real protection is that the agent takes no commands from the server and runs only hooks from the root-owned agent.yaml.

Ports below 1024

Standalone mode binds port 80, and the nginx hooks open the listen sockets of nginx (nginx -t with a listener on 443 fails with bind() … Permission denied otherwise). Both need the drop-in 20-low-ports.conf with CAP_NET_BIND_SERVICE, also in webroot mode for the nginx hooks. The agent installs it when sandbox.low_ports is true, when the enrollment or any deployment uses the standalone challenge, or when you pass --low-ports to setup or deployment add (the nginx recipe does). It removes the file only for an explicit sandbox.low_ports: false, and it does not overwrite a file that differs from the packaged one. You can also install it by hand from the package examples:

sudo install -d -m 0755 /etc/systemd/system/myownpki-agent.service.d
sudo install -m 0644 /usr/share/myownpki-agent/examples/agent-low-ports.conf /etc/systemd/system/myownpki-agent.service.d/20-low-ports.conf
sudo systemctl daemon-reload && sudo systemctl restart myownpki-agent

Ports and firewall

From To Port Purpose
Agent host Server 8444/tcp The agent channel, mutual TLS
Agent host Server The ACME HTTPS port (443 or your reverse proxy) Certificate orders
Server Agent host 80/tcp http-01 for enrollment and for every order
Agent host The DNS server, or api.cloudflare.com 53/tcp, or 443/tcp Only with dns-01: the agent writes the TXT record. More ports (the resolver, the name servers) are in the firewall table.

The agent only makes outbound connections; the server never connects to an administrative port on the agent. But http-01 means the server fetches /.well-known/acme-challenge/… from port 80 of the host, so that port must be open from the server to the host, a firewall on the host (nftables, ufw) included, and the name must resolve to the host from the point of view of the server (acme.resolver). In webroot mode the web server on port 80 must answer the challenge directory; in standalone mode port 80 is bound only while a check runs. A deployment with challenge: dns-01 needs no port 80 at all (but the host still enrolls with http-01, or with an approval).

Renewal, “Renew now” and what the agent reports

The agent renews at two thirds of the certificate’s lifetime, or earlier if the server’s ARI window asks for it. On the agent’s page in the UI Renew now (operator and admin) wakes the agent through a bounded long-poll and it runs its normal ACME path, with a new key. Failures back off instead of retrying continuously.

The agent reports every five minutes (with jitter) and right after each deployment pass: last seen, version, installed package format, and for each deployment the state (deployed, failed, rolled_back or pending), serial, expiry and last error. An agent is silent after three missed reports. Reports and watches are rate-limited per agent to 60 and 120 calls per 10 minutes, far above normal use.

Note: After a successful renewal the old certificate is revoked according to the tenant’s predecessor setting. The default for agent deployments is immediately after the deployment is confirmed, and for other certificates after seven days. A revocation happens only after an accepted deployed report with proof that the new certificate is the one being served. Review both defaults in Administration → Tenant settings.

Look at one host:

myownpki-agent status
journalctl -u myownpki-agent -n 100 --no-pager

Removing a host

To enroll the same host as a new agent, create a new join token (or use the guided page), stop the service and remove the old identity, the ACME account files together, and keep the deployment history:

sudo systemctl stop myownpki-agent
sudo sh -c 'cd /var/lib/myownpki-agent && rm -f agent.json agent.key agent.crt pending.key enrollment.json acme-*.key acme-*.json'
sudo /usr/local/bin/myownpki-agent enroll --token-file /root/myownpki-join-token
sudo systemctl start myownpki-agent

Keep deployments.json, deployment-journal.json, deploy-backup-* and webroot-files.json; they hold deployment history, rollback data and crash cleanup. To uninstall an agent for good, disable and stop the service, remove the unit and its .service.d directory under /etc/systemd/system, remove the package, and delete /etc/myownpki-agent, /var/lib/myownpki-agent and the certificate files it deployed. Nothing does this for you.