If your organization uses Vault as an internal certificate authority (CA) and you want to use certificates signed by Vault CA to enable secure mTLS communication between services within your service mesh, you must create an integration with Vault CA using the Tanzu Service Mesh API.

When your organization uses Vault as an internal CA, it can have one or multiple Vault servers that store a trusted root certificate and one or more intermediate certificates. Vault uses these CA certificates to generate and sign mTLS session certificates that are used for authenticated and encrypted traffic between services within the service mesh.

Every time a service needs an mTLS session certificate for secure communication with other services in the service mesh, the service sends a request to a Vault server from its Vault-connected cluster. Vault generates a certificate, signs it, and sends it back to the cluster. The cluster trusts the certificate because it stores Vault CA's root and intermediate certificates in its trust store. The service then uses the certificate to make mTLS authenticated and encrypted connections to other services.

If you want to use Vault CA for your service mesh, you must create a Vault integration in Tanzu Service Mesh. The integration defines a configuration that points to a Vault server. The Vault CA configuration contains such details as the URL of the Vault server, the endpoint on Vault to use for signing certificates, and the reference to the Vault CA bundle that contains the root certificate and the intermediate certificates.

After you create a Vault CA integration, you need to apply the CA label from the integration to a cluster when you onboard it. During onboarding, the Vault CA configuration is pushed to the services in the cluster, and the root and intermediate certificates are uploaded into the cluster's trust store.

Once the Vault CA configuration is applied to a cluster, the cluster is considered to be connected to the Vault server, and the services can send certificate generation and signing requests to the server. Because the cluster has the Vault CA root and intermediate certificates in its trust store, it trusts mTLS session certificates received from Vault CA.

To create a Vault CA integration through the API, you must make these API calls:

  • Upload the CA bundle containing the Vault server's root and intermediate certificates to Tanzu Service Mesh. This step is optional and you must do it only if you use a self-signed root certificate that is not publicly available.

  • Create an external account to define the Vault CA configuration.

  • Create a certificate authority (CA) integration to generate the Vault CA label.

The following procedure describes how to make these API calls.

Prerequisites

  • Get an API token and an access code to authenticate your requests to theTanzu Service Mesh API. You must use the access code in the csp-auth-token header in your requests. For information about generating an API token and getting an access code, see Authentication with the Tanzu Service Mesh REST API.

  • Configure Vault to trust connections from your Kubernetes clusters. For detailed information about the configuration steps to perform on Vault, see step 1 in Create a Vault CA Integration Account.

Procedure

  1. (Optional) To upload the Vault server's CA bundle to Tanzu Service Mesh, submit the following request.

    You must make this API call only if you use a self-signed root certificate on Vault that is not publicly available.

    PUT https://{server_name}/tsm/v1alpha2/projects/default/certificates/{id}

    Where {server_name} is the host name of the Tanzu Service Mesh server (for example, prod-1.nsxservicemesh.vmware.com), and {id} is the identifier of the certificate.

    Request Body

    {
      "name": "CA_bundle_name",
      "description": "",
      "certificateType": "CertificateAuthorityBundle",
      "certificateAuthorityBundle": {
        "cert_chain": "content_of_CA_bundle_file"
      }
    }
    Table 1. Request Body Properties

    Property

    Data type

    Required/Optional

    Description

    name

    String

    Required

    Name of the CA bundle in Tanzu Service Mesh.

    description

    String

    Required

    Description of the CA bundle.

    certificateType

    String

    Required

    Certificate type. Set this field to CertificateAuthorityBundle.

    certificateAuthorityBundle

    Object

    Optional

    Container object holding the content of the CA bundle

    cert_chain

    String

    Optional

    The content of the CA bundle file.

    Important:

    Make sure that the value of cert_chain is a single string. To generate a single string from the content of the CA Bundle (.pem) file, you can use the following command:

    awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' cert.pem

    Example of request body

    {
      "name": "my-CA-bundle",
      "description": "",
      "certificateType": "CertificateAuthorityBundle",
      "certificateAuthorityBundle": {
        "cert_chain": "-----BEGIN CERTIFICATE-----    \nMIIDSzCCAjOgAwIBAgIIOyfLeigPwDIwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE\nAxMVbWluaWNhIHJvb3QgY2EgM2IyN2NiMCAXDTIzMDMyNTEyMjQ1NloYDzIxMjMw\nMzI1MTIyNDU2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAzYjI3Y2IwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkn6FrEl/7XfEYxKDK78lJTdW7\nhMQiW/65cx92FbjXHfpBTJ7wows7hMfNfRoDdxtfby04It6gzFfKJfL+u/Y0SQbV\nWWrTEPTrbJ5B3JyTv6IJ4IujvTLG29dMU5oiW/i4wDuNO4S1RYoevAdBZz4zTXiP\nCSn4XNqC/LUd54KKnoQ1Pc3HKxgSbcwb9sJxEhr+dx++n9jaPxOKiczoIdgn3KkC\nLLGePbmDZx/TX8QvLdyXxtzdSRsQ8q8OLs4BiE83Dut3fibxGZPQcgIICNDf+NhE\nkGIgBh4nhKs+LTR5XRXYcd675XONAn3ifgcQKILE/urTSkETdZfaxEzvo5EhAgMB\nAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\nBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRY4vMgDhoBtwzT\nAQZYIIiOOL8YrzAfBgNVHSMEGDAWgBRY4vMgDhoBtwzTAQZYIIiOOL8YrzANBgkq\nhkiG9w0BAQsFAAOCAQEAALhcM1JumeJKQKrJ9D3dDh3Snr96E/0+k1OQd1f4cH5U\n1R4DeqN22wQYIBlg4RVGkBbniG2VVP/7Lxwf0Qpb0Ij3oPzoiFGoYRHK9iKUQaXn\nG2+FpaQW68DT1U1Eyv9GKNN/xyOT7sWuRGXYu7ydbYlB6WC9BGviy6tM38cz8Tuk\nePVOe0Q5Igo5eFuxEMzCx2yBNUJ4g/pdvjTW1qolodR/8XIjx8b11i6kgwpfjiLS\n2gbG43rXF8qwffdXnIUKx7GTqhPinKc13Cpa8JY6i+8GF6YCZqBRjQm314UV8aVj\nB9RrXXFZIUt99j++j31lj9gP0Hm1iSqoP8qyPpWrUw==\n-----END CERTIFICATE-----\n"
      }
    }
  2. To create an external account, submit the following request.
    PUT https://{server_name}/tsm/v1alpha1/external-accounts/{id}

    Where {id} is the identifier of the external account.

    {
      "name": "account_name",
      "description": "account_description",
      "provider": "VAULT",
      "provider_url": "server_url:port",
      "authentication_type": "VAULT_CREDENTIALS",
      "authentication": {
        "auth_vault": {
          "type": "K8S_SERVICE_ACCOUNT",
          "service_account_name": "service_account_name",
          "role_name": "role_name",
          "mount_path" : "/v1/auth/path",
          "namespace": "Vault_namespace_name"
        }
      },
      "certificate_id": "id"
    }

    Property

    Data type

    Required/Optional

    Description

    name

    String

    Required

    The name of the external account.

    description

    String

    Optional

    Description of the external account.

    provider

    String

    Required

    External provider name. Set this field to VAULT.

    provider_url

    String

    Optional

    The URL of the Vault server and the port on which it is accessible.

    authentication_type

    String

    Required

    Type of authentication to use when authenticating to the external provider. Set this field to VAULT_CREDENTIALS.

    authentication

    Object

    Optional

    Container object for the Vault authentication configuration details

    auth_vault

    Nested object

    Optional

    Holds the configuration that is used to authenticate to Vault.

    auth_vault.type

    String

    Required

    Method of Vault authentication. Set this field to K8S_SERVICE_ACCOUNT.

    auth_vault.service_account_name

    String

    Required

    The name of the Kubernetes service account to use for authentication to the Vault server. When sending requests to the Vault server, services will authenticate as the specified service account.

    auth_vault.role_name

    String

    Required

    The name of the Vault role. The role is used to associate the Kubernetes service account with the set of Vault policies specified in the role configuration.

    This value must be the name of the role that you created in Vault (see step 1 g in Create a Vault CA Integration Account).

    auth_vault.mount_path

    String

    Optional

    The Vault mount path to use when authenticating with Vault. If you specified the cluster name as the value of path when enabling the Kubernetes authentication method in Vault (see step 1 e in Create a Vault CA Integration Account), provide the mount path in the format /v1/auth/my_cluster_name. You can leave mount_path empty. In that case, the default mount path of /v1/auth/kubernetes will be used.

    auth_vault.namespace

    String

    Optional

    The namespace to use in Vault. Provide this value only if you use Vault Enterprise.

    certificate_id

    String

    Optional

    Reference to the ID of the CA bundle uploaded in step 1. You must reference the ID of the CA bundle if you use a self-signed root certificate that is not publicly available.

    Example of request body

    {
      "name": "my-vault-account",
      "description": "my vault ca account",
      "provider": "VAULT",
      "provider_url": "https://my-vault-server-22608bc3.4514f36d.z1.hashicorp.cloud:8200",
      "authentication_type": "VAULT_CREDENTIALS",
      "authentication": {
        "auth_vault": {
          "type": "K8S_SERVICE_ACCOUNT",
          "service_account_name": "vault-issuer",
          "role_name": "pki_int",
          "mount_path" : "/v1/auth/tenant-02",
          "namespace": "admin"
        }
      },
      "certificate_id": "my-CA-bundle"
    }
  3. To create a CA configuration, submit the following request.
    PUT https://{server_name}/tsm/v1alpha2/projects/default/certificate-authorities/{id}

    Where {id} is the identifier of the CA configuration.

    {
      "name": "configuration_name",
      "description": "description",
      "accountId": "external_account_id",
      "labels": [
        {
          "key": "CertificateAuthority",
          "value": "CA_label"
        }
      ],
      "vault": {
        "path": "path"
      }
    }

    Property

    Data type

    Required/Optional

    Description

    name

    String

    Required

    The name of the CA configuration.

    description

    String

    Optional

    Description of the configuration.

    accountId

    String

    Required

    The ID of the external account that you created in step 2.

    labels

    Object

    Required

    Container object for the CA label.

    labels.key

    String

    Required

    CA label key. Set this field to CertificateAuthority.

    labels.value

    String

    Required

    The CA label with which you want to associate this Vault CA configuration.

    Note:

    Take a note of the CA label so that you can apply it to clusters when you onboard them.

    vault

    Object

    Required

    Container object for holding the Vault path used for signing certificates.

    vault.path

    String

    Required

    The Vault path to use for signing certificates. This path must use the sign endpoint.

    This must be the same path you specified in the vault secrets enable command when creating a PKI secrets engine (see step 1 b in Create a Vault CA Integration Account). See an example of path below.

    Example of request body

    {
      "name": "my-vault-ca-configuration",
      "description": "My Vault CA configuration",
      "accountId": "my-vault-account",
      "labels": [
        {
          "key": "CertificateAuthority",
          "value": "my-ca-label"
        }
      ],
      "vault": {
        "path": "pki_int/sign/example-dot-com"
      }
    }

What to do next

To apply the Vault CA configuration from the Vault integration to a cluster during onboarding, provide the CA label as the value of caLabels[].value in the API call to onboard the cluster.

You can change the Vault CA integration for a cluster. We recommend changing the CA integration for a cluster only if the change will not cause that cluster and the other clusters in the global namespace to use different roots of trust. The use of different roots of trust in the global namespace will cause cross-cluster connectivity problems.