From e08693eab213f109344fdb77b6abc209e5dad46e Mon Sep 17 00:00:00 2001 From: Michael Harp Date: Tue, 15 Sep 2026 07:41:30 -0400 Subject: [PATCH 1/2] Document how the CA CLI is authorized and fix stale CA endpoint statements Explain that puppetserver ca setup and ca import stamp the server's own certificate with the pp_cli_auth extension, that the default auth.conf authorizes the CA administrative endpoints on that extension rather than by certname, and that --ca-client is the way to issue it to another host. Add pp_owner, pp_auth_auto_renew, and pp_cli_auth to the registered OIDs table and give the ppAuthCertExt rows a proper table header. Correct the certificate status page, which still said the endpoint was disabled by default, and the bulk sign page, which pointed at ca.conf instead of auth.conf. Replace the Puppet 5 upgrade note on the subcommands page with a CA CLI authorization section and show the shipped cert status rule as the extensions example on the auth.conf page. Closes #484 Co-Authored-By: Claude Fable 5.1 Signed-off-by: Michael Harp --- .../ca-api/v1/http_certificate_sign.md | 4 +-- .../ca-api/v1/http_certificate_status.md | 10 ++++-- .../config_file_auth.markdown | 22 ++++++++++++ docs/_openvox-server_8x/subcommands.markdown | 35 ++++++++++--------- .../ca-api/v1/http_certificate_sign.md | 4 +-- .../ca-api/v1/http_certificate_status.md | 10 ++++-- .../config_file_auth.markdown | 22 ++++++++++++ docs/_openvox-server_9x/subcommands.markdown | 35 ++++++++++--------- docs/_openvox_8x/_registered_oids.md | 11 ++++-- docs/_openvox_9x/_registered_oids.md | 11 ++++-- 10 files changed, 118 insertions(+), 46 deletions(-) diff --git a/docs/_openvox-server_8x/ca-api/v1/http_certificate_sign.md b/docs/_openvox-server_8x/ca-api/v1/http_certificate_sign.md index 27a5fa887..52ea464e6 100644 --- a/docs/_openvox-server_8x/ca-api/v1/http_certificate_sign.md +++ b/docs/_openvox-server_8x/ca-api/v1/http_certificate_sign.md @@ -36,7 +36,7 @@ None (certnames are provided in the request body) ### Access Requires a client certificate with the `pp_cli_auth: "true"` certificate extension. Access is controlled by -OpenVox Server's `ca.conf` authorization configuration. +OpenVox Server's [`auth.conf`](../../config_file_auth.html). ### Example @@ -112,7 +112,7 @@ None ### Access Requires a client certificate with the `pp_cli_auth: "true"` certificate extension. Access is controlled by -OpenVox Server's `ca.conf` authorization configuration. +OpenVox Server's [`auth.conf`](../../config_file_auth.html). ### Example diff --git a/docs/_openvox-server_8x/ca-api/v1/http_certificate_status.md b/docs/_openvox-server_8x/ca-api/v1/http_certificate_status.md index 1954d5fb5..765d7060d 100644 --- a/docs/_openvox-server_8x/ca-api/v1/http_certificate_status.md +++ b/docs/_openvox-server_8x/ca-api/v1/http_certificate_status.md @@ -71,9 +71,13 @@ Otherwise it returns ### Supported HTTP Methods -This endpoint is disabled in the default configuration. It is -recommended to be careful with this endpoint, as it can allow control -over the certificates used by the puppet master. +In the default `auth.conf`, these endpoints accept only requests made with a client +certificate that carries the `pp_cli_auth: "true"` extension. The server's own +certificate has that extension when the server, `puppetserver ca setup`, or +`puppetserver ca import` generated it, which is how the `puppetserver ca` commands reach these endpoints. See +[CA CLI authorization](../../subcommands.html#ca-cli-authorization). Be careful when +widening that rule, as these endpoints allow control over every certificate the CA +manages. GET, PUT, DELETE diff --git a/docs/_openvox-server_8x/config_file_auth.markdown b/docs/_openvox-server_8x/config_file_auth.markdown index 8c4ccf213..a836356a1 100644 --- a/docs/_openvox-server_8x/config_file_auth.markdown +++ b/docs/_openvox-server_8x/config_file_auth.markdown @@ -172,6 +172,28 @@ request. > Also, in the HOCON OpenVox Server authentication method, there is no directly equivalent behavior to the [deprecated][] `auth` parameter's `on` value. +The default `auth.conf` uses an `extensions` match to authorize the `puppetserver ca` command line tool. Each CA administrative endpoint has a rule like this one, which allows any certificate carrying the `pp_cli_auth` extension instead of naming the server's certname: + +```hocon +{ + # Allow the CA CLI to access the certificate_status endpoint + match-request: { + path: "/puppet-ca/v1/certificate_status" + type: path + method: [get, put, delete] + } + allow: { + extensions: { + pp_cli_auth: "true" + } + } + sort-order: 500 + name: "puppetlabs cert status" +} +``` + +See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how the server's own certificate gets that extension and how to issue it to another host. + #### `sort-order` After each rule's `match-request` section, the required `sort-order` parameter sets the order in which OpenVox Server evaluates the rule by prioritizing it on a numeric value between 1 and 399 (to be evaluated diff --git a/docs/_openvox-server_8x/subcommands.markdown b/docs/_openvox-server_8x/subcommands.markdown index c3b6e4f26..06152c4ab 100644 --- a/docs/_openvox-server_8x/subcommands.markdown +++ b/docs/_openvox-server_8x/subcommands.markdown @@ -49,26 +49,29 @@ Because these commands utilize Puppet Server’s API, all except `setup` and `im Because these commands are shipped as a gem alongside Puppet Server, it can be updated out-of-band to pick up improvements and bug fixes. To upgrade it, run this command: `/opt/puppetlabs/puppet/bin/gem install -i /opt/puppetlabs/puppet/lib/ruby/vendor_gems puppetserver-ca` -**Note:** These commands are available in Puppet 5, but in order to use them, you must update Puppet Server’s `auth.conf` to include a rule allowing the master’s certname to access the `certificate_status` and -`certificate_statuses` endpoints. The same applies to upgrading in open source Puppet: if you're upgrading from Puppet 5 to Puppet 6 and are not regenerating your CA, you must whitelist the master’s certname. -See [Puppet Server Configuration Files: auth.conf](/openvox-server/latest/config_file_auth.html) for details on how to use `auth.conf`. +### CA CLI authorization -Example: +Every `ca` action except `setup` and `import` talks to the CA over its HTTP API, so the certificate the command presents must be allowed by [`auth.conf`](./config_file_auth.html). + +The default `auth.conf` does not name the server's certname. Instead, each CA administrative rule (`certificate_status`, `certificate_statuses`, `sign`, `sign/all`, `clean`, and `PUT` on `certificate_revocation_list`) allows any client certificate that carries the `pp_cli_auth` extension (OID `1.3.6.1.4.1.34380.1.3.39`) with the value `true`. -```text -{ - # Allow the CA CLI to access the certificate_status endpoint - match-request: { - path: "/puppet-ca/v1/certificate_status" - type: path - method: [get, put, delete] - } - allow: master.example.com - sort-order: 500 - name: "puppetlabs cert status" -}, +`puppetserver ca setup` and `puppetserver ca import` add that extension to the server's own host certificate when they generate it, and OpenVox Server does the same when it creates that certificate itself on first start. That is why the CLI works on a fresh server with no configuration. To confirm a certificate has it, run: + +```sh +openssl x509 -text -noout -in "$(puppet config print hostcert)" ``` +In the `X509v3 extensions` section, look for `1.3.6.1.4.1.34380.1.3.39` with the value `true`, next to the `Puppet Server Internal Certificate` comment. OpenSSL prints the numeric OID because it does not know the short name. + +Two consequences follow from this: + +- If the server's host certificate is replaced by any other route, for example by cleaning it and letting the agent request an ordinary certificate, the new certificate lacks the extension and every `ca` action except `setup` and `import` is refused with `403 Forbidden`. + `puppetserver ca generate` refuses to overwrite an existing certificate or key, so follow [Regenerate the primary server's certificate](./certificate_renewal.html#regenerate-the-primary-servers-certificate), which removes the old files first and shows how to carry the subject alternative names over. +- To run `puppetserver ca` from another host, generate that host's certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. + A certificate with `pp_cli_auth` can list, sign, revoke, and clean any certificate the CA manages, so treat it as an administrative credential and never issue it to ordinary agents. + +`--ca-client` signs the certificate offline, without the running CA service, so use it only while OpenVox Server is stopped. This offline path is the only way to put the extension in a certificate. The CA refuses any CSR that requests `pp_cli_auth`, even when `allow-authorization-extensions` is enabled, so it cannot be obtained through `csr_attributes.yaml` and a normal signing. + ### Signing certs with SANs or auth extensions With the removal of `puppet cert sign`, it's possible for Puppet Server’s CA API to sign certificates with subject alternative names or auth extensions, which was previously completely disallowed. This is diff --git a/docs/_openvox-server_9x/ca-api/v1/http_certificate_sign.md b/docs/_openvox-server_9x/ca-api/v1/http_certificate_sign.md index 27a5fa887..52ea464e6 100644 --- a/docs/_openvox-server_9x/ca-api/v1/http_certificate_sign.md +++ b/docs/_openvox-server_9x/ca-api/v1/http_certificate_sign.md @@ -36,7 +36,7 @@ None (certnames are provided in the request body) ### Access Requires a client certificate with the `pp_cli_auth: "true"` certificate extension. Access is controlled by -OpenVox Server's `ca.conf` authorization configuration. +OpenVox Server's [`auth.conf`](../../config_file_auth.html). ### Example @@ -112,7 +112,7 @@ None ### Access Requires a client certificate with the `pp_cli_auth: "true"` certificate extension. Access is controlled by -OpenVox Server's `ca.conf` authorization configuration. +OpenVox Server's [`auth.conf`](../../config_file_auth.html). ### Example diff --git a/docs/_openvox-server_9x/ca-api/v1/http_certificate_status.md b/docs/_openvox-server_9x/ca-api/v1/http_certificate_status.md index 1954d5fb5..765d7060d 100644 --- a/docs/_openvox-server_9x/ca-api/v1/http_certificate_status.md +++ b/docs/_openvox-server_9x/ca-api/v1/http_certificate_status.md @@ -71,9 +71,13 @@ Otherwise it returns ### Supported HTTP Methods -This endpoint is disabled in the default configuration. It is -recommended to be careful with this endpoint, as it can allow control -over the certificates used by the puppet master. +In the default `auth.conf`, these endpoints accept only requests made with a client +certificate that carries the `pp_cli_auth: "true"` extension. The server's own +certificate has that extension when the server, `puppetserver ca setup`, or +`puppetserver ca import` generated it, which is how the `puppetserver ca` commands reach these endpoints. See +[CA CLI authorization](../../subcommands.html#ca-cli-authorization). Be careful when +widening that rule, as these endpoints allow control over every certificate the CA +manages. GET, PUT, DELETE diff --git a/docs/_openvox-server_9x/config_file_auth.markdown b/docs/_openvox-server_9x/config_file_auth.markdown index cdf0d8c09..d36d2dbf9 100644 --- a/docs/_openvox-server_9x/config_file_auth.markdown +++ b/docs/_openvox-server_9x/config_file_auth.markdown @@ -180,6 +180,28 @@ request. > Also, in the HOCON OpenVox Server authentication method, there is no directly equivalent behavior to the [deprecated][] `auth` parameter's `on` value. +The default `auth.conf` uses an `extensions` match to authorize the `puppetserver ca` command line tool. Each CA administrative endpoint has a rule like this one, which allows any certificate carrying the `pp_cli_auth` extension instead of naming the server's certname: + +```hocon +{ + # Allow the CA CLI to access the certificate_status endpoint + match-request: { + path: "/puppet-ca/v1/certificate_status" + type: path + method: [get, put, delete] + } + allow: { + extensions: { + pp_cli_auth: "true" + } + } + sort-order: 500 + name: "puppetlabs cert status" +} +``` + +See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how the server's own certificate gets that extension and how to issue it to another host. + #### `sort-order` After each rule's `match-request` section, the required `sort-order` parameter sets the order in which OpenVox Server evaluates the rule by prioritizing it on a numeric value between 1 and 399 (to be evaluated diff --git a/docs/_openvox-server_9x/subcommands.markdown b/docs/_openvox-server_9x/subcommands.markdown index 83637f9a1..06152c4ab 100644 --- a/docs/_openvox-server_9x/subcommands.markdown +++ b/docs/_openvox-server_9x/subcommands.markdown @@ -49,26 +49,29 @@ Because these commands utilize Puppet Server’s API, all except `setup` and `im Because these commands are shipped as a gem alongside Puppet Server, it can be updated out-of-band to pick up improvements and bug fixes. To upgrade it, run this command: `/opt/puppetlabs/puppet/bin/gem install -i /opt/puppetlabs/puppet/lib/ruby/vendor_gems puppetserver-ca` -**Note:** These commands are available in Puppet 5, but in order to use them, you must update Puppet Server’s `auth.conf` to include a rule allowing the master’s certname to access the `certificate_status` and -`certificate_statuses` endpoints. The same applies to upgrading in open source Puppet: if you're upgrading from Puppet 5 to Puppet 6 and are not regenerating your CA, you must whitelist the master’s certname. -See [Puppet Server Configuration Files: auth.conf](./config_file_auth.html) for details on how to use `auth.conf`. +### CA CLI authorization -Example: +Every `ca` action except `setup` and `import` talks to the CA over its HTTP API, so the certificate the command presents must be allowed by [`auth.conf`](./config_file_auth.html). + +The default `auth.conf` does not name the server's certname. Instead, each CA administrative rule (`certificate_status`, `certificate_statuses`, `sign`, `sign/all`, `clean`, and `PUT` on `certificate_revocation_list`) allows any client certificate that carries the `pp_cli_auth` extension (OID `1.3.6.1.4.1.34380.1.3.39`) with the value `true`. -```text -{ - # Allow the CA CLI to access the certificate_status endpoint - match-request: { - path: "/puppet-ca/v1/certificate_status" - type: path - method: [get, put, delete] - } - allow: master.example.com - sort-order: 500 - name: "puppetlabs cert status" -}, +`puppetserver ca setup` and `puppetserver ca import` add that extension to the server's own host certificate when they generate it, and OpenVox Server does the same when it creates that certificate itself on first start. That is why the CLI works on a fresh server with no configuration. To confirm a certificate has it, run: + +```sh +openssl x509 -text -noout -in "$(puppet config print hostcert)" ``` +In the `X509v3 extensions` section, look for `1.3.6.1.4.1.34380.1.3.39` with the value `true`, next to the `Puppet Server Internal Certificate` comment. OpenSSL prints the numeric OID because it does not know the short name. + +Two consequences follow from this: + +- If the server's host certificate is replaced by any other route, for example by cleaning it and letting the agent request an ordinary certificate, the new certificate lacks the extension and every `ca` action except `setup` and `import` is refused with `403 Forbidden`. + `puppetserver ca generate` refuses to overwrite an existing certificate or key, so follow [Regenerate the primary server's certificate](./certificate_renewal.html#regenerate-the-primary-servers-certificate), which removes the old files first and shows how to carry the subject alternative names over. +- To run `puppetserver ca` from another host, generate that host's certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. + A certificate with `pp_cli_auth` can list, sign, revoke, and clean any certificate the CA manages, so treat it as an administrative credential and never issue it to ordinary agents. + +`--ca-client` signs the certificate offline, without the running CA service, so use it only while OpenVox Server is stopped. This offline path is the only way to put the extension in a certificate. The CA refuses any CSR that requests `pp_cli_auth`, even when `allow-authorization-extensions` is enabled, so it cannot be obtained through `csr_attributes.yaml` and a normal signing. + ### Signing certs with SANs or auth extensions With the removal of `puppet cert sign`, it's possible for Puppet Server’s CA API to sign certificates with subject alternative names or auth extensions, which was previously completely disallowed. This is diff --git a/docs/_openvox_8x/_registered_oids.md b/docs/_openvox_8x/_registered_oids.md index cfce593d7..8d2025ff3 100644 --- a/docs/_openvox_8x/_registered_oids.md +++ b/docs/_openvox_8x/_registered_oids.md @@ -28,8 +28,15 @@ Numeric ID | Short Name | Descriptive Name 1.3.6.1.4.1.34380.1.1.23 | `pp_cloudplatform` | Puppet Node Cloud Platform Name 1.3.6.1.4.1.34380.1.1.24 | `pp_apptier` | Puppet Node Application Tier 1.3.6.1.4.1.34380.1.1.25 | `pp_hostname` | Puppet Node Hostname +1.3.6.1.4.1.34380.1.1.26 | `pp_owner` | Puppet Node Owner The "ppAuthCertExt" OID range contains the following OIDs: -1.3.6.1.4.1.34380.1.3.1 | `pp_authorization` | Certificate Extension Authorization -1.3.6.1.4.1.34380.1.3.13 | `pp_auth_role` | Puppet Node Role Name for Authorization +Numeric ID | Short Name | Descriptive Name +-------------------------|-----------------------|----------------------------------------- +1.3.6.1.4.1.34380.1.3.1 | `pp_authorization` | Certificate Extension Authorization +1.3.6.1.4.1.34380.1.3.2 | `pp_auth_auto_renew` | Auto-Renew Certificate Attribute +1.3.6.1.4.1.34380.1.3.13 | `pp_auth_role` | Puppet Node Role Name for Authorization +1.3.6.1.4.1.34380.1.3.39 | `pp_cli_auth` | Puppetserver CA CLI Authorization + +OpenVox Server's own certificate carries `pp_cli_auth` with the value `true`. OpenVox Server, `puppetserver ca setup`, and `puppetserver ca import` all add it when they generate that certificate, and the default `auth.conf` uses it to authorize the `puppetserver ca` command line tool. See [CA CLI authorization](/openvox-server/8.x/subcommands.html#ca-cli-authorization). diff --git a/docs/_openvox_9x/_registered_oids.md b/docs/_openvox_9x/_registered_oids.md index cfce593d7..435b70e94 100644 --- a/docs/_openvox_9x/_registered_oids.md +++ b/docs/_openvox_9x/_registered_oids.md @@ -28,8 +28,15 @@ Numeric ID | Short Name | Descriptive Name 1.3.6.1.4.1.34380.1.1.23 | `pp_cloudplatform` | Puppet Node Cloud Platform Name 1.3.6.1.4.1.34380.1.1.24 | `pp_apptier` | Puppet Node Application Tier 1.3.6.1.4.1.34380.1.1.25 | `pp_hostname` | Puppet Node Hostname +1.3.6.1.4.1.34380.1.1.26 | `pp_owner` | Puppet Node Owner The "ppAuthCertExt" OID range contains the following OIDs: -1.3.6.1.4.1.34380.1.3.1 | `pp_authorization` | Certificate Extension Authorization -1.3.6.1.4.1.34380.1.3.13 | `pp_auth_role` | Puppet Node Role Name for Authorization +Numeric ID | Short Name | Descriptive Name +-------------------------|-----------------------|----------------------------------------- +1.3.6.1.4.1.34380.1.3.1 | `pp_authorization` | Certificate Extension Authorization +1.3.6.1.4.1.34380.1.3.2 | `pp_auth_auto_renew` | Auto-Renew Certificate Attribute +1.3.6.1.4.1.34380.1.3.13 | `pp_auth_role` | Puppet Node Role Name for Authorization +1.3.6.1.4.1.34380.1.3.39 | `pp_cli_auth` | Puppetserver CA CLI Authorization + +OpenVox Server's own certificate carries `pp_cli_auth` with the value `true`. OpenVox Server, `puppetserver ca setup`, and `puppetserver ca import` all add it when they generate that certificate, and the default `auth.conf` uses it to authorize the `puppetserver ca` command line tool. See [CA CLI authorization](/openvox-server/9.x/subcommands.html#ca-cli-authorization). From 556380934ff1e23b8730e1ffc1f4b9fdd4c16ae4 Mon Sep 17 00:00:00 2001 From: Michael Harp Date: Tue, 15 Sep 2026 10:19:40 -0400 Subject: [PATCH 2/2] Say that any number of certificates can carry pp_cli_auth Review feedback: the server's own certificate is not special. Any service that calls the CA API gets a certificate with the extension, and having several is normal, so stop framing the server as the holder and other hosts as the exception. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Michael Harp --- docs/_openvox-server_8x/config_file_auth.markdown | 2 +- docs/_openvox-server_8x/subcommands.markdown | 2 +- docs/_openvox-server_9x/config_file_auth.markdown | 2 +- docs/_openvox-server_9x/subcommands.markdown | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_openvox-server_8x/config_file_auth.markdown b/docs/_openvox-server_8x/config_file_auth.markdown index a836356a1..26aad6d8d 100644 --- a/docs/_openvox-server_8x/config_file_auth.markdown +++ b/docs/_openvox-server_8x/config_file_auth.markdown @@ -192,7 +192,7 @@ The default `auth.conf` uses an `extensions` match to authorize the `puppetserve } ``` -See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how the server's own certificate gets that extension and how to issue it to another host. +See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how a certificate gets that extension. The server's own certificate has it, and so can any number of others, for example for services that call the CA API. #### `sort-order` diff --git a/docs/_openvox-server_8x/subcommands.markdown b/docs/_openvox-server_8x/subcommands.markdown index 06152c4ab..19aa9fa50 100644 --- a/docs/_openvox-server_8x/subcommands.markdown +++ b/docs/_openvox-server_8x/subcommands.markdown @@ -67,7 +67,7 @@ Two consequences follow from this: - If the server's host certificate is replaced by any other route, for example by cleaning it and letting the agent request an ordinary certificate, the new certificate lacks the extension and every `ca` action except `setup` and `import` is refused with `403 Forbidden`. `puppetserver ca generate` refuses to overwrite an existing certificate or key, so follow [Regenerate the primary server's certificate](./certificate_renewal.html#regenerate-the-primary-servers-certificate), which removes the old files first and shows how to carry the subject alternative names over. -- To run `puppetserver ca` from another host, generate that host's certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. +- To give another host or service the same access, whether to run `puppetserver ca` there or to call the CA API directly, generate its certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. A certificate with `pp_cli_auth` can list, sign, revoke, and clean any certificate the CA manages, so treat it as an administrative credential and never issue it to ordinary agents. `--ca-client` signs the certificate offline, without the running CA service, so use it only while OpenVox Server is stopped. This offline path is the only way to put the extension in a certificate. The CA refuses any CSR that requests `pp_cli_auth`, even when `allow-authorization-extensions` is enabled, so it cannot be obtained through `csr_attributes.yaml` and a normal signing. diff --git a/docs/_openvox-server_9x/config_file_auth.markdown b/docs/_openvox-server_9x/config_file_auth.markdown index d36d2dbf9..65179ee46 100644 --- a/docs/_openvox-server_9x/config_file_auth.markdown +++ b/docs/_openvox-server_9x/config_file_auth.markdown @@ -200,7 +200,7 @@ The default `auth.conf` uses an `extensions` match to authorize the `puppetserve } ``` -See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how the server's own certificate gets that extension and how to issue it to another host. +See [CA CLI authorization](./subcommands.html#ca-cli-authorization) for how a certificate gets that extension. The server's own certificate has it, and so can any number of others, for example for services that call the CA API. #### `sort-order` diff --git a/docs/_openvox-server_9x/subcommands.markdown b/docs/_openvox-server_9x/subcommands.markdown index 06152c4ab..19aa9fa50 100644 --- a/docs/_openvox-server_9x/subcommands.markdown +++ b/docs/_openvox-server_9x/subcommands.markdown @@ -67,7 +67,7 @@ Two consequences follow from this: - If the server's host certificate is replaced by any other route, for example by cleaning it and letting the agent request an ordinary certificate, the new certificate lacks the extension and every `ca` action except `setup` and `import` is refused with `403 Forbidden`. `puppetserver ca generate` refuses to overwrite an existing certificate or key, so follow [Regenerate the primary server's certificate](./certificate_renewal.html#regenerate-the-primary-servers-certificate), which removes the old files first and shows how to carry the subject alternative names over. -- To run `puppetserver ca` from another host, generate that host's certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. +- To give another host or service the same access, whether to run `puppetserver ca` there or to call the CA API directly, generate its certificate the same way: stop the server, run `puppetserver ca generate --certname --ca-client` on the CA, then copy the resulting key and certificate to the host. A certificate with `pp_cli_auth` can list, sign, revoke, and clean any certificate the CA manages, so treat it as an administrative credential and never issue it to ordinary agents. `--ca-client` signs the certificate offline, without the running CA service, so use it only while OpenVox Server is stopped. This offline path is the only way to put the extension in a certificate. The CA refuses any CSR that requests `pp_cli_auth`, even when `allow-authorization-extensions` is enabled, so it cannot be obtained through `csr_attributes.yaml` and a normal signing.