vault_pki

Manage the Vault (or OpenBao) PKI secret engine and Vault-issued X.509 certificates.

Added in version 1.1.0.

Important

This module requires the general Vault setup.

saltext.vault.states.vault_pki.certificate_managed(name, common_name=None, role_name=None, private_key=None, csr=None, mount='pki', ttl='720h', ttl_remaining='168h', issuer_ref=None, encoding='pem', append_ca_chain=False, sign_verbatim=False, private_key_passphrase=None, reissue=False, *, alt_names=None, exclude_cn_from_sans=False, not_after=None, serial_number=None, user_ids=None, key_usage=None, ext_key_usage=None, ext_key_usage_oids=None, **kwargs)[source]

Ensure an X.509 leaf certificate is present as specified.

Note

This state can use the sign-verbatim endpoint, which allows minute control of the certificate’s subject name and most extensions (see sign_verbatim below). If not used, only CN is preserved from the CSR subject, any other subject name attributes are taken from the role instead. Check this issue for more information.

Changed in version 1.9.0: Now compares all certificate subject attributes and extensions, including those that are derived from PKI role parameters and issuer URL configuration. This requires read access to the role, issuer and mount default URL configuration. If read access to the URL configuration is denied, URL-derived extensions are not verified and a note is appended to the state’s comment instead. The same graceful fallback applies to role-derived subject attributes and extensions when read access to the role is denied, but only if issuer_ref is specified explicitly - otherwise, the role configuration is required to discover the signing issuer and the state fails, as it always has.

Also, when issuer_ref is unspecified, now uses the generic <mount>/sign* endpoints instead of the issuer-specific <mount>/issuer/<issuer_ref>/sign/<role_name> with the explicit issuer_ref from the role.

Required policy:

# Need to read the role configuration in case of missing issuer_ref
# and to more accurately predict changes.
# Note: When issuer_ref is specified explicitly, failure to read
# this does not cause reissuance, only a note.
path "<mount>/roles/<role_name>" {
    capabilities = ["read"]
}

# Read mount default urls to account for cert extensions
# if the issuer has no configured URLs.
# Note: Failure to read this does not cause reissuance, only a note.
path "<mount>/config/urls" {
    capabilities = ["read"]
}

# Read issuer for URL configuration and CA chain. issuer_ref becomes `default` if unspecified
path "<mount>/issuer/<issuer_ref>" {
    capabilities = ["read"]
}

# When URLs use templating with `{{cluster_path}}`/`{{cluster_aia_path}}` variables
# Note: Failure to read this does not cause reissuance, only a note.
path "<mount>/config/cluster" {
    capabilities = ["read"]
}

# When sign_verbatim is false and not specifying issuer_ref
path "<mount>/sign/<role_name>" {
    capabilities = ["update"]
}

# When sign_verbatim is false and specifying issuer_ref
path "<mount>/issuer/<issuer_ref>/sign/<role_name>" {
    capabilities = ["update"]
}

# When sign_verbatim is true and neither specifying issuer_ref nor role_name
path "<mount>/sign-verbatim" {
    capabilities = ["update"]
}

# When sign_verbatim is true and specifying role_name, but not issuer_ref
path "<mount>/sign-verbatim/<role_name>" {
    capabilities = ["update"]
}

# When sign_verbatim is true and specifying issuer_ref, but not role_name
path "<mount>/issuer/<issuer_ref>/sign-verbatim" {
    capabilities = ["update"]
}

# When sign_verbatim is true and specifying both issuer_ref and role_name
path "<mount>/issuer/<issuer_ref>/sign-verbatim/<role_name>" {
    capabilities = ["update"]
}
name

Path to the managed certificate file.

common_name

Subject common name (CN) for the certificate. Required, unless the role explicitly sets require_cn to false or sign_verbatim is true. Ignored (i.e. also not required) when a csr is passed that specifies it and the role’s use_csr_common_name is true (the default value).

role_name

PKI role to use for issuing the certificate. Required, unless sign_verbatim is true.

private_key

Path or text of the private key to use for signing the CSR and thus as the private key for the certificate. Either this or csr is required.

csr

Added in version 1.9.0.

Path or text of the CSR to use for issuing the certificate. Either this or private_key is required.

mount

Mount path the PKI backend is mounted to. Defaults to pki.

ttl

Specifies the requested Time To Live (after which the certificate will be expired). Can be an integer, which is interpreted as seconds, or a time string such as 1h. Hour is the largest suffix. Defaults to 720h or 30 days.

Note

The effective validity is capped by the role’s max_ttl, if a role is used. This is accounted for in change reports when the role is readable.

ttl_remaining

If an existing certificate’s remaining Time To Live undercuts this period, renew it. Can be an integer, which is interpreted as seconds, or a time string such as 1h. Hour is the largest suffix. Defaults to 168h or 7 days.

Note

Must be less than the role’s max_ttl, if a role is used, otherwise issued certificates would be immediately due for renewal. The same applies to the signing issuer’s remaining validity, unless its leaf_not_after_behavior is set to permit.

issuer_ref

Override the specified role’s issuer for the certificate. Defaults to the one specified in the role.

encoding

Encoding of the managed certificate file. Valid options are pem, pkcs7_pem, der, pkcs7_der. Defaults to pem.

append_ca_chain

Whether to append the CA chain to the certificate. Defaults to false.

Note

This appends all CA chain certificates of the selected issuer except self-signed (root) ones.

sign_verbatim

If set to true, the resulting certificate follows the CSR more or less exactly, including extensions. Otherwise, only CN can be set for the subject, any other subject parameters (like O) are taken from the role.

Warning

This option uses a potentially dangerous endpoint. Be careful when using that option, as roles are not restricting what can be issued anymore.

private_key_passphrase

Password for the private key if encrypted.

reissue

Always reissue the certificate. Defaults to false.

alt_names

Any alternative names to add to the certificate. Can be specified either as dict ({ "<type>": "<value>" }), a dict of lists ({ "<type>": ["<value1>", "<value2>", ...] }) or list of SAN strings (["<type1>:<value1>", ...]).

<type> can be dns, email, uri, ip or any OID for otherName SANs. <value> is the corresponding value. Note that otherName SANs need to omit UTF8:.

Ignored when a csr is passed and the role’s use_csr_sans is true (the default value).

exclude_cn_from_sans

If set to true, the Common Name is not added to the SANs. Useful if the CN is not a hostname or email address. Has no effect when sign_verbatim is true.

not_after

Absolute value of the Not After field of the certificate in UTC format YYYY-MM-ddTHH:MM:SSZ. When set, ttl is ignored. ttl_remaining is still validated, but falling below it causes state failure instead of a reissuance.

Note

Must not exceed the role’s max_ttl, if a role is specified, which enforces a hard cutoff during issuance. The same applies to the signing issuer’s expiry, unless its leaf_not_after_behavior is set to permit.

serial_number

Single value for the subject SERIALNUMBER (OID: 2.5.4.5) name attribute (NOT the certificate’s serial number!).

user_ids

List of User ID (UID) subject attributes. Each one is added to the generated CSR’s subject Name as a distinct RDN.

key_usage

When sign_verbatim is true, list of key usages to encode onto the certificate if the CSR does not specify a keyUsage extension. For non-verbatim issuance, this parameter must not be specified because Vault takes it from the role. Valid values can be found at https://golang.org/pkg/crypto/x509/#KeyUsage - simply drop the KeyUsage part of the value. Values are case-insensitive. Pass an empty list to specify no constraints.

ext_key_usage

When sign_verbatim is true, list of extended key usages to encode onto the certificate if the CSR does not specify an extendedKeyUsage extension. For non-verbatim issuance, this parameter must not be specified because Vault takes it from the role. Valid values can be found at https://golang.org/pkg/crypto/x509/#ExtKeyUsage - simply drop the ExtKeyUsage part of the value. Values are case-insensitive. Pass an empty list to specify no constraints.

ext_key_usage_oids

When sign_verbatim is true, list of extended key usage oids to encode onto the certificate if the CSR does not specify an extendedKeyUsage extension. Useful for adding EKUs not supported by the Go standard library. For non-verbatim issuance, this parameter must not be specified because Vault takes it from the role.

kwargs

Most parameters for the file.managed state or any of the ones for the Vault PKI sign_certificate execution module function are passed through.

Hint

This is a high-level state, which connects several different functions:

  • Vault API (sign-certificate or sign-verbatim, depending on the value of sign_verbatim). Completely unknown keyword parameters end up there.

  • x509.create_csr: Used to generate a CSR that Vault should sign. Any subject name attribute parameters (O, OU etc.) and most extension parameters (certificatePolicies, keyUsage, extendedKeyUsage etc.) end up here. Note that Vault does not follow the CSR literally, even sign-verbatim e.g. prohibits basicConstraints with CA: true. The CN and subjectAltName parameters are synced with common_name and alt_names respectively, so specifying them directly has no effect. Ignored when csr is defined.

  • file.managed: Parameters such as user, group and mode end up influencing the certificate file on disk. Note: encoding is a valid parameter for both this function and file.managed. If you need to pass it to the latter, specify it as file_encoding instead.

saltext.vault.states.vault_pki.ca_certificate_managed(name, common_name=None, *, private_key=None, private_key_passphrase=None, csr=None, issuer_ref=None, sign_verbatim=False, ttl='4320h', ttl_remaining='1440h', encoding='pem', append_ca_chain=False, alt_names=None, max_path_length=None, key_usage=None, exclude_cn_from_sans=False, permitted_alt_names=None, excluded_alt_names=None, ou=None, organization=None, country=None, locality=None, province=None, street_address=None, postal_code=None, serial_number=None, signature_bits=0, not_before_duration=30, not_after=None, mount='pki', **kwargs)[source]

Added in version 1.9.0.

Ensure an X.509 CA certificate is present as specified.

Required policy:

# Read mount default urls to account for cert extensions
# if the issuer has no configured URLs.
# Note: Failure to read this does not cause reissuance, only a note.
path "<mount>/config/urls" {
    capabilities = ["read"]
}

# Read issuer for URL configuration and CA chain. issuer_ref becomes `default` if unspecified
path "<mount>/issuer/<issuer_ref>" {
    capabilities = ["read"]
}

# When URLs use templating with `{{cluster_path}}`/`{{cluster_aia_path}}` variables
# Note: Failure to read this does not cause reissuance, only a note.
path "<mount>/config/cluster" {
    capabilities = ["read"]
}

# When issuer_ref is not specified
path "<mount>/root/sign-intermediate" {
    capabilities = ["update"]
}

# When issuer_ref is specified
path "<mount>/issuer/<issuer_ref>/sign-intermediate" {
    capabilities = ["update"]
}
name

Path to the managed certificate file.

common_name

Subject common name (CN) for the certificate. Required, unless sign_verbatim is true.

private_key

Path or text of the private key to use for signing the CSR and thus as the private key for the certificate. Either this or csr is required.

private_key_passphrase

Password for the private key if encrypted.

csr

Path or text of the CSR to use for issuing the certificate. Either this or private_key is required.

issuer_ref

Specify issuer_name or issuer_id of intended issuer. Defaults to the mount default issuer.

sign_verbatim

If set to true, the resulting certificate follows the CSR more or less exactly, including the full subject and all extensions.

ttl

Specifies the requested Time To Live (after which the certificate will be expired). Can be an integer, which is interpreted as seconds, or a time string such as 1h. Hour is the largest suffix. Defaults to 4320h or 180 days.

Hint

Translated into not_after, hence not subject to the mount’s max_lease_ttl.

ttl_remaining

If an existing certificate’s remaining Time To Live undercuts this period, renew it. Can be an integer, which is interpreted as seconds, or a time string such as 1h. Hour is the largest suffix. Defaults to 1440h or 60 days.

Hint

This value should exceed the maximum validity of certificates issued by this CA, otherwise issuance close to its expiry can fail or yield certificates outliving it.

It must also be less than the signing issuer’s remaining validity when a Vault issuer signs this certificate, otherwise the certificate would be reissued during each run. This does not apply when the issuer’s leaf_not_after_behavior is set to permit and enforce_leaf_not_after_behavior is passed.

encoding

Encoding of the managed certificate file. Valid options are pem, pkcs7_pem, der, pkcs7_der. Defaults to pem.

append_ca_chain

Whether to append the CA chain to the certificate. Defaults to false.

Note

This appends all CA chain certificates of the selected issuer except self-signed (root) ones.

alt_names

Any alternative names to add to the certificate. Can be specified either as dict ({ "<type>": "<value>" }), a dict of lists ({ "<type>": ["<value1>", "<value2>", ...] }) or list of SAN strings (["<type1>:<value1>", ...]).

<type> can be dns, email, uri, ip or any OID for otherName SANs. <value> is the corresponding value. Note that otherName SANs need to omit UTF8:.

Ignored when a csr is passed and sign_verbatim is true.

max_path_length

basicConstraints pathlen parameter, which indicates the maximum number of CAs that can appear below this one in a chain. If set to 0, this CA can only issue leaf certificates, not other CAs. A negative value means no limit, unless the issuer certificate has a maximum path length, in which case it means one less than the issuer’s pathlen. Defaults to -1. Applies even when sign_verbatim is true: Vault does not allow a CSR to specify a basicConstraints extension with CA:true.

key_usage

(Requires Vault 1.20+ or OpenBao) List of key usages to add to the existing set of key usages (CRLSign,CertSign). Per the CAB Forum requirements, Vault ignores values other than DigitalSignature. Ignored when a csr is passed and sign_verbatim is true.

exclude_cn_from_sans

If set to true, the Common Name is not added to the SANs. Useful if the CN is not a hostname or email address. Has no effect when sign_verbatim is true.

permitted_alt_names

List of alternative names for which certificates are allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip. Ignored when a csr is passed and sign_verbatim is true.

Important

Types other than dns require Vault 1.19+.

excluded_alt_names

(Vault 1.19+ only) List of alternative names for which certificates are not allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip. Ignored when a csr is passed and sign_verbatim is true.

Subject DN fields

Most of these can be single strings or lists of strings (for multiple values). Ignored when sign_verbatim is true.

  • ou

  • organization

  • country

  • locality

  • province

  • street_address

  • postal_code

  • serial_number (only a single value; NOT the certificate’s serial number, just the SERIALNUMBER name attribute)

signature_bits

Number of bits to use in the signature algorithm. Valid: 256 (SHA-2-256), 384 (SHA-2-384), 512 (SHA-2-512). Defaults to 0, which automatically selects an algorithm based on the issuer’s key length.

not_before_duration

Duration by which to backdate the NotBefore property. Defaults to 30s.

not_after

Absolute value of the Not After field of the certificate in UTC format YYYY-MM-ddTHH:MM:SSZ. When set, ttl is ignored. ttl_remaining is still validated, but falling below it causes state failure instead of a reissuance.

Important

Must not exceed the signing issuer’s own expiry, which enforces a hard cutoff during issuance, unless the issuer’s leaf_not_after_behavior is set to permit and enforce_leaf_not_after_behavior is passed.

mount

Mount path the PKI backend is mounted to. Defaults to pki.

kwargs

Most parameters for the file.managed state or any of the ones for the Vault PKI sign_intermediate execution module function are passed through.

Hint

This is a high-level state, which connects several different functions:

  • Vault API (sign-intermediate). Completely unknown keyword parameters end up there.

  • x509.create_csr: Used to generate a CSR that Vault should sign. Any subject name attribute parameters (O, OU etc.) and most extension parameters (certificatePolicies, keyUsage, extendedKeyUsage etc.) end up here. Ignored when csr is defined or sign_verbatim is false (so by default).

  • file.managed: Parameters such as user, group and mode end up influencing the certificate file on disk. Note: encoding is a valid parameter for both this function and file.managed. If you need to pass it to the latter, specify it as file_encoding instead.

saltext.vault.states.vault_pki.role_managed(name, mount='pki', issuer_ref=None, ttl=None, max_ttl=None, **kwargs)[source]

Ensure a PKI role is present and configured as specified.

name

Name of the role.

mount

Mount path the PKI backend is mounted to. Defaults to pki.

issuer_ref

Issuer reference for the role. Can be name, id or literal default.

ttl

Specifies the Time To Live value to be used for the validity period of the requested certificate, provided as a string duration with time suffix. Hour is the largest suffix. The value specified is strictly used for future validity. If not set, uses the system default value or the value of max_ttl, whichever is shorter.

max_ttl

Specifies the maximum Time To Live provided as a string duration with time suffix. Hour is the largest suffix. If not set, defaults to the system maximum lease TTL.

kwargs

Any other parameter accepted by the Vault write_role execution module function or Vault update role API method.

saltext.vault.states.vault_pki.role_absent(name, mount='pki')[source]

Ensure a PKI role is absent.

name

Name of the role.

mount

Mount path the PKI backend is mounted to. Defaults to pki.

saltext.vault.states.vault_pki.intermediate_issuer_managed(name, days_remaining=60, rotate_key=False, issuer_ref=None, issuer_mount=None, key_ref=None, key_type=None, key_algo=None, key_bits=None, managed_key_name=None, managed_key_id=None, days_valid=180, not_after=None, not_before_duration=30, max_path_length=0, alt_names=None, exclude_cn_from_sans=False, key_usage=None, permitted_alt_names=None, excluded_alt_names=None, ou=None, organization=None, country=None, locality=None, province=None, street_address=None, postal_code=None, serial_number=None, signature_bits=0, issuer_name=None, leaf_not_after_behavior=None, usage=None, revocation_signature_algorithm=None, aia_urls=None, crl_endpoints=None, delta_crl_endpoints=None, ocsp_servers=None, aia_url_templating=None, mount='pki', **kwargs)[source]

Added in version 1.9.0.

Ensure an issuer representing an intermediate CA is present as the default issuer on the mount. Rotates the issuer when necessary by generating a new certificate. Unlike root_issuer_managed(), the rotation always happens when the certificate does not match the configuration, not only when days_remaining indicates expiry.

Important

You need to prune keys and issuers manually, they are never deleted by this state.

Hint

When an issuer is rotated, the old one is kept with slightly adjusted configuration:

  1. If issuer_name is specified and matches the old one, it receives the current timestamp as a suffix, separated by a dash (<issuer_name>-<timestamp>).

  2. issuing-certificates is removed from its usages.

Other issuers on the mount, e.g. manually cross-signed variants of the managed one, are ignored by this state and can coexist safely, as long as they are not assigned its issuer_name.

Signs the issuer certificate either via another Vault issuer or a Salt-internal CA.

A Vault issuer is selected by specifying issuer_ref. The resulting certificate can only be influenced by valid parameters to the endpoint used by vault_pki.sign_intermediate; passing sign_verbatim, CSR generation arguments or a pre-generated CSR has no effect.

When issuer_ref is unspecified, we rely on x509.create_certificate. Any unknown keyword arguments to this function are passed through. Vault-style parameters like alt_names are translated transparently (into subjectAltName and its format, in this example). You can still pass x509_v2-style parameters directly, these translations only happen when the respective x509.create_certificate parameter is not found in kwargs. Some x509.create_certificate parameters are enforced by this function, see kwargs below. The final certificate also depends on a signing_policy, if passed. It can override any parameter without this state failing or reporting necessary changes, similar to x509.certificate_managed.

Does not support certificate import.

Required policy:

# Read default issuer to check for necessary changes
path "<mount>/issuer/default" {
    capabilities = ["read"]
}

# When key_ref is not set, need to generate a key
path "<mount>/keys/generate/<key_type>" {
    capabilities = ["create", "update"]
}

# When key_ref is set, need to resolve names to ids
path "<mount>/keys" {
    capabilities = ["list"]
}

# Generate a CSR to derive the public key
path "<mount>/intermediate/generate/existing" {
    capabilities = ["create", "update"]
}

# When issuer_ref is specified, read the signing issuer to check for
# necessary changes. issuer_mount defaults to the value of mount.
path "<issuer_mount>/issuer/<issuer_ref>" {
    capabilities = ["read"]
}

# When issuer_ref is specified, we use that issuer to sign the certificate
path "<issuer_mount>/issuer/<issuer_ref>/sign-intermediate" {
    capabilities = ["update"]
}

# Import the signed cert
path "<mount>/intermediate/set-signed" {
    capabilities = ["create", "update"]
}

# Set default issuer
path "<mount>/config/issuers" {
    capabilities = ["create", "update"]
}

# Update issuer configuration. Might also be exercised when
# no issuer params are specified for config recovery after rotation.
path "<mount>/issuer/<issuer_id>" {
    capabilities = ["patch"]
}

# When issuer_ref is specified, read the signing issuer's mount default urls
# to account for cert extensions, unless the signing issuer overrides them
# with its own AIA configuration.
# Note: Failure to read this does not cause rotation, only a note.
path "<issuer_mount>/config/urls" {
    capabilities = ["read"]
}

# When URLs use templating with `{{cluster_path}}`/`{{cluster_aia_path}}` variables
# Note: Failure to read this does not cause rotation, only a note.
path "<issuer_mount>/config/cluster" {
    capabilities = ["read"]
}

Certificate/Key configuration:

name

Common name (CN) of the certificate subject.

Note

When issuer_ref is unspecified, the final CN can differ from this value because of signing policy merging.

days_remaining

Attempt to recreate the certificate if its remaining validity falls below this number of days. Defaults to 60.

Hint

This value should exceed the maximum validity of certificates issued by this CA, otherwise issuance close to its expiry can fail or yield certificates outliving it.

It must also be less than the signing issuer’s remaining validity when a Vault issuer signs this certificate, otherwise the certificate would be reissued during each run. This does not apply when the issuer’s leaf_not_after_behavior is set to permit and enforce_leaf_not_after_behavior is passed.

rotate_key

When rotating the default issuer, rotate its key along with it. Defaults to false. Not respected when key_ref is specified.

Important

Cross-signed variants of this issuer certify the old key, so they stop bridging anything issued under the new one. They are not re-established by this state, you need to cross-sign the new key manually.

Note

Key parameters are not managed statefully, meaning changes to key_type, key_algo and key_bits are only applied when generating a new key. key_ref changes are applied though.

issuer_ref

Issuer name/ID of the issuer that should sign this issuer’s certificate. If unspecified, uses x509.create_certificate to sign it instead.

issuer_mount

When issuer_ref is specified and the issuer is on a different mount, specify it here. Defaults to the value of mount.

key_ref

Instead of managing the key, use the one associated with this key ID/name. When specified, disables key generation/rotation.

key_type

Type of key to generate when necessary and key_ref is not specified. Either internal, exported or kms. Defaults to internal.

key_algo

Key algorithm. Either rsa, ed25519 or ec. Defaults to rsa.

key_bits

Number of bits to use for the generated keys. Valid values depend on the key_algo.

  • rsa: 2048 (default), 3072, 4096, 8192.

  • ec: 224, 256 (default), 384, 521

  • ed25519: ignored

Defaults to 0 (universal default).

managed_key_name

When key_type is kms, the managed key’s configured name. Either this or managed_key_id is required then.

managed_key_id

When key_type is kms, the managed key’s UUID. Either this or managed_key_name is required then.

days_valid

Number of days the certificate should be valid for when (re-)issued. Not respected when not_after is set explicitly. Defaults to 180.

Hint

Translated into not_after when a Vault issuer signs the certificate, hence not subject to the mount’s max_lease_ttl.

not_after

Absolute value of the Not After field of the certificate in UTC format, either YYYY-MM-ddTHH:MM:SSZ or YYYY-MM-dd HH:MM:SS. When set, days_valid is ignored. days_remaining is still validated, but falling below it causes state failure instead of a reissuance.

Note

This parameter is valid for both issuance methods and translated into the correct format automatically.

Must not exceed the signing issuer’s own expiry when a Vault issuer signs the certificate, which enforces a hard cutoff during issuance, unless the issuer’s leaf_not_after_behavior is set to permit and enforce_leaf_not_after_behavior is passed.

not_before_duration

Duration by which to backdate the NotBefore property. Defaults to 30s.

Has no effect when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

max_path_length

basicConstraints pathlen parameter, which indicates the maximum number of CAs that can appear below this one in a chain. If set to 0, this CA can only issue leaf certificates, not other CAs. A negative value means no limit, unless the issuer certificate has a maximum path length, in which case it means one less than the issuer’s pathlen. Defaults to 0.

Forcibly translated into basicConstraints when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

alt_names

Any alternative names to add to the certificate. Can be specified either as dict ({ "<type>": "<value>" }), a dict of lists ({ "<type>": ["<value1>", "<value2>", ...] }) or list of SAN strings (["<type1>:<value1>", ...]).

<type> can be dns, email, uri, ip or any OID for otherName SANs. <value> is the corresponding value. Note that otherName SANs need to omit UTF8:.

Translated into subjectAltName when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

exclude_cn_from_sans

If set to true, the Common Name is not added to the SANs. Useful if the CN is not a hostname or email address.

Has no effect when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

key_usage

(Requires Vault 1.20+ or OpenBao when issuer_ref is specified) List of key usages to add to the existing set of key usages (CRLSign,CertSign). Per the CAB Forum requirements, Vault ignores values other than DigitalSignature.

Translated into keyUsage when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

permitted_alt_names

List of alternative names for which certificates are allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip.

Important

Types other than dns require Vault 1.19+ when issuer_ref is specified.

Translated into nameConstraints when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

excluded_alt_names

(Vault 1.19+ only when issuer_ref is specified) List of alternative names for which certificates are not allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip.

Translated into nameConstraints when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

Subject DN fields

Most of these can be single strings or lists of strings (for multiple values).

  • ou

  • organization

  • country

  • locality

  • province

  • street_address

  • postal_code

  • serial_number (only a single value; NOT the certificate’s serial number, just the SERIALNUMBER name attribute)

Translated into subject when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

Note

The resulting subject format depends on whether a signing_policy was specified or not, because a signing policy that defines any subject attribute would override the default format completely.

  • If no signing_policy is specified, it becomes a string that faithfully recreates subjects as rendered by Vault.

  • When it is specified, it becomes a dictionary (e.g. {CN: Foo}), which allows merging of attributes from a signing policy that defines subject as a dictionary itself (e.g. + {C: US} => CN=Foo,C=US). There are several tradeoffs to using a dict: Parameters with more than one value are ignored, postal_code is ignored and the subject name’s RDN order differs a bit from the one Vault renders.

This translation is only meant as a helper, you can always specify subject yourself. It’s possible to use a list of RDN strings here and in the signing policy, which results in the signing policy’s list being prepended to the one passed in here (i.e. appended when visualizing its rfc4514 string representation).

signature_bits

Number of bits to use in the signature algorithm. Valid: 256 (SHA-2-256), 384 (SHA-2-384), 512 (SHA-2-512). Defaults to 0, which automatically selects an algorithm based on the issuer’s key length.

Has no effect when a Salt-internal CA issues the certificate (issuer_ref is unspecified).

kwargs

Unknown keyword arguments are passed to the certificate signing function, which depends on whether issuer_ref is specified:

  • A non-empty issuer_ref means we rely on vault_pki.sign_intermediate.

    Note that its sign_verbatim parameter is forced to false and its csr parameter is enforced by this function, so CSR generation arguments do not have any effect and you cannot pass a pre-generated CSR.

  • No issuer_ref means we rely on x509.create_certificate. See there for details.

    The following arguments are enforced by this function:

    • basicConstraints ({critical: true, ca: true, pathlen: <max_path_length>})

    • csr

    • format (pem)

    • private_key/public_key/path/raw/serial_number (empty)

    These receive defaults from specified Vault-style parameters to this function:

    • subject

    • subjectAltName (not critical)

    • nameConstraints (critical)

    • keyUsage (critical)

    These receive defaults if not specified at all:

    • keyUsage: [critical, cRLSign, keyCertSign]

    • subjectKeyIdentifier: hash

    • authorityKeyIdentifier: keyid:always

    Note

    Certificates passed to append_certs are imported together with the issuer certificate when it is (re-)issued, but not handled statefully themselves.

Issuer configuration:

Note

Unspecified parameters are ignored during management and retain their current values in most cases.

This state tries to recover them after rotating an issuer certificate, which would otherwise reset them to their defaults if they were configured manually. This does not apply to issuer_name, which requires special handling, and manual_chain, which is not handled in this state. When the key changes (different key_ref or rotate_key), this also does not apply to revocation_signature_algorithm because a key algorithm change can make the previous value invalid.

issuer_name

Custom name for the issuer. Must be unique and not equal to default.

Important

Never assign this name to issuers managed outside of this state (e.g. cross-signed variants). A conflicting issuer might be renamed under specific circumstances; in all other cases, this state fails.

leaf_not_after_behavior

Behavior of a leaf’s NotAfter field during issuance when it exceeds the issuer’s validity. Valid options:

  • err: Error, unless during CA/ACME issuance. (default)

  • always_enforce_err: Error, including during CA/ACME issuance. (Vault 1.18.2+ only)

  • truncate: Silently truncate the requested NotAfter to that of the issuer.

  • permit: Allow signed certificate validities to exceed that of the issuer.

usage

Allowed usages for this issuer. Valid options are:

  • read-only - to allow this issuer to be read; implicit; always allowed;

  • issuing-certificates - to allow this issuer to be used for issuing other certificates;

  • crl-signing - to allow this issuer to be used for signing CRLs. This is separate from the CRLSign KeyUsage on the x509 certificate, but this usage cannot be set unless that KeyUsage is allowed on the x509 certificate;

  • ocsp-signing - to allow this issuer to be used for signing OCSP responses.

revocation_signature_algorithm

Which signature algorithm to use when building CRLs. See Go’s x509.SignatureAlgorithm constant for possible values. Default (empty string) is to autoselect.

aia_urls

Specifies the URL values for the Issuing Certificate field as an array.

crl_endpoints

Specifies the URL values for the CRL Distribution Points field as an array.

delta_crl_endpoints

(Requires Vault 1.20+ or OpenBao) Specifies the URL values for the Delta CRL Distribution Points field. This can be an array or a comma-separated string list.

ocsp_servers

Specifies the URL values for the OCSP Servers field as an array.

aia_url_templating

Render aia_urls/crl_endpoints/ocsp_servers/delta_crl_endpoints as templates. Supported variables: {{issuer_id}}, {{cluster_path}}, {{cluster_aia_path}}.

mount

Mount path the PKI backend is mounted to. Defaults to pki.

saltext.vault.states.vault_pki.root_issuer_managed(name, days_remaining=365, allow_premature_rotation=False, key_ref=None, rotate_key=False, key_type=None, key_algo=None, key_bits=None, managed_key_name=None, managed_key_id=None, alt_names=None, days_valid=3650, max_path_length=-1, key_usage=None, exclude_cn_from_sans=False, permitted_alt_names=None, excluded_alt_names=None, ou=None, organization=None, country=None, locality=None, province=None, street_address=None, postal_code=None, serial_number=None, signature_bits=0, not_before_duration=30, not_after=None, issuer_name=None, leaf_not_after_behavior=None, usage=None, revocation_signature_algorithm=None, aia_urls=None, crl_endpoints=None, delta_crl_endpoints=None, ocsp_servers=None, aia_url_templating=None, mount='pki')[source]

Added in version 1.9.0.

Ensure an issuer representing a root CA is present as the default issuer on the mount. Rotates the issuer certificate when necessary.

By default, rotates the issuer certificate only when days_remaining indicates expiry. If the certificate would need to change before that, the state fails instead of rotating it. Set allow_premature_rotation: true to opt-in for stateful management of all parameters. When a rotation is triggered by expiry, any pending parameter changes are applied to the new certificate as well.

Important

Issuer configuration changes are always applied, even if the state refuses to rotate and fails. Reported certificate changes are only materialized when the state does not fail.

You need to prune keys and issuers manually, they are never deleted by this state.

Hint

When an issuer is rotated, the old one is kept with slightly adjusted configuration:

  1. If issuer_name is specified and matches the old one, it receives the current timestamp as a suffix, separated by a dash (<issuer_name>-<timestamp>).

  2. issuing-certificates is removed from its usages.

Other issuers on the mount, e.g. manually cross-signed variants of the managed one, are ignored by this state and can coexist safely, as long as they are not assigned its issuer_name.

Required policy:

# Read default issuer to check for necessary changes
path "<mount>/issuer/default" {
    capabilities = ["read"]
}

# When key_ref is not set, need to generate a key
path "<mount>/keys/generate/<key_type>" {
    capabilities = ["create", "update"]
}

# When key_ref is set, need to resolve names to ids
path "<mount>/keys" {
    capabilities = ["list"]
}

# Generate the root issuer certificate using a separately managed key,
# hence the key type is always `existing` here
path "<mount>/root/generate/existing" {
    capabilities = ["create", "update"]
}

# Set default issuer
path "<mount>/config/issuers" {
    capabilities = ["create", "update"]
}

# Update issuer configuration. Might also be exercised when
# no issuer params are specified for config recovery after rotation.
path "<mount>/issuer/<issuer_id>" {
    capabilities = ["patch"]
}

# Read mount default urls to account for cert extensions.
# Note: Failure to read this or URL drift does not cause rotation, only a note.
path "<mount>/config/urls" {
    capabilities = ["read"]
}

# When URLs use templating with `{{cluster_path}}`/`{{cluster_aia_path}}` variables,
# but not `{{issuer_id}}` (URLs are always excluded from the issuer certificate in that case)
# Note: Failure to read this or URL drift does not cause rotation, only a note.
path "<mount>/config/cluster" {
    capabilities = ["read"]
}

Certificate/Key configuration:

name

Common name (CN) of the certificate subject.

days_remaining

Attempt to recreate the certificate if its remaining validity falls below this number of days. Defaults to 365.

Hint

This value should exceed the maximum validity of certificates issued by this CA (including intermediate ones), otherwise issuance close to its expiry can fail or yield certificates outliving it.

allow_premature_rotation

Always rotate the root issuer certificate when it does not meet its specification, even when it is not nearing its expiration date as defined by days_remaining. Defaults to false, meaning this state fails instead of rotating the issuer and indicates necessary changes in the changes dict.

key_ref

Instead of managing the key, use the one associated with this key ID/name. When specified, disables key generation/rotation.

rotate_key

When rotating the default issuer, rotate its key along with it. Defaults to false. Not respected when key_ref is specified.

Important

Rotating the key is a hard cutover. A new root issuer key means nothing issued under the new root validates for clients that only trust the old one.

The new root must be distributed to trust stores before dependent reissuance cascades. Consider creating a new mount with a new root issuer instead that you can introduce gradually.

Cross-signed variants of this issuer certify the old key, so they stop bridging anything issued under the new one. They are not re-established by this state, you need to cross-sign the new key manually.

Note

Key parameters are not managed statefully, meaning changes to key_type, key_algo and key_bits are only applied when generating a new key. key_ref changes are applied though.

key_type

Type of key to generate when necessary and key_ref is not specified. Either internal, exported or kms. Defaults to internal.

key_algo

Key algorithm. Either rsa, ed25519 or ec. Defaults to rsa.

key_bits

Number of bits to use for the generated keys. Valid values depend on the key_algo.

  • rsa: 2048 (default), 3072, 4096, 8192.

  • ec: 224, 256 (default), 384, 521

  • ed25519: ignored

Defaults to 0 (universal default).

managed_key_name

When key_type is kms, the managed key’s configured name. Either this or managed_key_id is required then.

managed_key_id

When key_type is kms, the managed key’s UUID. Either this or managed_key_name is required then.

signature_bits

Number of bits to use in the signature algorithm. Valid: 256 (SHA-2-256), 384 (SHA-2-384), 512 (SHA-2-512). Defaults to 0, which automatically selects an algorithm based on key_algo and key_bits of the issuer’s private key.

days_valid

Number of days the certificate should be valid for when (re-)issued. Not respected when not_after is set explicitly. Defaults to 3650 (10 years).

Hint

Translated into not_after, hence not subject to the mount’s max_lease_ttl.

not_before_duration

Duration by which to backdate the NotBefore property. Defaults to 30s.

not_after

Absolute value of the Not After field of the certificate in UTC format YYYY-MM-ddTHH:MM:SSZ. When set, days_valid is ignored. days_remaining is still validated, but falling below it causes state failure instead of a reissuance.

alt_names

Any alternative names to add to the certificate. Can be specified either as dict ({ "<type>": "<value>" }), a dict of lists ({ "<type>": ["<value1>", "<value2>", ...] }) or list of SAN strings (["<type1>:<value1>", ...]).

<type> can be dns, email, uri, ip or any OID for otherName SANs. <value> is the corresponding value. Note that otherName SANs need to omit UTF8:.

max_path_length

basicConstraints pathlen parameter, which indicates the maximum number of CAs that can appear below this one in a chain. If set to 0, this CA can only issue leaf certificates, not other CAs. A negative value means no limit. Defaults to -1.

key_usage

(Requires Vault 1.20+ or OpenBao) List of key usages to add to the existing set of key usages (CRLSign,CertSign). Per the CAB Forum requirements, Vault ignores values other than DigitalSignature.

exclude_cn_from_sans

If set to true, the Common Name is not added to the SANs. Useful if the CN is not a hostname or email address.

permitted_alt_names

List of alternative names for which certificates are allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip.

Important

Types other than dns require Vault 1.19+.

excluded_alt_names

(Vault 1.19+ only) List of alternative names for which certificates are not allowed to be issued or signed by this CA certificate. The format is similar to the one for alt_names, but <type> can only be dns, email, uri and ip.

Subject DN fields

Most of these can be single strings or lists of strings (for multiple values).

  • ou

  • organization

  • country

  • locality

  • province

  • street_address

  • postal_code

  • serial_number (only a single value; NOT the certificate’s serial number, just the SERIALNUMBER name attribute)

Issuer configuration:

Note

Unspecified parameters are ignored during management and retain their current values in most cases.

This state tries to recover them after rotating an issuer certificate, which would otherwise reset them to their defaults if they were configured manually. This does not apply to issuer_name, which requires special handling, and manual_chain, which is not handled in this state. When the key changes (different key_ref or rotate_key), this also does not apply to revocation_signature_algorithm because a key algorithm change can make the previous value invalid.

issuer_name

Custom name for the issuer. Must be unique and not equal to default.

Important

Never assign this name to issuers managed outside of this state (e.g. cross-signed variants). A conflicting issuer might be renamed under specific circumstances; in all other cases, this state fails.

leaf_not_after_behavior

Behavior of a leaf’s NotAfter field during issuance when it exceeds the issuer’s validity. Valid options:

  • err: Error, unless during CA/ACME issuance. (default)

  • always_enforce_err: Error, including during CA/ACME issuance. (Vault 1.18.2+ only)

  • truncate: Silently truncate the requested NotAfter to that of the issuer.

  • permit: Allow signed certificate validities to exceed that of the issuer.

usage

Allowed usages for this issuer. Valid options are:

  • read-only - to allow this issuer to be read; implicit; always allowed;

  • issuing-certificates - to allow this issuer to be used for issuing other certificates;

  • crl-signing - to allow this issuer to be used for signing CRLs. This is separate from the CRLSign KeyUsage on the x509 certificate, but this usage cannot be set unless that KeyUsage is allowed on the x509 certificate;

  • ocsp-signing - to allow this issuer to be used for signing OCSP responses.

revocation_signature_algorithm

Which signature algorithm to use when building CRLs. See Go’s x509.SignatureAlgorithm constant for possible values. Default (empty string) is to autoselect.

aia_urls

Specifies the URL values for the Issuing Certificate field as an array.

crl_endpoints

Specifies the URL values for the CRL Distribution Points field as an array.

delta_crl_endpoints

(Requires Vault 1.20+ or OpenBao) Specifies the URL values for the Delta CRL Distribution Points field. This can be an array or a comma-separated string list.

ocsp_servers

Specifies the URL values for the OCSP Servers field as an array.

aia_url_templating

Render aia_urls/crl_endpoints/ocsp_servers/delta_crl_endpoints as templates. Supported variables: {{issuer_id}}, {{cluster_path}}, {{cluster_aia_path}}.

mount

Mount path the PKI backend is mounted to. Defaults to pki.