========================
Setting up Vault Issuers
========================

Installing Vault
----------------

Vault installation is a complex subject. For a thorough tour of the subject
you can read the official HashiCorp Vault
`documentation <https://learn.hashicorp.com/vault/getting-started/install>`__.


Vault PKI Backend
-----------------

The PKI Secrets Engine needs to be initialized for cert-manager to be
able to generate certificate. The official Vault documentation can be
found
`here <https://www.vaultproject.io/docs/secrets/pki/index.html>`__.

Vault Authentication with a AppRole
===================================

This Vault authentication method uses a
`Vault AppRole <https://www.vaultproject.io/docs/auth/approle.html>`__.

The secret ID of the AppRole is stored in a secret.

Here an example of a secret containing the secretId of the AppRole:

.. code-block:: yaml

    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: cert-manager-vault-approle
      namespace: default
    data:
      secretId: "MDI..."

Where the secretId is the base 64 encoded value of the appRole *secretId*
giving access to the pki backend in Vault.

We can now create a cluster issuer referencing this secret:

.. code-block:: yaml

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Issuer
    metadata:
      name: vault-issuer
      namespace: default
    spec:
      vault:
        path: pki_int/sign/example-dot-com
        server: https://vault
        caBundle: <base64 encoded caBundle PEM file>
        auth:
          appRole:
            path: approle
            roleId: "291b9d21-8ff5-..."
            secretRef:
              name: cert-manager-vault-approle
              key: secretId

Where *path* is the Vault role path of the PKI backend and *server* is
the Vault server base URL. The *path* MUST USE the vault ``sign`` endpoint.
The Vault appRole credentials are supplied as the
Vault authentication method using the appRole created in Vault. The secretRef
references the Kubernetes secret created previously. More specifically, the field
*name* is the Kubernetes secret name and *key* is the name given as the
key value that store the *secretId*. The optional attribute *path* specifies
where the AppRole authentication is mounted in Vault. The attribute *path* default
value is *approle*.

An optional base64 encoded *caBundle* in PEM format can be provided to validate
the TLS connection to the Vault Server. When *caBundle* is set it replaces the CA
bundle inside the container running cert-manager.
This parameter has no effect if the connection used is in plain HTTP.

Once we have created the above Issuer we can use it to obtain a certificate.

.. code-block:: yaml

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Certificate
    metadata:
      name: example-com
      namespace: default
    spec:
      secretName: example-com-tls
      issuerRef:
        name: vault-issuer
      commonName: example.com
      dnsNames:
      - www.example.com

The Certificate resource describes our desired certificate and the possible
methods that can be used to obtain it. You can learn more about the Certificate
resource in the :doc:`reference docs </reference/certificates>`.
If the certificate is obtained successfully, the resulting key pair will be
stored in a secret called ``example-com-tls`` in the same namespace as the Certificate.

The certificate will have a common name of ``example.com`` and the
`Subject Alternative Names`_ (SANs) will be ``example.com`` and ``www.example.com``.

In our Certificate we have referenced the ``vault-issuer`` Issuer above.
The Issuer must be in the same namespace as the Certificate.
If you want to reference a ClusterIssuer, which is a cluster-scoped version of
an Issuer, you must add ``kind: ClusterIssuer`` to the ``issuerRef`` stanza.

For more information on ClusterIssuers, read the
:doc:`ClusterIssuer reference docs </reference/clusterissuers>`.

Vault Authentication with a Token
=================================

This Vault authentication method uses a plain token. A Vault token is generated by
one of the many authentication backends supported by Vault. Tokens in Vault have
expiration and need to be refreshed.  You need to be aware that cert-manager does not
refresh these tokens. Another process must be put in place to keep them from expiring.

For testing purposes a root token is generated at Vault installation time.
**WARNING: Root tokens do not expire, so should only be used for testing purposes.**

Please refer to the official token `documentation <https://www.vaultproject.io/docs/concepts/tokens.html>`__
for all the details.

Here an example of a secret Kubernetes resource containing the Vault token:

.. code-block:: yaml

    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: cert-manager-vault-token
      namespace: kube-system
    data:
      token: "MjI..."

Where the token value is the base 64 encoded value of the token giving
access to the PKI backend in Vault.

We can now create an issuer referencing this secret:

.. code-block:: yaml

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Issuer
    metadata:
      name: vault-issuer
      namespace: default
    spec:
      vault:
        auth:
          tokenSecretRef:
            name: cert-manager-vault-token
            key: token
        path: pki_int/sign/example-dot-com
        server: https://vault
        caBundle: <base64 encoded caBundle PEM file>

Where *path* is the Vault role path of the PKI backend and *server* is
the Vault server base URL. The secret created previously is referenced in the issuer
with its *name* and *key* corresponding to the name of the Kubernetes secret and the
property name containing the token value respectively.

An optional base64 encoded *caBundle* in PEM format can be provided to validate
the TLS connection to the Vault Server. When *caBundle* is set it replaces the CA
bundle inside the container running cert-manager. This parameter as no effect if the
connection used is in plain HTTP.

Once we have created the above Issuer we can use it to obtain a certificate.

.. code-block:: yaml

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Certificate
    metadata:
      name: example-com
      namespace: default
    spec:
      secretName: example-com-tls
      issuerRef:
        name: vault-issuer
      commonName: example.com
      dnsNames:
      - www.example.com

The Certificate resource describes our desired certificate and the possible
methods that can be used to obtain it. You can learn more about the Certificate
resource in the :doc:`reference docs </reference/certificates>`.
If the certificate is obtained successfully, the resulting key pair will be
stored in a secret called ``example-com-tls`` in the same namespace as the Certificate.

The certificate will have a common name of ``example.com`` and the
`Subject Alternative Names`_ (SANs) will be ``example.com`` and ``www.example.com``.

In our Certificate we have referenced the ``vault-issuer`` Issuer above.
The Issuer must be in the same namespace as the Certificate.
If you want to reference a ClusterIssuer, which is a cluster-scoped version of
an Issuer, you must add ``kind: ClusterIssuer`` to the ``issuerRef`` stanza.

For more information on ClusterIssuers, read the
:doc:`ClusterIssuer reference docs </reference/clusterissuers>`.

.. _`Subject Alternative Names`: https://en.wikipedia.org/wiki/Subject_Alternative_Name
