Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

akamu-cli — Command Reference

akamu-cli is a command-line ACME client that wraps akamu-client. It covers the full ACME lifecycle: account management, certificate issuance with multiple challenge types, ARI-aware renewal, and revocation.

Installation

Build from source

cargo build -p akamu-cli --release

The binary is placed at target/release/akamu-cli.

sudo install -m 0755 target/release/akamu-cli /usr/local/bin/akamu-cli

cargo install (from a local checkout)

cargo install --path crates/akamu-cli

This installs the binary to ~/.cargo/bin/akamu-cli.

Command tree

akamu-cli
  account
    register       Register a new ACME account
    deregister     Deactivate an existing account (RFC 8555 §7.3.7)
    show           Print current account URL, status, and contacts
    update         Update account contact list
    key-change     Roll the account key to a new key (RFC 8555 §7.3.5)
  issue            Obtain a certificate (http-01 / dns-01 / dns-persist-01 /
                   tls-alpn-01 / onion-csr-01)
  renew            ARI-aware renewal (RFC 9773); skips issuance if outside window
  revoke           Revoke a certificate via account key or certificate's own key

Subcommands

account register

Register a new ACME account and save the account URL to a sidecar file.

akamu-cli account register --server URL --account-key FILE [OPTIONS]
FlagRequiredDescription
--server URLyesACME directory URL. Default: Let’s Encrypt production.
--account-key FILEyesPath to the account key PEM file. Generated and saved if the file does not exist.
--key-type TYPEnoKey type to generate when the key file does not exist. Default: ec:P-256.
--contact URInoContact URI (e.g. mailto:admin@example.com). Repeatable.
--agree-tosnoAgree to the server’s Terms of Service.
--eab-kid KIDnoExternal Account Binding key ID.
--eab-key KEY_B64UnoEAB HMAC key encoded as base64url (no padding).
--eab-alg ALGnoEAB HMAC algorithm: HS256, HS384, or HS512. Default: HS256.

After registration the account URL is written to <account-key>.account-url (see Sidecar file).

account deregister

Deactivate an existing account (RFC 8555 §7.3.7).

akamu-cli account deregister --server URL --account-key FILE

The account URL is read from <account-key>.account-url. After deactivation the sidecar file is removed.

account show

Fetch the current account state from the server and print it.

akamu-cli account show --server URL --account-key FILE

Output example:

URL:     https://acme.example.com/acme/account/1234
Status:  valid
Contact: mailto:admin@example.com

account update

Update the contact list for an existing account.

akamu-cli account update --server URL --account-key FILE [--contact URI ...]
FlagRequiredDescription
--server URLyesACME directory URL
--account-key FILEyesAccount key PEM file
--contact URIno (repeatable)New contact URI. Omit entirely to clear all contacts.

account key-change

Roll the account key to a new key (RFC 8555 §7.3.5). The server atomically replaces the account key. The new key is written back to --account-key, overwriting the old one. The account URL sidecar file is unchanged.

akamu-cli account key-change --server URL --account-key FILE --new-key FILE [OPTIONS]
FlagRequiredDescription
--server URLyesACME directory URL
--account-key FILEyesCurrent account key PEM file
--new-key FILEyesNew key PEM file. Generated if the file does not exist.
--new-key-type TYPEnoKey type for generation when --new-key file is absent. Default: ec:P-256.

After success, --account-key contains the new key.

issue

Obtain a certificate for one or more domains.

akamu-cli issue --server URL --account-key FILE -d DOMAIN --out FILE [OPTIONS]
FlagRequiredDescription
--server URLyesACME directory URL
--account-key FILEyesAccount key PEM file
-d DOMAINyes (repeatable)Domain to include. First value becomes the CN.
--out FILEyesOutput path for the PEM bundle (leaf + chain).
--key-type TYPEnoAccount key type when generating a new key. Default: ec:P-256.
--cert-key-type TYPEnoCertificate key type. Default: ec:P-256.
--cert-key FILEnoReuse an existing certificate private key PEM file. Generated and saved alongside --out if absent.
--challenge TYPEnoChallenge type: http-01, dns-01, dns-persist-01, tls-alpn-01, onion-csr-01. Default: http-01.
--http-port PORTnoPort for the built-in http-01 solver. Default: 80.
--tls-port PORTnoPort for the built-in tls-alpn-01 solver. Default: 443.
--onion-key FILErequired for onion-csr-01Ed25519 hidden-service private key PEM file.
--poll-timeout SECSnoMaximum seconds to wait for order/challenge validation. Default: 120.
--eab-kid KIDnoEAB key ID (used if no account exists yet).
--eab-key KEY_B64UnoEAB HMAC key (base64url).

If the account URL sidecar file does not exist, issue registers a new account first.

The http-01 and tls-alpn-01 challenge types cannot validate wildcard identifiers (RFC 8555 §8.3, RFC 8737 §3). Use dns-01 or dns-persist-01 for *.example.com.

The certificate private key is generated and saved to <out>.key.pem unless --cert-key is provided.

renew

Check the ARI renewal window (RFC 9773) for an existing certificate, then issue a replacement if renewal is suggested or --force is given.

akamu-cli renew --server URL --account-key FILE -d DOMAIN --out FILE [OPTIONS]
FlagRequiredDescription
--server URLyesACME directory URL
--account-key FILEyesAccount key PEM file
-d DOMAINyes (repeatable)Domains for the new certificate
--out FILEyesOutput path for the new PEM bundle
--cert FILEnoExisting certificate PEM to check against ARI. Without this flag, no ARI check is performed.
--forcenoRenew unconditionally, skipping the ARI window check.
--challenge TYPEnoSame values as issue. Default: http-01.
--http-port PORTnoDefault: 80.
--tls-port PORTnoDefault: 443.
--onion-key FILEnoRequired for onion-csr-01.
--poll-timeout SECSnoDefault: 120.
--key-type TYPEnoAccount key type. Default: ec:P-256.
--cert-key-type TYPEnoCertificate key type. Default: ec:P-256.
--eab-kid KIDnoEAB key ID.
--eab-key KEY_B64UnoEAB HMAC key (base64url).

Behavior when --cert is given and --force is not:

  • If the current time is before the ARI window start, the command exits without issuing and prints a message.
  • If the current time is within (or past) the window, issuance proceeds.
  • If the server does not support ARI or returns an error, issuance proceeds with a warning.

revoke

Revoke an issued certificate (RFC 8555 §7.6).

akamu-cli revoke --server URL --account-key FILE --cert FILE [OPTIONS]
FlagRequiredDescription
--server URLyesACME directory URL
--account-key FILEyesAccount key PEM file (used unless --cert-key is given)
--cert FILEyesPEM file containing the certificate to revoke
--reason NnoCRL reason code: 0–6 or 8–10 (7 is not valid). Omit for unspecified.
--cert-key FILEnoCertificate’s own private key PEM file. When provided, revocation is signed with the certificate key instead of the account key (self-revocation).

Self-revocation (via --cert-key) is useful when the ACME account key is unavailable.

Sidecar file

When you register an account, akamu-cli writes the account URL to a file named <account-key>.account-url in the same directory as the account key. For example, if your account key is ~/.akamu/account.pem, the sidecar is ~/.akamu/account.pem.account-url.

The issue, renew, deregister, account show, account update, and account key-change subcommands read this file to find the account URL without re-registering.

If the sidecar is missing and you run issue, the CLI registers a new account first. If the sidecar is missing and you run deregister, the command fails with an error.

Keep the key file and sidecar file together and back them up. If you lose the account key, you cannot deactivate or otherwise manage the account.

Example sessions

Register, issue (http-01), and deregister

# 1. Register an account
akamu-cli account register \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --key-type ec:P-256 \
  --contact mailto:admin@example.com \
  --agree-tos

# 2. Issue a certificate
akamu-cli issue \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d example.com \
  -d www.example.com \
  --out /etc/ssl/example.com/fullchain.pem

# 3. Deregister the account
akamu-cli account deregister \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem

Port 80 must be reachable from the ACME server for http-01 validation. The CLI starts a temporary HTTP server during challenge validation and shuts it down afterwards.

Issue with tls-alpn-01

Port 443 must be reachable from the ACME server. Wildcard domains are not supported.

akamu-cli issue \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d example.com \
  --challenge tls-alpn-01 \
  --tls-port 443 \
  --out /etc/ssl/example.com/fullchain.pem

Issue with dns-01 (wildcard)

dns-01 is interactive: the CLI prints the TXT record to add and waits for you to press Enter.

akamu-cli issue \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d "*.example.com" \
  --challenge dns-01 \
  --out /etc/ssl/example.com/wildcard.pem

Output:

DNS-01 challenge for *.example.com:
  Name:  _acme-challenge.example.com.
  Type:  TXT
  Value: <base64url>

Press Enter after the TXT record has propagated (Ctrl-C to abort)...

Issue with onion-csr-01 (RFC 9799)

akamu-cli issue \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d myservice.onion \
  --challenge onion-csr-01 \
  --onion-key ~/.tor/hs_ed25519_secret_key.pem \
  --out /etc/ssl/myservice/fullchain.pem

ARI-aware renewal

# Check ARI window; issue only if inside it
akamu-cli renew \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d example.com \
  --cert /etc/ssl/example.com/fullchain.pem \
  --out /etc/ssl/example.com/fullchain.pem

# Force renewal regardless of ARI window
akamu-cli renew \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  -d example.com \
  --cert /etc/ssl/example.com/fullchain.pem \
  --out /etc/ssl/example.com/fullchain.pem \
  --force

Revoke a certificate

# Via account key
akamu-cli revoke \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --cert /etc/ssl/example.com/fullchain.pem \
  --reason 1

# Self-revocation (account key unavailable)
akamu-cli revoke \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --cert /etc/ssl/example.com/fullchain.pem \
  --cert-key /etc/ssl/example.com/fullchain.pem.key.pem

Roll the account key

akamu-cli account key-change \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --new-key ~/.akamu/account-new.pem \
  --new-key-type ec:P-384

After success, ~/.akamu/account.pem contains the new key and the old key is no longer accepted by the server.

Show and update account contacts

akamu-cli account show \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem

akamu-cli account update \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --contact mailto:new@example.com \
  --contact mailto:backup@example.com

External Account Binding

Some CAs require EAB credentials before accepting a new account. Obtain a KID and HMAC key from your CA’s operator, then pass them to account register or issue:

akamu-cli account register \
  --server https://acme.example.com/acme/directory \
  --account-key ~/.akamu/account.pem \
  --agree-tos \
  --eab-kid my-eab-key-id \
  --eab-key dGhpcyBpcyBhIHRlc3Qga2V5 \
  --eab-alg HS256

The --eab-key value must be the raw HMAC key encoded as base64url without padding. Do not wrap it in additional base64 encoding.

If the server has external_account_required = true and you omit the EAB flags, registration fails with urn:ietf:params:acme:error:externalAccountRequired.

Key type selection

Use caseRecommended typeNotes
Default / broadest compatibilityec:P-256Widely supported, fast, small signatures
Stronger classical securityec:P-384 or rsa:3072Use when policy requires
Post-quantum account keyml-dsa-65Larger signatures; check server support
Post-quantum certificate keyml-dsa-44Smallest PQ key; suitable for most cases
Legacy RSA-only environmentsrsa:2048 or rsa:4096Avoid unless forced by policy

ML-DSA keys require that the Akāmu server is built with the PQC OpenSSL fork. Vanilla Let’s Encrypt does not support ML-DSA.

Logging

Set the RUST_LOG environment variable to control log output:

RUST_LOG=info   akamu-cli issue ...    # normal progress messages
RUST_LOG=debug  akamu-cli issue ...    # HTTP request/response details
RUST_LOG=trace  akamu-cli issue ...    # full JWS content and all internal steps

The default level is warn, which prints only errors and warnings.

Error messages and troubleshooting

ACME error urn:ietf:params:acme:error:badNonce

The server rejected the nonce. The library retries automatically once. If this appears in CLI output, both attempts failed. Retry the command.

ACME error urn:ietf:params:acme:error:incorrectResponse

The server could not validate the challenge. For http-01, verify that port 80 is reachable and that no firewall or reverse proxy is blocking .well-known/acme-challenge/. For tls-alpn-01, verify port 443 is reachable with no TLS terminator in front.

ACME error urn:ietf:params:acme:error:externalAccountRequired

The server requires EAB credentials. Pass --eab-kid and --eab-key.

ACME error urn:ietf:params:acme:error:accountDoesNotExist

No account is registered for the given key. Run account register first.

invalid reason code 7; valid values: 0–6, 8–10

Reason code 7 (removeFromCRL) is not valid for revocation requests. Choose a different code or omit --reason.

Failed to bind port 80: Permission denied

The http-01 solver needs to listen on port 80. Either run with sudo, grant CAP_NET_BIND_SERVICE to the binary, or use an iptables redirect from port 80 to a high port and pass --http-port <high-port>.

Error: No such file: account.pem.account-url

The sidecar file is missing. Run account register first, or restore the sidecar from a backup.

Unsupported algorithm: ML-DSA-65

The server does not support the requested key type. Use a classical key type such as ec:P-256, or connect to an Akāmu server built with the PQC OpenSSL fork.