From b84c07e6413163a5b9ca97636139cb92c9e74df8 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Fri, 25 Aug 2023 09:52:08 +0000 Subject: [PATCH 1/7] backport of commit bc79b0a235af21a9747e05a05c8655748be7ee42 --- charts/consul/templates/server-config-configmap.yaml | 1 + charts/consul/values.yaml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 6c102f0ae3..4630040bd3 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -72,6 +72,7 @@ data: "ca_file": "/consul/vault-ca/tls.crt", {{- end }} "intermediate_pki_path": "{{ .connectCA.intermediatePKIPath }}", + "namespace": "{{ .namespace }}", "root_pki_path": "{{ .connectCA.rootPKIPath }}", "auth_method": { "type": "kubernetes", diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index ec6a1ce720..3eede8d010 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -114,6 +114,10 @@ global: # secretKey should be in the form of "key". secretsBackend: vault: + + # Vault namespace + namespace: root + # Enabling the Vault secrets backend will replace Kubernetes secrets with referenced Vault secrets. enabled: false From 794fd7d5b60deb92e87d00695bc702651d2ede3d Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 28 Aug 2023 15:58:39 +0000 Subject: [PATCH 2/7] backport of commit 3ee878c6a3867193b9559b27ca22a514d14f51ef --- charts/consul/templates/server-config-configmap.yaml | 4 +++- charts/consul/values.yaml | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 4630040bd3..b825c47447 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -72,7 +72,9 @@ data: "ca_file": "/consul/vault-ca/tls.crt", {{- end }} "intermediate_pki_path": "{{ .connectCA.intermediatePKIPath }}", - "namespace": "{{ .namespace }}", + {{- if .connectCA.namespace }} + "namespace": "{{ .connectCA.namespace }}", + {{- end }} "root_pki_path": "{{ .connectCA.rootPKIPath }}", "auth_method": { "type": "kubernetes", diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 3eede8d010..4bac09d2f9 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -115,9 +115,6 @@ global: secretsBackend: vault: - # Vault namespace - namespace: root - # Enabling the Vault secrets backend will replace Kubernetes secrets with referenced Vault secrets. enabled: false @@ -209,6 +206,9 @@ global: # Please refer to [Vault ACL policies](https://developer.hashicorp.com/consul/docs/connect/ca/vault#vault-acl-policies) # documentation for information on how to configure the Vault policies. connectCA: + # Vault namespace + namespace: "" + # The address of the Vault server. address: "" From 37b91d9094e93fa025c5e5a1b366e4b178bee626 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Tue, 29 Aug 2023 08:07:55 +0000 Subject: [PATCH 3/7] backport of commit 10ec942ff1902a73222d47b09695d3836d79af68 --- .../tests/vault/vault_namespaces_test.go | 268 +++++++++++++++++- .../test/unit/server-config-configmap.bats | 37 +++ 2 files changed, 303 insertions(+), 2 deletions(-) diff --git a/acceptance/tests/vault/vault_namespaces_test.go b/acceptance/tests/vault/vault_namespaces_test.go index 4a9ca092d0..6d6c18fa65 100644 --- a/acceptance/tests/vault/vault_namespaces_test.go +++ b/acceptance/tests/vault/vault_namespaces_test.go @@ -20,10 +20,274 @@ import ( "github.com/stretchr/testify/require" ) +// TestVault_VaultNamespace_AdditionalConfig installs Vault, configures a Vault namespace, and then bootstraps it +// with secrets, policies, and Kube Auth Method. +// It then configures Consul to use vault as the backend and checks that it works +// with the vault namespace. Namespace is added in this via global.secretsBackend.vault.connectCA.additionalConfig +func TestVault_VaultNamespace_AdditionalConfig(t *testing.T) { + cfg := suite.Config() + ctx := suite.Environment().DefaultContext(t) + ns := ctx.KubectlOptions(t).Namespace + + ver, err := version.NewVersion("1.12.0") + require.NoError(t, err) + if cfg.ConsulVersion != nil && cfg.ConsulVersion.LessThan(ver) { + t.Skipf("skipping this test because vault secrets backend is not supported in version %v", cfg.ConsulVersion.String()) + } + + vaultNamespacePath := "test-namespace" + consulReleaseName := helpers.RandomName() + vaultReleaseName := helpers.RandomName() + + k8sClient := environment.KubernetesClientFromOptions(t, ctx.KubectlOptions(t)) + vaultLicenseSecretName := fmt.Sprintf("%s-enterprise-license", vaultReleaseName) + vaultLicenseSecretKey := "license" + + vaultEnterpriseLicense := os.Getenv("VAULT_LICENSE") + + logger.Log(t, "Creating secret for Vault license") + consul.CreateK8sSecret(t, k8sClient, cfg, ns, vaultLicenseSecretName, vaultLicenseSecretKey, vaultEnterpriseLicense) + vaultHelmvalues := map[string]string{ + "server.image.repository": "docker.mirror.hashicorp.services/hashicorp/vault-enterprise", + "server.image.tag": "1.9.4-ent", + "server.enterpriseLicense.secretName": vaultLicenseSecretName, + "server.enterpriseLicense.secretKey": vaultLicenseSecretKey, + } + vaultCluster := vault.NewVaultCluster(t, ctx, cfg, vaultReleaseName, vaultHelmvalues) + vaultCluster.Create(t, ctx, vaultNamespacePath) + // Vault is now installed in the cluster. + + // Now fetch the Vault client so we can create the policies and secrets. + vaultClient := vaultCluster.VaultClient(t) + + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) + + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + MaxTTL: "1h", + AuthMethodPath: "kubernetes", + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } + if cfg.EnableEnterprise { + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + } + + //Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // ------------------------- + // Additional Auth Roles + // ------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) + if cfg.EnableEnterprise { + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) + } + + // server + consulServerRole := "server" + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: manageSystemACLsRole, + PolicyNames: bootstrapTokenSecret.PolicyName, + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + vaultCASecret := vault.CASecretName(vaultReleaseName) + + consulHelmValues := map[string]string{ + "server.extraVolumes[0].type": "secret", + "server.extraVolumes[0].name": vaultCASecret, + "server.extraVolumes[0].load": "false", + + "connectInject.enabled": "true", + "connectInject.replicas": "1", + + "global.secretsBackend.vault.enabled": "true", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, + + "global.secretsBackend.vault.ca.secretName": vaultCASecret, + "global.secretsBackend.vault.ca.secretKey": "tls.crt", + + "global.secretsBackend.vault.connectCA.address": vaultCluster.Address(), + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, + "global.secretsBackend.vault.connectCA.additionalConfig": fmt.Sprintf(`"{\"connect\": [{ \"ca_config\": [{ \"namespace\": \"%s\"}]}]}"`, vaultNamespacePath), + + "global.secretsBackend.vault.agentAnnotations": fmt.Sprintf("\"vault.hashicorp.com/namespace\": \"%s\"", vaultNamespacePath), + + "global.acls.manageSystemACLs": "true", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, + "global.tls.enabled": "true", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, + + "ingressGateways.enabled": "true", + "ingressGateways.defaults.replicas": "1", + "terminatingGateways.enabled": "true", + "terminatingGateways.defaults.replicas": "1", + + "server.serverCert.secretName": serverPKIConfig.CertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, + "global.tls.enableAutoEncrypt": "true", + + // For sync catalog, it is sufficient to check that the deployment is running and ready + // because we only care that get-auto-encrypt-client-ca init container was able + // to talk to the Consul server using the CA from Vault. For this reason, + // we don't need any services to be synced in either direction. + "syncCatalog.enabled": "true", + "syncCatalog.toConsul": "false", + "syncCatalog.toK8S": "false", + } + + if cfg.EnableEnterprise { + consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key + } + + logger.Log(t, "Installing Consul") + consulCluster := consul.NewHelmCluster(t, consulHelmValues, ctx, cfg, consulReleaseName) + consulCluster.Create(t) + + // Validate that the gossip encryption key is set correctly. + logger.Log(t, "Validating the gossip key has been set correctly.") + consulCluster.ACLToken = bootstrapToken + consulClient, _ := consulCluster.SetupConsulClient(t, true) + keys, err := consulClient.Operator().KeyringList(nil) + require.NoError(t, err) + // There are two identical keys for LAN and WAN since there is only 1 dc. + require.Len(t, keys, 2) + require.Equal(t, 1, keys[0].PrimaryKeys[gossipKey]) + + // Confirm that the Vault Connect CA has been bootstrapped correctly. + caConfig, _, err := consulClient.Connect().CAGetConfig(nil) + require.NoError(t, err) + require.Equal(t, caConfig.Provider, "vault") + + // Validate that consul sever is running correctly and the consul members command works + logger.Log(t, "Confirming that we can run Consul commands when exec'ing into server container") + membersOutput, err := k8s.RunKubectlAndGetOutputWithLoggerE(t, ctx.KubectlOptions(t), terratestLogger.Discard, "exec", fmt.Sprintf("%s-consul-server-0", consulReleaseName), "-c", "consul", "--", "sh", "-c", fmt.Sprintf("CONSUL_HTTP_TOKEN=%s consul members", bootstrapToken)) + logger.Logf(t, "Members: \n%s", membersOutput) + require.NoError(t, err) + require.Contains(t, membersOutput, fmt.Sprintf("%s-consul-server-0", consulReleaseName)) + + if cfg.EnableEnterprise { + // Validate that the enterprise license is set correctly. + logger.Log(t, "Validating the enterprise license has been set correctly.") + license, licenseErr := consulClient.Operator().LicenseGet(nil) + require.NoError(t, licenseErr) + require.True(t, license.Valid) + } + + // Deploy two services and check that they can talk to each other. + logger.Log(t, "creating static-server and static-client deployments") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + } else { + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + } + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") + }) + k8s.KubectlApplyK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") + + logger.Log(t, "checking that connection is successful") + if cfg.EnableTransparentProxy { + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") + } else { + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") + } +} + // TestVault_VaultNamespace installs Vault, configures a Vault namespace, and then bootstraps it // with secrets, policies, and Kube Auth Method. // It then configures Consul to use vault as the backend and checks that it works -// with the vault namespace. +// with the vault namespace. Namespace is added in this via global.secretsBackend.vault.connectCA.namespace func TestVault_VaultNamespace(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) @@ -195,7 +459,7 @@ func TestVault_VaultNamespace(t *testing.T) { "global.secretsBackend.vault.connectCA.address": vaultCluster.Address(), "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, - "global.secretsBackend.vault.connectCA.additionalConfig": fmt.Sprintf(`"{\"connect\": [{ \"ca_config\": [{ \"namespace\": \"%s\"}]}]}"`, vaultNamespacePath), + "global.secretsBackend.vault.connectCA.namespace": vaultNamespacePath, "global.secretsBackend.vault.agentAnnotations": fmt.Sprintf("\"vault.hashicorp.com/namespace\": \"%s\"", vaultNamespacePath), diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 52a5c4d4c1..639bce5adf 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -658,6 +658,43 @@ load _helpers [ "${actual}" = "true" ] } +@test "server/ConfigMap: doesn't set Vault Namespace in connect CA config when connectCA.namespace is blank in values.yaml" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("namespace")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: set Vault Namespace in connect CA config when connectCA.namespace is blank in values.yaml" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + --set 'global.secretsBackend.vault.connectCA.namespace=vault-namespace' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("\"namespace\": \"vault-namespace\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + @test "server/ConfigMap: doesn't add federation config when global.federation.enabled is false (default)" { cd `chart_dir` local actual=$(helm template \ From 285d7a08a2e2b214ff23be0c940375ffe45f2146 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Tue, 29 Aug 2023 08:18:03 +0000 Subject: [PATCH 4/7] backport of commit 9935a1b6fda54895e90d05386829b4cc279a8f1b --- charts/consul/test/unit/server-config-configmap.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 639bce5adf..01723b1754 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -676,7 +676,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "server/ConfigMap: set Vault Namespace in connect CA config when connectCA.namespace is blank in values.yaml" { +@test "server/ConfigMap: set Vault Namespace in connect CA config when connectCA.namespace is not blank in values.yaml" { cd `chart_dir` local actual=$(helm template \ From 966648f54c8ae4c212f3b29466fa3811308db32b Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Tue, 29 Aug 2023 08:57:09 +0000 Subject: [PATCH 5/7] backport of commit 4097b48e6757d3c2c8e9818c7e5ec2b0d286527a --- .changelog/2841.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/2841.txt diff --git a/.changelog/2841.txt b/.changelog/2841.txt new file mode 100644 index 0000000000..b42584d0de --- /dev/null +++ b/.changelog/2841.txt @@ -0,0 +1,4 @@ +```release-note:improvement +vault: Adds `namespace` in `secretsBackend.vault.connectCA` in `values.yaml` .This namespace is used for Vault namespace, +this introduces one more way to specify namespace other than `"{"connect": [{ "ca_config": [{ "namespace": "value"}]}]}"` in `connectCA.additionalConfig` +``` From e6961f461cd8130fe0d376bd66e283deb8c49151 Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut <134911583+absolutelightning@users.noreply.github.com> Date: Tue, 29 Aug 2023 22:19:25 +0000 Subject: [PATCH 6/7] backport of commit 3f8c4f3e66efa57cabf91aa32604cc941d31b0b4 --- .changelog/2841.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changelog/2841.txt b/.changelog/2841.txt index b42584d0de..73e89860d8 100644 --- a/.changelog/2841.txt +++ b/.changelog/2841.txt @@ -1,4 +1,3 @@ ```release-note:improvement -vault: Adds `namespace` in `secretsBackend.vault.connectCA` in `values.yaml` .This namespace is used for Vault namespace, -this introduces one more way to specify namespace other than `"{"connect": [{ "ca_config": [{ "namespace": "value"}]}]}"` in `connectCA.additionalConfig` +vault: Add `namespace` to `secretsBackend.vault.connectCA` in Helm chart. This provides a more convenient way to specify the Vault namespace than nested JSON in `connectCA.additionalConfig`. ``` From 1d86ccdc9c4f3911cfb5ff65ccff8ec079d85618 Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut <134911583+absolutelightning@users.noreply.github.com> Date: Tue, 29 Aug 2023 22:20:06 +0000 Subject: [PATCH 7/7] backport of commit 5339dd9e5238a37951552613349d73d42246d940 --- charts/consul/values.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 4bac09d2f9..e8f279bb64 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -206,7 +206,8 @@ global: # Please refer to [Vault ACL policies](https://developer.hashicorp.com/consul/docs/connect/ca/vault#vault-acl-policies) # documentation for information on how to configure the Vault policies. connectCA: - # Vault namespace + # Vault namespace (optional). + # For more details, please refer to [Vault Connect CA configuration](https://developer.hashicorp.com/consul/docs/connect/ca/vault#namespace) namespace: "" # The address of the Vault server.