Skip to content

Using pkiaas from an AI Agent

pkiaas manages PKIaaS certificate authorities and makes keys, certificate signing requests (CSRs) and PKCS#12 files on the user’s computer. It is built to be run by AI agents as well as people. This guide is for agents.

Rules

  • Add --json to every command. Standard output then holds exactly one JSON value: the result, or {"error": {"code", "message", "hint"}}. Messages for people (progress, notices, update hints) go to standard error; don’t parse them. Use the exit code and the error code, not the message text.
  • Look commands up rather than guess. pkiaas help --json describes every command: its flags, examples, result fields, side effects, and whether it calls the server, needs a login or needs the user, with the exit codes and error codes. pkiaas help --json key create (or pkiaas key create --help --json) describes one command.
  • pkiaas never prompts without a terminal. When something is missing, such as a passphrase, it fails with the usage code and names the flag to give. Don’t pipe answers to prompts. Only pkiaas login waits, for the user to approve the login.
  • Files are never overwritten unless --force is given (error file_exists). Only add --force when the user wants the file replaced. If you ran the command before and lost its output, the file it wrote is the result: use it rather than making another key.
  • Private keys stay on this computer. Pass key files by path. Don’t read, print or copy their contents, and don’t send them anywhere.

Secrets

Your commands and their output may be logged, so keep secrets out of both.

  • Passphrases are never command-line arguments. Give them with --passphrase-env NAME (an environment variable the user has set) or --passphrase-file PATH (the first line of a file). Commands that read a key and write another file take --key-passphrase-env and --key-passphrase-file for the key’s passphrase, and ca update takes --cep-password-env and --cep-password-file for a CA’s CEP password.
  • Ask the user to set the variable or write the file themselves. Don’t put a passphrase in a command you run, for example echo secret | pkiaas ... or export KEY_PASSPHRASE=secret.
  • If you have to make a passphrase up, generate it into a file without printing it, and tell the user where it is, so they can move it to a password manager: (umask 077; openssl rand -base64 32 > server.key.pass), or without OpenSSL (umask 077; head -c 32 /dev/urandom | base64 > server.key.pass). In PowerShell: [Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(32)) | Set-Content server.key.pass.
  • Keys are encrypted by default. Only use --no-passphrase when the user asks for an unencrypted key, e.g. for a service that loads its key at startup without a passphrase.
  • Keys, PKCS#12 files and CSRs from cert export --csr (a SCEP CSR holds the challenge password) are secrets: pkiaas help --json names them in a command’s secretOutput. Ask the user before you make one, and say where it will go. Write it with --out FILE (readable by the user only), tell the user where the file is, and never read the file yourself. Suggest that the user add a deny rule for the folder to your settings (e.g. Claude Code’s permissions.deny), so that the file stays out of your reach.
  • pkiaas prints a secret only with --out - or to a terminal, and never puts one in a result: without --out in a pipe or captured output, or with --json, the command fails with secret_destination. It never prints passphrases or tokens. Don’t print PKIAAS_TOKEN, and don’t read the CLI’s hosts.json.

Logging in

Commands that call the server need a login. Run pkiaas whoami --json to check one: exit code 3 with not_logged_in or invalid_token means there is none.

Logging in needs the user, who approves it in their browser.

  • Ask the user to run pkiaas login themselves. In Claude Code, they can type ! pkiaas login.
  • Where no browser can open on this computer (SSH, containers), they run pkiaas login --device. It prints an address and a code to enter in a browser on any device.
  • If the user can’t run commands, you can run pkiaas login --device --json yourself. Start it in the background (it waits up to 10 minutes for the user’s approval), read the address and code from its standard error as soon as they appear, and pass them to the user. Keep it running until it exits; its standard output is then the result. Never enter a code in a browser yourself, and never approve a login you didn’t start for the user.
  • In CI, set PKIAAS_TOKEN from the CI system’s secret store instead of logging in.

The login is kept for 30 days of inactivity, and for at most 90 days. pkiaas logout revokes it.

Certificate authorities

pkiaas ca list --json lists the user’s CAs: their own and those they were invited to. Each has an id and a name, and signed (false while the CA waits for its certificate).

Commands take a CA by its name, in any case (e.g. --ca "Example Issuing CA"), or by its id. Use names with people: say the CA’s name to the user, and accept the name they give. Use IDs in scripts and in commands you keep: an ID never changes, while a CA can be renamed and two CAs can share a name. A name that more than one of the user’s CAs has fails with ca_ambiguous, whose message lists their IDs: ask the user which one they mean.

One CA is active: commands that work in a CA use it unless told otherwise. pkiaas ca show --json says which one it is and why. Login makes it the CA the user last worked in on the website; pkiaas ca set NAME --json (or ID) changes it, and keeps the ID, so renaming the CA doesn’t change it. The active CA is kept on this computer for that server; setting it doesn’t change the CA the user works in on the website. Before working in a CA, check that the active one is the CA the user means; when they have more than one and haven’t said which, ask them rather than choosing.

To work in another CA without changing the active one, give --ca NAME (or ID) to the command, or set PKIAAS_CA to its name or ID in its environment. --ca comes first, then PKIAAS_CA, then the active CA; source in pkiaas ca show --json says which chose it (flag, environment, or set, website, first for the active CA). A name or ID the account doesn’t have fails with not_found.

pkiaas ca show --json also gives the CA’s details: signed, its key (keyType, keySize, hsm), its certificate (serial, thumbprint, validFrom, validTo), activeCertificates, and urls with its public services: certificate, chain, CRL, OCSP, time stamping, the CPS page and Windows enrollment (CEP/CES).

pkiaas ca export --out FILE --json saves the CA’s certificate; with --chain, the CA’s certificate followed by those that issued it. The chain is what pkiaas pkcs12 create --chain-file and servers (e.g. nginx after the server’s certificate) need; a root CA’s certificate is what clients add to their trust store. A CA that isn’t signed yet fails with ca_not_signed. (ca cert, its name in 0.1.0, still works but is deprecated.)

pkiaas ca create --name NAME --json creates a CA owned by the user: the platform makes and keeps its key, self-signs its certificate, and gives it an OCSP certificate and a “Web Server” template, so it can issue certificates at once. The result is the new CA as ca show describes it, with its id. Create a CA only when the user asks for one, or for a test the user wants; it doesn’t become the active CA unless you add --set. --subject, --key-type, --days, --path-length and the key usages set what its certificate holds (see pkiaas help --json ca create). With --csr-only, the CA waits for another CA to sign it: pkiaas ca export --csr --ca ID --out ca.csr --json exports its CSR, and the user imports the signed certificate on the website. A user can create 20 CAs an hour; beyond that it fails with http_429 and says how long to wait. When a step fails on the server, it fails with ca_creation_failed and nothing is kept. --signature-algorithm sha1 makes a CA for testing only (OpenSSL 3 and Windows reject SHA-1 chains) and needs confirmation: pass --yes only when the person asked for SHA-1. As with requests, pass --idempotency-key KEY and keep the key (see “Requesting certificates”).

pkiaas ca update --json changes a CA’s settings, as the website’s Edit CA page does; only the settings whose flags are given change, and it needs the modify privilege in the CA (forbidden without it). settings in pkiaas ca show --json shows them all. To edit the CA’s CPS (the text of its public page), export it, change the file, and send it back:

Terminal window
pkiaas ca export --cps > cps
pkiaas ca update --cps-file cps --json

The CPS you send is Markdown; an HTML CPS written in the website’s old editor is replaced by it, so tell the user that converting it on the website keeps its formatting. --policy-oid sets the certificate policy OID, and --service-key-type (with --service-signature-algorithm for RSA and EC keys) the key of the OCSP and time-stamping certificates, which they get at their next renewal. To turn Windows enrollment (CEP/CES) on, the user puts the password in an environment variable or a file: pkiaas ca update --cep on --cep-username enroll --cep-password-env CEP_PASSWORD --json. Add --dry-run to see what would change (changes, old and new) without sending anything; show it to the user before changes they haven’t spelled out. A CA that already has the settings is left as it is, so the command is safe to run again. If someone changed the CA between reading and saving, it fails with ca_changed and nothing is saved: run it again.

pkiaas ca delete NAME --json deletes a CA, with every certificate it issued, its pending requests, templates, ACME policies and log lines. OCSP, the CRL, SCEP, ACME and CEP stop answering for it, its ACME accounts stop working, and the users it is shared with lose it; an HSM keeps the key of a CA whose key is on it. It can’t be undone, and only the CA’s owner can do it (forbidden otherwise). The CA is always named (its name or id); it is never the active CA by default. Delete a CA only when the user asks you to:

  1. Preview it: pkiaas ca delete NAME --dry-run --json changes nothing; impact says how many certificates (activeCertificates still valid), pending requests, templates, ACME accounts and other users (delegates) the delete takes with it, and hsm.
  2. Show that to the user, naming the CA (name and id), and ask whether to go ahead.
  3. Only if they agree, run pkiaas ca delete ID --yes --json. Without --yes and without a terminal it fails with usage; on a terminal it asks for the CA’s name to be typed instead.

If the CA changed between the preview and the delete, it fails with ca_changed and deletes nothing: preview it again and ask again. A retry of a delete that already went through reports deleted as true. If the deleted CA was the active one, the active CA is cleared on this computer.

Exporting

ca export and cert export work the same way, as openssl x509 does:

  • Without --out, the output goes to standard output, ready to pipe into another command; there is no result then, so --json needs --out FILE. With --out FILE --json, the file is written and the result describes it. A CSR from cert export --csr is a secret (see “Secrets”): write it with --out FILE.
  • --format pem (default) or --format der, as OpenSSL’s -outform. PEM is what servers, OpenSSL and pkcs12 create read; DER is the binary form (.cer, .der) Windows and Java also take. DER holds one certificate, so it can’t be combined with --chain. Redirect or pipe DER: it is binary.
  • --chain adds the certificates that issued it, up to the root. --force replaces an existing --out file.

Prefer --out FILE --json: you get the file and a result to check (content, certificates, format). Use standard output only to pipe the output straight into another command.

Standard input and output

The local commands work the same way: key create, csr create and pkcs12 create write to standard output without --out (then --json needs --out FILE; keys and PKCS#12 files only to a terminal, see below), and key create and csr create take --format pem|der (pkcs12 create always writes DER). Their input files, --key, --cert and --chain-file, may be - for standard input; PEM or DER is recognized from the content. Only one input or passphrase per command can come from standard input, and with data on standard input passphrases can’t be prompted for, so give them with --*passphrase-env or --*passphrase-file FILE.

Keys, PKCS#12 files and CSRs from cert export --csr are secrets: always write them with --out FILE (owner-only), since your transcript is kept. Without --out, they go to standard output only when it is a terminal; in a pipe the command fails with secret_destination. --out - sends them to standard output anyway: use it only to pipe one straight into another command, never to read it. Pipe certificates, and CSRs you made with csr create or a CA’s CSR from ca export --csr, e.g. pkiaas cert export SERIAL --chain | pkiaas pkcs12 create --cert - --key server.key ... --out server.pfx.

In Windows PowerShell 5.1, > and | re-encode output, which breaks keys, certificates and PKCS#12 files: always use --out FILE there, and give file names rather than -. PowerShell 7.4 and later keep the bytes. A file re-encoded this way fails with a message saying so.

Certificates

pkiaas cert list --json lists the certificates the CA issued, newest first: also expired and revoked ones, and the CAs it signed. Each has a serial, which the other cert commands take to name it in its CA, a status (valid, expired or revoked) and revocation (reason and date, or null). It returns the first --limit (default 50, at most 1000); total says how many match, so when it is larger, narrow the list rather than reading everything: --search TEXT keeps certificates whose common name contains the text, and --sort FIELD (name, revocationReason, template, validFrom, validTo, keyType or keySize) with --order asc|desc brings the ones you need first. Like every command that works in a CA, they take --ca NAME (or ID), and their results name the CA in issuer (id and name).

  • pkiaas cert show SERIAL --json gives a certificate’s details; with --text, text holds every field and extension as openssl x509 -text prints them (e.g. its subject alternative names). Serials are hex, with or without colons, in any case. A serial the CA didn’t issue fails with not_found.
  • pkiaas cert export SERIAL --out FILE --json saves the certificate (see “Exporting” above); with --chain, followed by the CA’s certificate and its issuers, which is what a server sends (e.g. nginx’s ssl_certificate).
  • pkiaas cert export SERIAL --csr --out FILE --json saves the CSR it was issued from, when hasCsr is true (otherwise csr_not_stored). A CSR sent by SCEP holds the enrollment’s challenge password: the file is owner-only; don’t print it or put it in your output.

To find the certificate for a name, e.g. before renewing it: pkiaas cert list --search www.example.com --json, and take the newest one whose status is valid.

Revoking

Revoking stops a certificate from being trusted: the CA’s next CRL and OCSP responses list it. Clients that check revocation stop accepting it, so ask the user before revoking, naming the certificate (name and serial) and the reason, and only then run the command with --yes. Without --yes and without a terminal, it fails with usage.

  • pkiaas cert revoke SERIAL --reason REASON --yes --json. The reasons are RFC 5280’s: unspecified, keyCompromise (its private key leaked or may have), cACompromise, affiliationChanged, superseded (replaced by a new certificate), cessationOfOperation (no longer used) and certificateHold (suspended for now).
  • Only certificateHold can be undone: pkiaas cert unrevoke SERIAL --json takes the certificate off hold. A certificate on hold can also be revoked for good with another reason. Every other reason is final; changing or undoing it fails with revocation_final.
  • Both are safe to run again: revoking with the same reason, or unrevoking a certificate that isn’t revoked, changes nothing and succeeds.
  • Both need a subscription, the user’s or the CA owner’s; without one they fail with subscription_required. Tell the user rather than retrying.

Requests that are safe to repeat (reading, revoking, unrevoking, changing a CA’s settings, deleting a CA, and requesting a certificate or creating a CA with its Idempotency-Key) are tried up to 3 times in all when the connection fails or the server answers with a 5xx or 429; a notice goes to standard error. Only run a command again yourself after it has failed. When the server asks to wait longer than 10 seconds, the command fails at once and its message says how long to wait before running it again.

Requesting certificates

pkiaas request create --csr FILE --template NAME --json sends a CSR (PEM or DER, - for standard input) to the CA. The request waits for a member of the CA to approve it, which issues the certificate. No email is sent. Add --approve to approve it in the same command when the user wants the certificate issued now: the result is then issued, with the certificate’s serial, and --out FILE (or --out -) writes the certificate too. Otherwise tell the user the request’s id and that it waits for approval.

  • --template is the name of a template from pkiaas template list --json whose enabled is true, in any case (e.g. --template "Web Server"), or its id. A template says what the certificate holds (validity, key usages and so on); if more than one fits, ask the user which to use. A wrong or disabled one fails with template_not_found; a name that two enabled templates share fails with template_ambiguous: use the id.
  • The server checks the CSR’s signature; an unreadable or altered CSR fails with invalid_csr. Only the CSR is sent, never anything else in the file.

Keep the idempotency key. Each run is a new request. To make a create safe to repeat, make a key for it (e.g. a UUID), pass it with --idempotency-key KEY, and keep it with your notes. If you can’t tell whether the command worked (it timed out, or a later session picks up the work), run it again with the same CSR, template, CA and key: within 24 hours that returns the first result rather than a second request. Without the flag, the CLI makes a key and reports it as idempotencyKey. A key used for a different request fails with idempotency_key_reused, and one whose first request hasn’t finished with idempotency_key_in_use (wait, then retry with the same key). After 24 hours the key is forgotten and the command makes a new request. With --approve, the same command and key approves the same request, which is safe: an issued request stays as it is. If the approval fails, the request stays (waiting for approval) and the error says its id.

Pending requests

pkiaas request list --json lists the CA’s requests that wait for something, as the website’s Pending Requests page does; pkiaas request show ID --json shows one with what its CSR asks for (subject, subjectAltNames, keyType). status says what each waits for:

  • pendingApproval: a member of the CA approves or declines it. With hasCsr true, pkiaas request approve ID issues it; one without a CSR needs an approved voucher, which only the website sends.
  • pendingEmailVerification: the requester has yet to confirm their email address.
  • preApproved: it is issued when the requester picks it up with its voucher or SCEP challenge.
  • processing: it is being signed, which takes seconds. One processing for more than 10 minutes (processingSince) is stuck: it can be declined, and the requester makes a new request.

Approving and declining are the user’s decisions: approve or decline only the requests the user asked you to, and check each with pkiaas request show first. Approving issues a certificate for whatever the request’s template allows; declining is final.

  • pkiaas request approve ID --json ends once the certificate is issued and gives its serial; with --out FILE (and --chain) it writes the certificate too. It is safe to run again: an issued request stays as it is. It fails with request_not_approvable (no CSR, email not confirmed, pre-approved, or changes to a request that isn’t readyToBeSigned), request_declined, request_processing (wait a few seconds and check it with request show), or signing_failed when the CA couldn’t sign (e.g. its IoT HSM didn’t answer): tell the user, whose CA log on the website says why. Approvals are never retried by themselves.
  • Changing what is issued. By default the certificate holds what the CSR asks for, as the template allows. When the user asks for something else, request approve (and request create --approve) take --subject DN (in place of the CSR’s subject; the template’s subject attributes still win), --san NAME (repeatable; all of the certificate’s SANs, in place of the CSR’s) and --not-after TIME with an optional --not-before TIME (RFC 3339, e.g. 2027-01-31T00:00:00Z; from now without --not-before), as the website’s override boxes do. Only a request whose statusDetail is readyToBeSigned can be changed (otherwise request_not_approvable). Without a subscription, while validityLimitDays is set in request show, the validity can’t be changed (subscription_required); values OpenSSL won’t take fail with invalid_overrides, and nothing is signed. An issued request is never signed again: running the command again with other changes succeeds but applies none.
  • pkiaas request decline ID --yes --json declines it for good. Declining a declined request succeeds; an issued one fails with request_issued (revoke its certificate instead, if the user wants that).

Troubleshooting with the logs

When something failed on the platform rather than in the CLI, e.g. a device’s SCEP enrollment, a CEP/CES or ACME request, or signing_failed, the CA’s log says why. pkiaas log list --json lists the latest log lines of all the user’s CAs in time order, the newest last (.logs[-1]): each has its ca (id and name), level, time (UTC), the client’s ip and the message. It doesn’t use the active CA or PKIAAS_CA; --ca NAME (or ID, repeatable) keeps the lines of those CAs. --level warning keeps warnings and the more severe lines (error, critical, alert, emergency). --since and --until keep the lines from a time and before a time: RFC 3339, a date (midnight in the computer’s time zone, so prefer RFC 3339 with an offset) or how long ago (90m, 24h, 7d); the result’s since and until say which times they stood for. --search TEXT keeps the lines with that text in the message or the client’s IP address, in any case. To find why a request failed, e.g.:

Terminal window
pkiaas log list --ca "Example Issuing CA" --level warning --since 24h --json
pkiaas log list --search 203.0.113.7 --since 2026-10-24T08:00:00Z --until 2026-10-24T09:00:00Z --json

and look for the lines near the time it failed, from the client’s IP address. Lines are kept for a while (by default 30 days).

Recipes

Choose a key type with pkiaas key types --json. The default, rsa-2048, works everywhere. Use ec-p256 for smaller, faster keys. Use ml-dsa-* or slh-dsa-* (post-quantum) only when the user asks for them, because few clients accept them yet.

Create a key and a CSR for a TLS server (the user has set KEY_PASSPHRASE):

Terminal window
pkiaas key create --type ec-p256 --out server.key --passphrase-env KEY_PASSPHRASE --json
pkiaas csr create --key server.key --key-passphrase-env KEY_PASSPHRASE --cn www.example.com \
--san www.example.com --san example.com --out server.csr --json

List the common name among the SANs too: with --san, it isn’t added for you, and most clients only check SANs.

Then request the certificate from the user’s CA, with a key you keep (see “Requesting certificates”):

Terminal window
pkiaas template list --json
pkiaas request create --csr server.csr --template "Web Server" --idempotency-key KEY --json

If the user wants it issued now, add --approve and --out: the command issues the certificate and writes it, so no serial has to be copied between commands:

Terminal window
pkiaas request create --csr server.csr --template "Web Server" --approve --chain --out server.pem \
--idempotency-key KEY --json

--chain adds the CA’s certificates (what a server sends); --out - writes the certificate to standard output instead, for piping, with no result. Without --approve, the user approves it (pkiaas request approve ID --out server.pem, or the website’s Pending Requests page); pkiaas request show ID --json gives the certificate’s serial for pkiaas cert export later.

Combine the key, the signed certificate and the CA chain into a PKCS#12 file for Windows, Java or a load balancer (the user has set PFX_PASSPHRASE too):

Terminal window
pkiaas ca export --chain --out ca.pem --json
pkiaas pkcs12 create --key server.key --key-passphrase-env KEY_PASSPHRASE --cert server.pem --chain-file ca.pem \
--out server.pfx --passphrase-env PFX_PASSPHRASE --json

Or, with the certificate’s serial, without saving the certificate and chain first:

Terminal window
pkiaas cert export SERIAL --chain | pkiaas pkcs12 create --key server.key --key-passphrase-env KEY_PASSPHRASE \
--cert - --out server.pfx --passphrase-env PFX_PASSPHRASE --json

Add --legacy only for systems older than Windows 10 1709, Java 12 or OpenSSL 1.1.1.

Create a disposable test CA, e.g. to try out commands without touching the user’s CAs (with the user’s agreement: it counts toward their 20 CAs an hour). Make a key for the run (e.g. a UUID) and keep it with your notes, so that running the command again returns the same CA instead of a second one:

Terminal window
pkiaas ca create --name "Test CA $RUN" --key-type ec-p256 --days 7 --idempotency-key "$KEY" --json

Keep the result’s id and give it to every command with --ca ID (e.g. pkiaas template list --ca ID --json, pkiaas request create --ca ID ...), rather than making the test CA the active one. When the tests are done, delete it by its id; the user agreed to the whole run, so --yes is fine here, for the CA you created only:

Terminal window
pkiaas ca delete "$ID" --dry-run --json
pkiaas ca delete "$ID" --yes --json

Versions

pkiaas version --json shows the installed version. When the server has a newer one, pkiaas prints an update command on standard error. If a command fails with cli_outdated, run the install command in the message, then run the command again.

Exit codes

ExitNameMeaning
0okthe command succeeded
1errorthe command failed; the error code says why
2usagethe command line is wrong: an unknown command or flag, or missing or conflicting options
3authnot logged in, the login expired, or not allowed
4not_foundthe CA, certificate or other object doesn’t exist
5conflictthe operation would overwrite or clash with something that exists, e.g. an output file

Error codes

With --json, an error is {"error": {"code", "message", "hint"}}. The hint is what to do; when an error has none of its own, it is the one below.

CodeExitMeaningWhat to do
error1an error without a more specific code; the message says what failedread the message: fix the cause if it is clear (e.g. a wrong file path), otherwise tell the user
usage2the command line is wrong, or a needed option (such as a passphrase without a terminal to prompt on) is missingfix the command line; run the command with --help (or pkiaas help --json <command>) for its flags
file_exists5an output file exists, and files are never replaced without --forceif an earlier run of yours wrote the file, it is the result: use it; otherwise choose another output file, or add --force if the user wants the file replaced
secret_destination2the output is a secret (a key, a PKCS#12 file or a stored CSR), so it isn’t sent into a pipe, captured output or a --json result without --outsave it with --out FILE, tell the user where the file is, and don’t read it yourself; use --out - only to pipe it straight into another command, since your output may be logged
wrong_passphrase1the key’s passphrase is wrong, or the key file is damagedask the user for the right passphrase, given the same way (environment variable or file)
not_logged_in3there is no login for the server, and PKIAAS_TOKEN isn’t setask the user to run pkiaas login (or pkiaas login --device where no browser can open); see pkiaas help agents
invalid_token3the server refused the token: the login expired, was revoked, or the account was removedask the user to run pkiaas login (or pkiaas login --device where no browser can open); see pkiaas help agents
forbidden3the account isn’t allowed to do thisask the user to check their access, or the CA owner to delegate it
not_found4the server has no such object, or the account can’t see itcheck the name or ID
conflict5the server refused a change that clashes with something that existsread the message; check what exists before changing it, and ask the user before replacing anything
ca_not_signed5the CA has no certificate yet: it waits for its signed certificate to be importedask the user to import the CA’s signed certificate on the website (the CA’s page), or use another CA from pkiaas ca list --json (signed is true)
csr_not_stored4no CSR is stored for the certificate (e.g. one issued by ACME)the certificate itself is still available with pkiaas cert export SERIAL; check hasCsr in pkiaas cert show --json before asking for a CSR
subscription_required3the feature needs a subscription, the user’s or the CA owner’s (revoking and unrevoking certificates; changing the validity when approving a request)tell the user; they can subscribe, or link a subscription they already have, on the website’s profile page
revocation_final5the certificate is revoked with a reason other than certificateHold, which can’t be undone or changednothing to do: the certificate stays revoked; pkiaas cert show SERIAL --json shows its reason
invalid_csr1the server can’t read the CSR, or its signature doesn’t match its keycheck that the file is the CSR (PEM or DER) and wasn’t changed after it was signed; make a new one with pkiaas csr create
template_not_found4the CA has no template with this name or ID; to request a certificate, no enabled onerun pkiaas template list --json (with the same --ca) and use the name or id of a template whose enabled is true
template_ambiguous2more than one template of the CA has this name; to request a certificate, more than one enabled onegive --template the id of the one to use; if it isn’t clear which, pkiaas template list --json shows them, and ask the user
ca_ambiguous2more than one of the account’s CAs has this name (--ca, PKIAAS_CA or pkiaas ca set)give the id of the one to use instead; if it isn’t clear which, pkiaas ca list --json shows them, and ask the user
idempotency_key_reused5the --idempotency-key was used for a different request in the last 24 hoursmake a new key for a new request; reuse a key only to repeat exactly the same command
idempotency_key_in_use5the first request with this --idempotency-key hasn’t finished yetwait a minute and run the same command with the same key again; if it lasts, check on the website whether the request exists before making a new one
request_not_approvable5the request can’t be approved: it has no CSR, waits for the requester to confirm their email address, or is pre-approved; or it can’t be approved with changes (--subject, --san, --not-before, --not-after), since it isn’t readyToBeSignedread the message; pkiaas request show ID --json shows its status and hasCsr. A request without a CSR needs an approved voucher, which the user sends on the website’s Pending Requests page
invalid_overrides1OpenSSL won’t take the --subject or --san an approval gives, e.g. a common name longer than 64 characters; nothing was signedfix the value the message names and approve again; the request still waits for approval
request_declined5the request was declined, which is finalnothing to approve: make a new request with pkiaas request create if the certificate is still needed
request_issued5the request is issued, so it can’t be declinedpkiaas request show ID --json gives the certificate’s serial; revoke it with pkiaas cert revoke SERIAL if it mustn’t be used
request_processing5the request is being signed right nowwait a few seconds, then check it with pkiaas request show ID --json; one processing for more than 10 minutes (processingSince) is stuck: decline it and make a new request
signing_failed1the CA couldn’t sign the request, e.g. its IoT HSM didn’t answer or the template doesn’t fit the CSR; the CA’s log says whytell the user, who can read the CA’s log on the website; the request waits for approval again (or stays processing if the certificate was signed), so approve it again once the cause is fixed
ca_creation_failed1creating the CA failed on the server at the step the message names; nothing was kept, unless the message says the half-made CA couldn’t be removedrun the same command again once (with the same --idempotency-key); if it fails again, tell the user and quote the request ID from the message. Each try counts toward the limit of 20 CAs an hour
ca_changed5someone changed the CA since the command read it (pkiaas ca update) or previewed its delete (pkiaas ca delete), so nothing was saved or deletedsomeone changed the CA since it was read; run the command again (it reads the CA again and applies only its own flags); pkiaas ca show --json shows the CA’s settings now
cli_outdated1the server needs a newer pkiaasupdate pkiaas with the install command in the message, then run the command again
connection_failed1the server couldn’t be reachedcheck the server address (--server or PKIAAS_SERVER) and the network, then try again
http_<status>1the server answered with an unexpected HTTP status, e.g. http_500; the message has the request ID to quotetry again later; if it persists, report the request ID
no_browser1pkiaas login couldn’t open a browser, and there is no terminal to wait onask the user to run pkiaas login --device, or run it and pass its address and code to the user
timeout1nobody finished the login in the browser in timeask the user to run pkiaas login again and approve it in the browser
access_denied3the user denied the loginask the user whether to log in again
expired_token3the device login code expired before the user approved itask the user to run pkiaas login --device again, and to enter the code promptly
invalid_state3the browser came back from a different loginask the user to run pkiaas login again
invalid_issuer3the login came back from a different serverask the user to run pkiaas login again, with the intended --server
invalid_request3the server or the browser rejected the login requestask the user to run pkiaas login again; if it persists, update pkiaas
invalid_grant3the login code was used, expired or doesn’t matchask the user to run pkiaas login again
invalid_client3the server doesn’t know this CLI as a clientcheck the server address; update pkiaas
unsupported_grant_type3the server doesn’t support this login flowupdate pkiaas, or log in with the other flow (--device or without it)
temporarily_unavailable3the server has too many pending loginswait a minute, then ask the user to run pkiaas login --device again
slow_down3the server is limiting login requests from this addresswait a minute, then ask the user to run pkiaas login again