diff --git a/website/content/api-docs/secret/pki.mdx b/website/content/api-docs/secret/pki.mdx
index b3ee111f6f..c952dec9c1 100644
--- a/website/content/api-docs/secret/pki.mdx
+++ b/website/content/api-docs/secret/pki.mdx
@@ -30,7 +30,9 @@ update your API calls accordingly.
- [List Roles](#list-roles)
- [Read Role](#read-role)
- [Generate Certificate and Key](#generate-certificate-and-key)
+ - [Generate Certificate and Key with External Policy](#generate-certificate-and-key-with-external-policy)
- [Sign Certificate](#sign-certificate)
+ - [Sign Certificate with External Policy](#sign-certificate-with-external-policy)
- [Sign Intermediate](#sign-intermediate)
- [Sign Self-Issued](#sign-self-issued)
- [Sign Verbatim](#sign-verbatim)
@@ -142,24 +144,30 @@ $ certbot certonly --server https://localhost:8200/v1/pki/acme/directory ...
These endpoints are unauthenticated from a Vault authentication model, but
internally authenticated via the ACME protocol.
-| Method | Path | Default Directory Policy | Issuer | Role |
-|:-------|:-----------------------------------------------------|:-------------------------|:----------------------|:--------------|
-| `ACME` | `/pki/acme/directory` | `sign-verbatim` | `default` | Sign-Verbatim |
-| `ACME` | `/pki/acme/directory` | `role:role_ref` | Specified by the role | `:role_ref` |
-| `ACME` | `/pki/issuer/:issuer_ref/acme/directory` | `sign-verbatim` | `:issuer_ref` | Sign-Verbatim |
-| `ACME` | `/pki/issuer/:issuer_ref/acme/directory` | `role:role_ref` | `:issuer_ref` | `:role_ref` |
-| `ACME` | `/pki/roles/:role/acme/directory` | (any) | Specified by the role | `:role` |
-| `ACME` | `/pki/issuer/:issuer_ref/roles/:role/acme/directory` | (any) | `:issuer_ref` | `:role` |
+| Method | Path | Default Directory Policy | Issuer | Role |
+|:-------|:-------------------------------------------------------------------|:---------------------------|:----------------------|:--------------|
+| `ACME` | `/pki/acme/directory` | `sign-verbatim` | `default` | Sign-Verbatim |
+| `ACME` | `/pki/acme/directory` | `role:role_ref` | Specified by the role | `:role_ref` |
+| `ACME` | `/pki/acme/directory` | `external-policy(:policy)` | Specified by CIEPS | CIEPS |
+| `ACME` | `/pki/issuer/:issuer_ref/acme/directory` | `sign-verbatim` | `:issuer_ref` | Sign-Verbatim |
+| `ACME` | `/pki/issuer/:issuer_ref/acme/directory` | `role:role_ref` | `:issuer_ref` | `:role_ref` |
+| `ACME` | `/pki/roles/:role/acme/directory` | (any) | Specified by the role | `:role` |
+| `ACME` | `/pki/issuer/:issuer_ref/roles/:role/acme/directory` | (any) | `:issuer_ref` | `:role` |
+| `ACME` | `/pki/external-policy(/:policy)/acme/directory` | (any) | Specified by CIEPS | CIEPS |
+| `ACME` | `/pki/issuer/:issuer_ref/external-policy(/:policy)/acme/directory` | (any) | Specified by CIEPS | CIEPS |
-When a role is not specified (for the first two directory URLs, or four lines
-in the table), behavior is specified by the `default_directory_policy` in the
-[ACME configuration](#set-acme-configuration). These directories can also be
-forbidden by setting that policy as `forbid`. If the policy is `sign-verbatim`
-then _any_ identifier for which the client can prove ownership of will be
-issued for. This is similar to using the [Sign Verbatim](#sign-verbatim)
-endpoint, but with additional verification that the client has proven
-ownership (within the ACME protocol) of the requested certificate
-identifiers.
+When a role is not explicitly specified, behavior is specified by the
+`default_directory_policy` in the [ACME configuration](#set-acme-configuration).
+These directories can also be forbidden by setting that policy as `forbid`. If
+the policy is `sign-verbatim` then _any_ identifier for which the client can
+prove ownership of will be issued for. This is similar to using the
+[Sign Verbatim](#sign-verbatim) endpoint, but with additional verification
+that the client has proven ownership (within the ACME protocol) of the
+requested certificate identifiers. When `external-policy` is specified as the
+default value, the CIEPS engine is used for
+validating and templating the certificate. An optional policy name can be
+specified by using `external-policy:policy`. Roles are not used when CIEPS is
+used.
#### ACME challenge types
@@ -690,6 +698,103 @@ $ curl \
}
```
+### Generate certificate and key with external policy
+
+Similar to the [generate certificate and key](#generate-certificate-and-key)
+endpoint, this endpoint generate key material and certificate via an external
+policy engine. The private key material stays local to Vault, with the external
+service getting only an empty CSR. Any parameters passed to this endpoint are
+passed verbatim to the CIEPS engine . The
+response format is the same between both endpoints.
+
+It is suggested to limit access to the path-overridden issue endpoint (on
+`/pki/issuer/:issuer_ref/external-policy/issue/:policy`) and let the CIEPS
+engine override the issuer as necessary.
+
+| Method | Path | Issuer |
+| :----- | :------------------------------------------------------ | :-------------------------- |
+| `POST` | `/pki/external-policy/issue/:policy` | `default` or CIEPS-selected |
+| `POST` | `/pki/issuer/:issuer_ref/external-policy/issue/:policy` | Path or CIEPS selected |
+
+#### Parameters
+
+- `policy` `(string: )` - Specifies the name of the policy to create
+ the certificate against. This is part of the request URL and is passed to the
+ external CIEPS engine.
+
+- `issuer_ref` `(string: )` - Reference to an existing issuer,
+ either by Vault-generated identifier, the literal string `default` to
+ refer to the currently configured default issuer, or the name assigned
+ to an issuer. This parameter is part of the request URL.
+
+~> Note: This parameter is not present on the `/pki/external-policy/sign/:policy`
+ path and takes its value from the CIEPS engine response's `issuer_ref`
+ field, which can override the user-requested issuer.
+
+- `format` `(string: "pem")` - Specifies the format for returned data. Can be
+ `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is
+ base64 encoded. If `pem_bundle`, the `certificate` field will contain the
+ private key and certificate, concatenated; if the issuing CA is not a
+ Vault-derived self-signed root, this will be included as well.
+
+- `key_type` `(string: "rsa")` - Specifies the desired key type; must be `rsa`, `ed25519`
+ or `ec`.
+
+~> **Note**: In FIPS 140-2 mode, the following algorithms are not certified
+ and thus should not be used: `ed25519`.
+
+- `key_bits` `(int: 0)` - Specifies the number of bits to use for the
+ generated keys. Allowed values are 0 (universal default); with
+ `key_type=rsa`, allowed values are: 2048 (default), 3072, or
+ 4096; with `key_type=ec`, allowed values are: 224, 256 (default),
+ 384, or 521; ignored with `key_type=ed25519`.
+
+- `private_key_format` `(string: "der")` - Specifies the format for marshaling
+ the private key within the private_key response field. Defaults to `der` which will
+ return either base64-encoded DER or PEM-encoded DER, depending on the value of
+ `format`. The other option is `pkcs8` which will return the key marshalled as
+ PEM-encoded PKCS8.
+
+~> **Note** that this does not apply to the private key within the certificate
+ field if `format=pem_bundle` parameter is specified.
+
+
+- `remove_roots_from_chain` `(bool: false)` - If true, the returned `ca_chain`
+ field will not include any self-signed CA certificates. Useful if end-users
+ already have the root CA in their trust store.
+
+Other parameters may be specified and will not be parsed by Vault but may be
+recognized based on external CIEPS engine definition.
+
+#### Sample payload
+
+```json
+{
+ "common_name": "example.com",
+ "key_type": "rsa",
+ "key_bits": 2048
+}
+```
+
+#### Sample response
+
+```json
+{
+ "lease_id": "",
+ "renewable": false,
+ "lease_duration": 0,
+ "data": {
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n",
+ "issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n...\nG/7g4koczXLoUM3OQXd5Aq2cs4SS1vODrYmgbioFsQ3eDHd1fg==\n-----END CERTIFICATE-----\n",
+ "ca_chain": [
+ "-----BEGIN CERTIFICATE-----\nMIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n...\nG/7g4koczXLoUM3OQXd5Aq2cs4SS1vODrYmgbioFsQ3eDHd1fg==\n-----END CERTIFICATE-----\n"
+ ],
+ "serial_number": "39:dd:2e:90:b7:23:1f:8d:d3:7d:31:c5:1b:da:84:d0:5b:65:31:52"
+ },
+ "auth": null
+}
+```
+
### Sign certificate
This endpoint signs a new certificate based upon the provided CSR and the
@@ -804,6 +909,91 @@ It is suggested to limit access to the path-overridden sign endpoint (on
}
```
+### Sign certificate with external policy
+
+Similar to the [sign certificate](#sign-certificate) endpoint, this endpoint
+signs the specified leaf CSR via an external policy engine. Any parameters
+passed to this endpoint are passed verbatim to the CIEPS
+engine . The response format is the same
+between both endpoints.
+
+It is suggested to limit access to the path-overridden sign endpoint (on
+`/pki/issuer/:issuer_ref/external-policy/sign/:policy`) and let the CIEPS
+engine override the issuer as necessary.
+
+| Method | Path | Issuer |
+| :----- | :----------------------------------------------------- | :-------------------------- |
+| `POST` | `/pki/external-policy/sign/:policy` | `default` or CIEPS-selected |
+| `POST` | `/pki/issuer/:issuer_ref/external-policy/sign/:policy` | Path or CIEPS selected |
+
+#### Parameters
+
+- `policy` `(string: )` - Specifies the name of the policy to create
+ the certificate against. This is part of the request URL and is passed to the
+ external CIEPS engine.
+
+- `issuer_ref` `(string: )` - Reference to an existing issuer,
+ either by Vault-generated identifier, the literal string `default` to
+ refer to the currently configured default issuer, or the name assigned
+ to an issuer. This parameter is part of the request URL.
+
+~> Note: This parameter is not present on the `/pki/external-policy/sign/:policy`
+ path and takes its value from the CIEPS engine response's `issuer_ref`
+ field, which can override the user-requested issuer.
+
+- `csr` `(string: )` - Specifies the PEM-encoded CSR.
+
+- `format` `(string: "pem")` - Specifies the format for returned data. Can be
+ `pem`, `der`, or `pem_bundle`; defaults to `pem`. If `der`, the output is
+ base64 encoded. If `pem_bundle`, the `certificate` field will contain the
+ private key and certificate, concatenated; if the issuing CA is not a
+ Vault-derived self-signed root, this will be included as well.
+
+- `private_key_format` `(string: "der")` - Specifies the format for marshaling
+ the private key within the private_key response field. Defaults to `der` which will
+ return either base64-encoded DER or PEM-encoded DER, depending on the value of
+ `format`. The other option is `pkcs8` which will return the key marshalled as
+ PEM-encoded PKCS8.
+
+~> **Note** that this does not apply to the private key within the certificate
+ field if `format=pem_bundle` parameter is specified.
+
+- `remove_roots_from_chain` `(bool: false)` - If true, the returned `ca_chain`
+ field will not include any self-signed CA certificates. Useful if end-users
+ already have the root CA in their trust store.
+
+Other parameters may be specified and will not be parsed by Vault but may be
+recognized based on external CIEPS engine definition.
+
+#### Sample payload
+
+```json
+{
+ "csr": "...",
+ "common_name": "example.com",
+ "key_attestation": "..."
+}
+```
+
+#### Sample response
+
+```json
+{
+ "lease_id": "",
+ "renewable": false,
+ "lease_duration": 0,
+ "data": {
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n",
+ "issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n...\nG/7g4koczXLoUM3OQXd5Aq2cs4SS1vODrYmgbioFsQ3eDHd1fg==\n-----END CERTIFICATE-----\n",
+ "ca_chain": [
+ "-----BEGIN CERTIFICATE-----\nMIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n...\nG/7g4koczXLoUM3OQXd5Aq2cs4SS1vODrYmgbioFsQ3eDHd1fg==\n-----END CERTIFICATE-----\n"
+ ],
+ "serial_number": "39:dd:2e:90:b7:23:1f:8d:d3:7d:31:c5:1b:da:84:d0:5b:65:31:52"
+ },
+ "auth": null
+}
+```
+
### Sign intermediate
This endpoint uses the configured CA certificate to issue a certificate with