From ff4db6b66639f275d0af1d5bba7f255f3c52eabe Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:09:50 +0200 Subject: [PATCH 1/6] add VenafiConnection support for NGTS Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- .../charts/venafi-kubernetes-agent/README.md | 5 +- .../jetstack.io_venaficonnections.yaml | 2 +- .../templates/deployment.yaml | 2 +- .../tests/deployment_test.yaml | 68 +++++++++++++++++++ .../values.schema.json | 2 +- .../venafi-kubernetes-agent/values.yaml | 8 ++- go.mod | 10 +-- go.sum | 20 +++--- pkg/agent/config_test.go | 13 ++++ pkg/client/client_oauth.go | 2 +- pkg/client/client_venconn.go | 52 ++++++++++---- pkg/client/client_venconn_test.go | 4 +- 12 files changed, 149 insertions(+), 39 deletions(-) diff --git a/deploy/charts/venafi-kubernetes-agent/README.md b/deploy/charts/venafi-kubernetes-agent/README.md index 232b8d77..f4ff5db5 100644 --- a/deploy/charts/venafi-kubernetes-agent/README.md +++ b/deploy/charts/venafi-kubernetes-agent/README.md @@ -390,7 +390,10 @@ Configure VenafiConnection authentication > false > ``` -When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager using the configuration in a VenafiConnection resource. Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the +When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or +`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and +`spec.vcp.apiKey` are rejected by the agent. +Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the Discovery Agent Pod. #### **authentication.venafiConnection.name** ~ `string` > Default value: diff --git a/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml b/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml index 90cdcb70..9389601d 100644 --- a/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml +++ b/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.20.1 + controller-gen.kubebuilder.io/version: v0.21.0 name: venaficonnections.jetstack.io spec: group: jetstack.io diff --git a/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml b/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml index 24eb99a9..c582d504 100644 --- a/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml +++ b/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml @@ -81,8 +81,8 @@ spec: - {{ .Values.config.clientId | quote }} - "--private-key-path" - "/etc/venafi/agent/key/{{ .Values.authentication.secretKey }}" - {{- end }} - --venafi-cloud + {{- end }} {{- if .Values.metrics.enabled }} - --enable-metrics {{- end }} diff --git a/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml b/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml index f1e27510..9f770ff1 100644 --- a/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml +++ b/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml @@ -133,3 +133,71 @@ tests: - lengthEqual : path: spec.template.spec.containers[0].env count: 4 + + # VenafiConnection mode (used for both VCP and NGTS backends) wires the + # connection name/namespace through as flags and skips mounting the keypair + # Secret. The Secret-based --client-id / --private-key-path flags must not be + # present in this mode. + - it: VenafiConnection mode passes the connection flags and omits the credentials Secret + set: + authentication.venafiConnection.enabled: true + authentication.venafiConnection.name: my-venconn + authentication.venafiConnection.namespace: my-ns + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection + - contains: + path: spec.template.spec.containers[0].args + content: my-venconn + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection-namespace + - contains: + path: spec.template.spec.containers[0].args + content: my-ns + - notContains: + path: spec.template.spec.containers[0].args + content: --client-id + - notContains: + path: spec.template.spec.containers[0].args + content: --private-key-path + - notContains: + path: spec.template.spec.containers[0].args + content: --venafi-cloud + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: credentials + mountPath: /etc/venafi/agent/key + readOnly: true + - notContains: + path: spec.template.spec.volumes + content: + name: credentials + secret: + secretName: agent-credentials + optional: false + + # Keypair mode (the default, used when authentication.venafiConnection.enabled + # is false) still renders --venafi-cloud since the agent's mode-resolution + # treats keypair as a Venafi Cloud backend. + - it: Keypair mode still passes --venafi-cloud + set: + config.clientId: "00000000-0000-0000-0000-000000000000" + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-cloud + - contains: + path: spec.template.spec.containers[0].args + content: --client-id + - contains: + path: spec.template.spec.containers[0].args + content: --private-key-path diff --git a/deploy/charts/venafi-kubernetes-agent/values.schema.json b/deploy/charts/venafi-kubernetes-agent/values.schema.json index 48a04b63..b7fe9506 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.schema.json +++ b/deploy/charts/venafi-kubernetes-agent/values.schema.json @@ -137,7 +137,7 @@ }, "helm-values.authentication.venafiConnection.enabled": { "default": false, - "description": "When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager using the configuration in a VenafiConnection resource. Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", + "description": "When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or\n`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and\n`spec.vcp.apiKey` are rejected by the agent.\nUse `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", "type": "boolean" }, "helm-values.authentication.venafiConnection.name": { diff --git a/deploy/charts/venafi-kubernetes-agent/values.yaml b/deploy/charts/venafi-kubernetes-agent/values.yaml index 92829937..c40c9d4b 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.yaml +++ b/deploy/charts/venafi-kubernetes-agent/values.yaml @@ -238,8 +238,12 @@ authentication: # +docs:section=Venafi Connection # Configure VenafiConnection authentication venafiConnection: - # When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager - # using the configuration in a VenafiConnection resource. + # When set to true, the Discovery Agent will authenticate to its upload + # backend using the configuration in a VenafiConnection resource. The + # backend is determined by the VenafiConnection's spec: use `spec.vcp` for + # CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or + # `url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and + # `spec.vcp.apiKey` are rejected by the agent. # Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). # When set to true, the `authentication.secret` values will be ignored and the # Secret with `authentication.secretName` will _not_ be mounted into the diff --git a/go.mod b/go.mod index ca88f6a0..ccbbd358 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/fatih/color v1.19.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/jetstack/venafi-connection-lib v0.6.0 + github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5 github.com/lestrrat-go/jwx/v3 v3.1.1 github.com/microcosm-cc/bluemonday v1.0.27 github.com/pmylund/go-cache v2.1.0+incompatible @@ -63,7 +63,7 @@ require ( go.opentelemetry.io/otel v1.41.0 // indirect go.opentelemetry.io/otel/trace v1.41.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.1 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.50.0 // indirect @@ -74,8 +74,8 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/ini.v1 v1.67.1 // indirect - k8s.io/apiextensions-apiserver v0.36.0 // indirect - k8s.io/apiserver v0.36.0 // indirect + k8s.io/apiextensions-apiserver v0.36.1 // indirect + k8s.io/apiserver v0.36.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect ) @@ -112,6 +112,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 k8s.io/klog/v2 v2.140.0 k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect - k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect + k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect ) diff --git a/go.sum b/go.sum index 92d9f01c..a13e4c26 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jetstack/venafi-connection-lib v0.6.0 h1:ZVR06xfJdWTKfIjVK3v4oPgc68TZNd9cYZmsi+9prFg= -github.com/jetstack/venafi-connection-lib v0.6.0/go.mod h1:XEjTVju/2ROnUEDQAyAm0Rj7Mk7HJF0/bwmS67KbwQA= +github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5 h1:bF8CfskHNjfxm5dcIhMKBSa+hWvSR0rQEzFxXcj3dBw= +github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5/go.mod h1:KPndhwwPHPkBqv7cocVTtEDPHV/CBrwapLqzUnwbCUs= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -238,8 +238,8 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -293,12 +293,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= +k8s.io/apiextensions-apiserver v0.36.1 h1:6JfYmPUsuUIHuN+3QxutXYWj492RqF5fBSx67GYK5Ks= +k8s.io/apiextensions-apiserver v0.36.1/go.mod h1:pLzZin90riwisdzKwv/GoTwENooytoIx5zWJb4Hkby8= k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA= k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8= -k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE= -k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho= +k8s.io/apiserver v0.36.1 h1:iMS5V+rPUertv5P9RaqJgmHHTuh4quWpoxchvMUY+JY= +k8s.io/apiserver v0.36.1/go.mod h1:Cby1PbLWztu0GDOxoO6iFOyyqIsziHNEW+w9zVQ22Kw= k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0= k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU= k8s.io/component-base v0.36.1 h1:iG6GsELftXqTNG9HG6kiVjatSgAw1sf5pJ6R5a6N0kA= @@ -307,8 +307,8 @@ k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= -k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= diff --git a/pkg/agent/config_test.go b/pkg/agent/config_test.go index 364661c6..c122d979 100644 --- a/pkg/agent/config_test.go +++ b/pkg/agent/config_test.go @@ -645,6 +645,19 @@ func Test_ValidateAndCombineConfig(t *testing.T) { assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) }) + t.Run("venafi-cloud-workload-identity-auth: --venafi-cloud is tolerated alongside --venafi-connection for backwards compatibility with older rendered charts", func(t *testing.T) { + t.Setenv("POD_NAMESPACE", "venafi") + t.Setenv("KUBECONFIG", withFile(t, fakeKubeconfig)) + got, _, err := ValidateAndCombineConfig(discardLogs(), + withConfig(testutil.Undent(` + period: 1h + cluster_name: cluster-1 + `)), + withCmdLineFlags("--venafi-connection", "venafi-components", "--venafi-cloud")) + require.NoError(t, err) + assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) + }) + const arkUsername = "cluster-1-region-1-cloud-1@cyberark.cloud.123456" t.Run("--machine-hub selects MachineHub mode", func(t *testing.T) { diff --git a/pkg/client/client_oauth.go b/pkg/client/client_oauth.go index 5cc1e64f..b7ad93ea 100644 --- a/pkg/client/client_oauth.go +++ b/pkg/client/client_oauth.go @@ -159,8 +159,8 @@ func (c *OAuthClient) post(ctx context.Context, path string, body io.Reader) (*h return nil, err } + req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") - version.SetUserAgent(req) if len(token.bearer) > 0 { diff --git a/pkg/client/client_venconn.go b/pkg/client/client_venconn.go index 9ce0c86b..25869411 100644 --- a/pkg/client/client_venconn.go +++ b/pkg/client/client_venconn.go @@ -13,8 +13,10 @@ import ( "time" venapi "github.com/jetstack/venafi-connection-lib/api/v1alpha1" - "github.com/jetstack/venafi-connection-lib/chain/sources/venafi" + "github.com/jetstack/venafi-connection-lib/connection_details" + "github.com/jetstack/venafi-connection-lib/sources/venafi" "github.com/jetstack/venafi-connection-lib/venafi_client" + "github.com/microcosm-cc/bluemonday" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -137,17 +139,25 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading if err != nil { return fmt.Errorf("while loading the VenafiConnection %s/%s: %w", c.venConnNS, c.venConnName, err) } - if details.TPP != nil { - return fmt.Errorf(`VenafiConnection %s/%s: the agent cannot be used with TPP`, c.venConnNS, c.venConnName) - } - if details.VCP != nil && details.VCP.APIKey != "" { + server := details.ServerDetails() + switch server.BackendAuth { + case connection_details.VCPAccessToken, connection_details.NGTSAccessToken: + // Supported. + case connection_details.TPPAccessToken: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support the TPP backend`, c.venConnNS, c.venConnName) + case connection_details.DistributedIssuerAccessToken: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support the Distributed Issuer backend`, c.venConnNS, c.venConnName) + case connection_details.VCPAPIKey: // Although it is technically possible to use an API key, we have // decided to not allow it as it isn't recommended and will eventually // be phased out. - return fmt.Errorf(`VenafiConnection %s/%s: the agent cannot be used with an API key`, c.venConnNS, c.venConnName) + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support API key authentication with the VCP backend`, c.venConnNS, c.venConnName) + default: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support backend auth %q`, c.venConnNS, c.venConnName, server.BackendAuth) } - if details.VCP == nil || details.VCP.AccessToken == "" { - return fmt.Errorf(`programmer mistake: VenafiConnection %s/%s: TPPAccessToken is empty in the token returned by connHandler.Get: %v`, c.venConnNS, c.venConnName, details) + token := details.Credential() + if token == "" { + return fmt.Errorf(`programmer mistake: VenafiConnection %s/%s: access token is empty in the connection details returned by connHandler.Get`, c.venConnNS, c.venConnName) } payload := api.DataReadingsPost{ @@ -160,9 +170,10 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading return err } + uploadURL := fullURL(server.BaseURL, "/v1/tlspk/upload/clusterdata/no") klog.FromContext(ctx).V(2).Info( "uploading data readings", - "url", fullURL(details.VCP.URL, "/v1/tlspk/upload/clusterdata/no"), + "url", uploadURL, "cluster_name", opts.ClusterName, "data_readings_count", len(readings), "data_size_bytes", len(data), @@ -171,21 +182,32 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading // The path parameter "no" is a dummy parameter to make the Venafi Cloud // backend happy. This parameter, named `uploaderID` in the backend, is not // actually used by the backend. - req, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL(details.VCP.URL, "/v1/tlspk/upload/clusterdata/no"), bytes.NewReader(data)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadURL, bytes.NewReader(data)) if err != nil { return err } + req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", details.VCP.AccessToken)) + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) version.SetUserAgent(req) - q := req.URL.Query() - q.Set("name", opts.ClusterName) + isNGTS := server.BackendAuth == connection_details.NGTSAccessToken + + query := req.URL.Query() + stripHTML := bluemonday.StrictPolicy() + if opts.ClusterName != "" { + query.Add("name", stripHTML.Sanitize(opts.ClusterName)) + } if opts.ClusterDescription != "" { - q.Set("description", base64.RawURLEncoding.EncodeToString([]byte(opts.ClusterDescription))) + query.Add("description", base64.RawURLEncoding.EncodeToString([]byte(stripHTML.Sanitize(opts.ClusterDescription)))) } - req.URL.RawQuery = q.Encode() + if isNGTS && opts.ClaimableCerts { + // The TLSPK backend reads "certOwnership=unassigned" — this is the backend contract. + query.Set("certOwnership", "unassigned") + } + + req.URL.RawQuery = query.Encode() res, err := c.Client.Do(req) if err != nil { diff --git a/pkg/client/client_venconn_test.go b/pkg/client/client_venconn_test.go index 6b9e14a4..93db9e5f 100644 --- a/pkg/client/client_venconn_test.go +++ b/pkg/client/client_venconn_test.go @@ -156,7 +156,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) { // PostDataReadingsWithOptions failed, but Get succeeded; that's why the // condition says the VenafiConnection is ready. expectReadyCondMsg: "Generated a new token", - expectErr: "VenafiConnection error-when-the-apikey-field-is-used/venafi-components: the agent cannot be used with an API key", + expectErr: "VenafiConnection error-when-the-apikey-field-is-used/venafi-components: the agent does not support API key authentication with the VCP backend", })) t.Run("error when the tpp field is used", run_TestVenConnClient_PostDataReadingsWithOptions(ctx, restconf, kclient, testcase{ // IMPORTANT: The user may think they can use 'tpp', spend time @@ -214,7 +214,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) { namespace: venafi `), expectReadyCondMsg: "Generated a new token", - expectErr: "VenafiConnection error-when-the-tpp-field-is-used/venafi-components: the agent cannot be used with TPP", + expectErr: "VenafiConnection error-when-the-tpp-field-is-used/venafi-components: the agent does not support the TPP backend", })) } From d41150ad1d060a4a75ca4d4c56c503f9acd1186a Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:39:44 +0200 Subject: [PATCH 2/6] update config options and comments to explain that VenafiConnection can be used for NGTS too Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- pkg/agent/config.go | 87 ++++++++++++++++++++++++---------------- pkg/agent/config_test.go | 26 ++++++------ 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/pkg/agent/config.go b/pkg/agent/config.go index 45dae0b0..1c8e7335 100644 --- a/pkg/agent/config.go +++ b/pkg/agent/config.go @@ -41,8 +41,9 @@ type Config struct { // Server is the base URL for the Preflight server. It defaults to // https://preflight.jetstack.io in Jetstack Secure OAuth and Jetstack // Secure API Token modes, and https://api.venafi.cloud in Venafi Cloud Key - // Pair Service Account mode. It is ignored in Venafi Cloud VenafiConnection - // mode and in MachineHub mode. + // Pair Service Account mode. It is ignored in VenafiConnection mode (the + // backend URL is taken from the VenafiConnection resource), in NGTS mode + // (use --tsg-id or --ngts-server-url instead) and in MachineHub mode. Server string `yaml:"server"` // OrganizationID is only used in Jetstack Secure OAuth and Jetstack Secure @@ -160,7 +161,9 @@ type AgentCmdFlags struct { APIToken string // VenConnName (--venafi-connection) is the name of the VenafiConnection - // resource to use. Using this flag will enable Venafi Connection mode. + // resource to use. Using this flag will enable VenafiConnection mode. The + // upload backend (Venafi Cloud or NGTS) is selected by the spec of the + // referenced VenafiConnection resource. VenConnName string // VenConnNS (--venafi-connection-namespace) is the namespace of the @@ -183,8 +186,13 @@ type AgentCmdFlags struct { // Prometheus (--enable-metrics) enables the Prometheus metrics server. Prometheus bool - // NGTSMode (--ngts) turns on the NGTS mode. The agent will authenticate - // using key pair authentication and send data to NGTS endpoints. + // NGTSMode (--ngts) turns on the NGTS keypair mode. The agent will + // authenticate to the NGTS endpoint using an NGTS built-in service account + // key pair (--client-id and --private-key-path). + // + // To authenticate to NGTS through a VenafiConnection resource instead, use + // --venafi-connection (without --ngts) and point it at a VenafiConnection + // whose spec selects the NGTS backend. NGTSMode bool // TSGID (--tsg-id) is the TSG (Tenant Service Group) ID for NGTS mode. @@ -291,8 +299,10 @@ func InitAgentCmdFlags(c *cobra.Command, cfg *AgentCmdFlags) { &cfg.VenConnName, "venafi-connection", "", - "Turns on the "+string(VenafiCloudVenafiConnection)+" mode. "+ - "This flag configures the name of the VenafiConnection to be used.", + "Turns on the "+string(VenafiConnection)+" mode. The upload backend (Venafi Cloud "+ + "or NGTS) is selected by the spec of the referenced VenafiConnection "+ + "resource. This flag configures the name of the VenafiConnection to "+ + "be used.", ) c.PersistentFlags().StringVar( &cfg.VenConnNS, @@ -352,9 +362,10 @@ func InitAgentCmdFlags(c *cobra.Command, cfg *AgentCmdFlags) { &cfg.NGTSMode, "ngts", false, - "Enables NGTS mode. The agent will authenticate using key pair authentication and send data to NGTS endpoints. "+ + "Enables NGTS keypair mode. The agent will authenticate to NGTS using an NGTS built-in service account key pair. "+ "Must be used with --private-key-path and exactly one of --tsg-id or --ngts-server-url. "+ - "--client-id is optional if provided in the credentials secret.", + "--client-id is optional if provided in the credentials secret. "+ + "To authenticate to NGTS through a VenafiConnection resource instead, use --venafi-connection without this flag.", ) c.PersistentFlags().StringVar( &cfg.TSGID, @@ -386,13 +397,13 @@ func InitAgentCmdFlags(c *cobra.Command, cfg *AgentCmdFlags) { type OutputMode string const ( - JetstackSecureOAuth OutputMode = "Jetstack Secure OAuth" - JetstackSecureAPIToken OutputMode = "Jetstack Secure API Token" - VenafiCloudKeypair OutputMode = "Venafi Cloud Key Pair Service Account" - VenafiCloudVenafiConnection OutputMode = "Venafi Cloud VenafiConnection" - LocalFile OutputMode = "Local File" - MachineHub OutputMode = "MachineHub" - NGTS OutputMode = "NGTS" + JetstackSecureOAuth OutputMode = "Jetstack Secure OAuth" + JetstackSecureAPIToken OutputMode = "Jetstack Secure API Token" + VenafiCloudKeypair OutputMode = "Venafi Cloud Key Pair Service Account" + VenafiConnection OutputMode = "VenafiConnection" + LocalFile OutputMode = "Local File" + MachineHub OutputMode = "MachineHub" + NGTS OutputMode = "NGTS" ) // The command-line flags and the config file and some environment variables are @@ -411,7 +422,9 @@ type CombinedConfig struct { ClusterID string // Used by JetstackSecureOAuth, JetstackSecureAPIToken, and - // VenafiCloudKeypair. Ignored in VenafiCloudVenafiConnection mode. + // VenafiCloudKeypair. Ignored in VenafiConnection mode (the + // backend URL is taken from the VenafiConnection resource) and in NGTS + // mode (set via --tsg-id or --ngts-server-url instead). Server string // JetstackSecureOAuth and JetstackSecureAPIToken modes only. @@ -434,11 +447,11 @@ type CombinedConfig struct { // false (default) = certs are owned by this cluster's tenant. ClaimableCerts bool - // VenafiCloudVenafiConnection mode only. + // VenafiConnection mode only. VenConnName string VenConnNS string - // VenafiCloudKeypair and VenafiCloudVenafiConnection modes only. + // Applied to all data gatherers regardless of OutputMode. ExcludeAnnotationKeysRegex []*regexp.Regexp ExcludeLabelKeysRegex []*regexp.Regexp @@ -490,7 +503,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) reason = "--client-id and --private-key-path were specified" keysAndValues = []any{"clientID", flags.ClientID, "privateKeyPath", flags.PrivateKeyPath} case flags.VenConnName != "": - mode = VenafiCloudVenafiConnection + mode = VenafiConnection reason = "--venafi-connection was specified" keysAndValues = []any{"venConnName", flags.VenConnName} case flags.APIToken != "": @@ -513,7 +526,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) "To enable one of the output modes, you can:\n" + " - Use --ngts with --private-key-path and exactly one of --tsg-id or --ngts-server-url to use the " + string(NGTS) + " mode (--client-id is optional if provided in the credentials secret).\n" + " - Use (--venafi-cloud with --credentials-file) or (--client-id with --private-key-path) to use the " + string(VenafiCloudKeypair) + " mode.\n" + - " - Use --venafi-connection for the " + string(VenafiCloudVenafiConnection) + " mode.\n" + + " - Use --venafi-connection for the " + string(VenafiConnection) + " mode (the upload backend - Venafi Cloud or NGTS - is selected by the VenafiConnection resource).\n" + " - Use --credentials-file alone if you want to use the " + string(JetstackSecureOAuth) + " mode.\n" + " - Use --api-token if you want to use the " + string(JetstackSecureAPIToken) + " mode.\n" + " - Use --machine-hub if you want to use the " + string(MachineHub) + " mode.\n" + @@ -544,9 +557,13 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) errs = multierror.Append(errs, fmt.Errorf("--machine-hub cannot be used with --ngts. These are mutually exclusive modes.")) } - // Error if VenafiConnection mode flags are used + // Error if VenafiConnection mode flags are used. The --ngts flag + // selects NGTS keypair auth; to authenticate to NGTS through a + // VenafiConnection resource, drop --ngts and use --venafi-connection + // on its own (the agent picks the NGTS backend from the + // VenafiConnection's spec). if flags.VenConnName != "" { - errs = multierror.Append(errs, fmt.Errorf("--venafi-connection cannot be used with --ngts. Use --client-id and --private-key-path instead.")) + errs = multierror.Append(errs, fmt.Errorf("--venafi-connection cannot be used with --ngts. Either drop --ngts to authenticate to NGTS through a VenafiConnection resource, or drop --venafi-connection and use --client-id and --private-key-path for NGTS keypair auth.")) } // Error if Jetstack Secure OAuth mode flags are used @@ -602,12 +619,14 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) case !hasServerField && !hasEndpointField: server = "https://preflight.jetstack.io" if res.OutputMode == VenafiCloudKeypair { - // The VenafiCloudVenafiConnection mode doesn't need a server. + // VenafiConnection mode (VCP or NGTS) takes its server from + // the VenafiConnection resource and doesn't need one here. server = client.VenafiCloudProdURL } if res.OutputMode == NGTS { - // In NGTS mode, use NGTSServerURL if provided, otherwise we'll use a default - // (which will be determined when creating the client) + // In NGTS keypair mode, use NGTSServerURL if provided, otherwise + // we'll use a default (derived from --tsg-id at client construction + // time). server = res.NGTSServerURL } } @@ -633,8 +652,8 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) errs = multierror.Append(errs, fmt.Errorf("server %q is not a valid URL", server)) } - if res.OutputMode == VenafiCloudVenafiConnection && server != "" { - log.Info(fmt.Sprintf("ignoring the server field specified in the config file. In %s mode, this field is not needed.", VenafiCloudVenafiConnection)) + if res.OutputMode == VenafiConnection && server != "" { + log.Info(fmt.Sprintf("ignoring the server field specified in the config file. In %s mode, this field is not needed.", VenafiConnection)) server = "" } @@ -658,7 +677,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) } uploadPath = cfg.VenafiCloud.UploadPath - case VenafiCloudVenafiConnection: + case VenafiConnection: // The venafi-cloud.upload_path was initially meant to let users // configure HTTP proxies, but it has never been used since HTTP // proxies don't rewrite paths. Thus, we've disabled the ability to @@ -706,7 +725,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) } clusterName = cfg.ClusterName // cluster_id and organization_id were already validated to not be present in NGTS mode - case VenafiCloudKeypair, VenafiCloudVenafiConnection: + case VenafiCloudKeypair, VenafiConnection: // For backwards compatibility, use the agent config's `cluster_id` as // ClusterName if `cluster_name` is not set. if cfg.ClusterName == "" && cfg.ClusterID == "" { @@ -795,7 +814,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) var err error installNS, err = getInClusterNamespace() if err != nil { - if res.OutputMode == VenafiCloudVenafiConnection { + if res.OutputMode == VenafiConnection { errs = multierror.Append(errs, fmt.Errorf("could not guess which namespace the agent is running in: %w", err)) } } @@ -804,7 +823,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags) } // Validation of --venafi-connection and --venafi-connection-namespace. - if res.OutputMode == VenafiCloudVenafiConnection { + if res.OutputMode == VenafiConnection { res.VenConnName = flags.VenConnName venConnNS := flags.VenConnNS if flags.VenConnNS == "" { @@ -933,7 +952,7 @@ func validateCredsAndCreateClient(log logr.Logger, flagCredentialsPath, flagClie // arbitrary value. uploaderID := "no" - // We don't do this for the VenafiCloudVenafiConnection mode because + // We don't do this for the VenafiConnection mode because // the upload_path field is ignored in that mode. log.Info("Loading upload_path from \"venafi-cloud\" configuration.") @@ -942,7 +961,7 @@ func validateCredsAndCreateClient(log logr.Logger, flagCredentialsPath, flagClie if err != nil { errs = multierror.Append(errs, err) } - case VenafiCloudVenafiConnection: + case VenafiConnection: var restCfg *rest.Config restCfg, err := kubeconfig.LoadRESTConfig("") if err != nil { diff --git a/pkg/agent/config_test.go b/pkg/agent/config_test.go index c122d979..d4460251 100644 --- a/pkg/agent/config_test.go +++ b/pkg/agent/config_test.go @@ -197,7 +197,7 @@ func Test_ValidateAndCombineConfig(t *testing.T) { no output mode specified. To enable one of the output modes, you can: - Use --ngts with --private-key-path and exactly one of --tsg-id or --ngts-server-url to use the NGTS mode (--client-id is optional if provided in the credentials secret). - Use (--venafi-cloud with --credentials-file) or (--client-id with --private-key-path) to use the Venafi Cloud Key Pair Service Account mode. - - Use --venafi-connection for the Venafi Cloud VenafiConnection mode. + - Use --venafi-connection for the VenafiConnection mode (the upload backend - Venafi Cloud or NGTS - is selected by the VenafiConnection resource). - Use --credentials-file alone if you want to use the Jetstack Secure OAuth mode. - Use --api-token if you want to use the Jetstack Secure API Token mode. - Use --machine-hub if you want to use the MachineHub mode. @@ -585,15 +585,15 @@ func Test_ValidateAndCombineConfig(t *testing.T) { withCmdLineFlags("--venafi-connection", "venafi-components")) require.NoError(t, err) assert.Equal(t, testutil.Undent(` - INFO Output mode selected venConnName="venafi-components" mode="Venafi Cloud VenafiConnection" reason="--venafi-connection was specified" - INFO ignoring the server field specified in the config file. In Venafi Cloud VenafiConnection mode, this field is not needed. + INFO Output mode selected venConnName="venafi-components" mode="VenafiConnection" reason="--venafi-connection was specified" + INFO ignoring the server field specified in the config file. In VenafiConnection mode, this field is not needed. INFO Using cluster_id as cluster_name for backwards compatibility clusterID="legacy cluster_id as cluster name" INFO Using period from config period="1h0m0s" `), gotLogs.String()) assert.Equal(t, CombinedConfig{ Period: 1 * time.Hour, ClusterName: "legacy cluster_id as cluster name", - OutputMode: VenafiCloudVenafiConnection, + OutputMode: VenafiConnection, VenConnName: "venafi-components", VenConnNS: "venafi", InstallNS: "venafi", @@ -620,14 +620,14 @@ func Test_ValidateAndCombineConfig(t *testing.T) { ) require.NoError(t, err) assert.Equal(t, testutil.Undent(` - INFO Output mode selected venConnName="venafi-components" mode="Venafi Cloud VenafiConnection" reason="--venafi-connection was specified" - INFO ignoring the server field specified in the config file. In Venafi Cloud VenafiConnection mode, this field is not needed. - INFO ignoring the venafi-cloud.upload_path field in the config file. In Venafi Cloud VenafiConnection mode, this field is not needed. - INFO ignoring the venafi-cloud.uploader_id field in the config file. This field is not needed in Venafi Cloud VenafiConnection mode. - INFO Ignoring the cluster_id field in the config file. This field is not needed in Venafi Cloud VenafiConnection mode. + INFO Output mode selected venConnName="venafi-components" mode="VenafiConnection" reason="--venafi-connection was specified" + INFO ignoring the server field specified in the config file. In VenafiConnection mode, this field is not needed. + INFO ignoring the venafi-cloud.upload_path field in the config file. In VenafiConnection mode, this field is not needed. + INFO ignoring the venafi-cloud.uploader_id field in the config file. This field is not needed in VenafiConnection mode. + INFO Ignoring the cluster_id field in the config file. This field is not needed in VenafiConnection mode. INFO Using period from config period="1h0m0s" `), gotLogs.String()) - assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) + assert.Equal(t, VenafiConnection, got.OutputMode) assert.IsType(t, &client.VenConnClient{}, gotCl) }) @@ -642,7 +642,7 @@ func Test_ValidateAndCombineConfig(t *testing.T) { `)), withCmdLineFlags("--venafi-connection", "venafi-components")) require.NoError(t, err) - assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) + assert.Equal(t, VenafiConnection, got.OutputMode) }) t.Run("venafi-cloud-workload-identity-auth: --venafi-cloud is tolerated alongside --venafi-connection for backwards compatibility with older rendered charts", func(t *testing.T) { @@ -655,7 +655,7 @@ func Test_ValidateAndCombineConfig(t *testing.T) { `)), withCmdLineFlags("--venafi-connection", "venafi-components", "--venafi-cloud")) require.NoError(t, err) - assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) + assert.Equal(t, VenafiConnection, got.OutputMode) }) const arkUsername = "cluster-1-region-1-cloud-1@cyberark.cloud.123456" @@ -877,7 +877,7 @@ func Test_ValidateAndCombineConfig_VenafiConnection(t *testing.T) { _, _, err := ValidateAndCombineConfig(discardLogs(), Config{Server: "http://should-be-ignored", Period: 1 * time.Hour}, AgentCmdFlags{VenConnName: "venafi-components", InstallNS: "venafi"}) - assert.EqualError(t, err, "1 error occurred:\n\t* cluster_name or cluster_id is required in Venafi Cloud VenafiConnection mode\n\n") + assert.EqualError(t, err, "1 error occurred:\n\t* cluster_name or cluster_id is required in VenafiConnection mode\n\n") }) t.Run("the server field is ignored when VenafiConnection is used", func(t *testing.T) { From 58469e8eef82693dfe2a9a3fbd43ea941d43b9aa Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:48:14 +0200 Subject: [PATCH 3/6] add venafiConnection option to Helm chart Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- deploy/charts/discovery-agent/README.md | 28 ++++- .../discovery-agent/templates/deployment.yaml | 23 ++++ .../tests/deployment_test.yaml | 109 ++++++++++++++++++ .../charts/discovery-agent/values.schema.json | 43 ++++++- deploy/charts/discovery-agent/values.yaml | 23 ++++ 5 files changed, 218 insertions(+), 8 deletions(-) diff --git a/deploy/charts/discovery-agent/README.md b/deploy/charts/discovery-agent/README.md index f182efdf..3bd42f8c 100644 --- a/deploy/charts/discovery-agent/README.md +++ b/deploy/charts/discovery-agent/README.md @@ -12,7 +12,7 @@ The Discovery Agent connects your Kubernetes or OpenShift cluster to Palo Alto N > "" > ``` -The TSG (Tenant Service Group) ID to use when connecting to SCM. The production SCM server URL is derived from this value. Required unless config.serverURL is set. Mutually exclusive with config.serverURL. +The TSG (Tenant Service Group) ID to use when connecting to SCM. The production SCM server URL is derived from this value. Required unless config.serverURL is set. Mutually exclusive with config.serverURL. Must not be set when config.venafiConnection.enabled is true (the TSG ID is taken from the VenafiConnection's `spec.ngts` instead). #### **config.clusterName** ~ `string` @@ -72,7 +72,7 @@ Example: excludeAnnotationKeysRegex: ['^kapp\.k14s\.io/original.*'] > "" > ``` -Deprecated: Client ID for the configured service account. The client ID should be provided in the "clientID" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the "venafi-kubernetes-agent" chart. +Deprecated: Client ID for the configured service account. The client ID should be provided in the "clientID" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the "venafi-kubernetes-agent" chart. Must not be set when config.venafiConnection.enabled is true. #### **config.secretName** ~ `string` > Default value: @@ -84,8 +84,30 @@ The name of the Secret containing the NGTS built-in service account credentials. The Secret must contain the following key: - privatekey.pem: PEM-encoded private key for the service account The Secret should also contain the following key: -- clientID: Service account client ID (config.clientID must be set if not present) +- clientID: Service account client ID (config.clientID must be set if not present) +Ignored when config.venafiConnection.enabled is true. +#### **config.venafiConnection.enabled** ~ `bool` +> Default value: +> ```yaml +> false +> ``` + +When set to true, config.tsgID, config.serverURL, config.clientID and config.clientId must not be set (the chart will fail to render otherwise), and the Secret named by config.secretName will _not_ be mounted into the Discovery Agent Pod. +#### **config.venafiConnection.name** ~ `string` +> Default value: +> ```yaml +> venafi-components +> ``` + +The name of a VenafiConnection resource which contains the configuration for authenticating to the upload backend. +#### **config.venafiConnection.namespace** ~ `string` +> Default value: +> ```yaml +> venafi +> ``` + +The namespace of a VenafiConnection resource which contains the configuration for authenticating to the upload backend. #### **replicaCount** ~ `number` > Default value: > ```yaml diff --git a/deploy/charts/discovery-agent/templates/deployment.yaml b/deploy/charts/discovery-agent/templates/deployment.yaml index fdde00f4..325a3ad2 100644 --- a/deploy/charts/discovery-agent/templates/deployment.yaml +++ b/deploy/charts/discovery-agent/templates/deployment.yaml @@ -71,6 +71,24 @@ spec: - "agent" - "-c" - "/etc/discovery-agent/config.yaml" + {{- if .Values.config.venafiConnection.enabled }} + {{- if .Values.config.tsgID }} + {{- fail "config.tsgID must not be set when config.venafiConnection.enabled is true; the TSG ID is read from the VenafiConnection's spec.ngts" }} + {{- end }} + {{- if .Values.config.serverURL }} + {{- fail "config.serverURL must not be set when config.venafiConnection.enabled is true; the server URL is read from the VenafiConnection's spec" }} + {{- end }} + {{- if .Values.config.clientID }} + {{- fail "config.clientID must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" }} + {{- end }} + {{- if .Values.config.clientId }} + {{- fail "config.clientId must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" }} + {{- end }} + - --venafi-connection + - {{ .Values.config.venafiConnection.name | quote }} + - --venafi-connection-namespace + - {{ .Values.config.venafiConnection.namespace | quote }} + {{- else }} - --ngts {{- if and .Values.config.tsgID .Values.config.serverURL }} {{- fail "config.tsgID and config.serverURL are mutually exclusive; set exactly one" }} @@ -87,6 +105,7 @@ spec: {{- end }} - --private-key-path - /etc/discovery-agent/credentials/privatekey.pem + {{- end }} - --logging-format=json {{- if .Values.metrics.enabled }} - --enable-metrics @@ -105,9 +124,11 @@ spec: - name: config mountPath: "/etc/discovery-agent" readOnly: true + {{- if not .Values.config.venafiConnection.enabled }} - name: credentials mountPath: "/etc/discovery-agent/credentials" readOnly: true + {{- end }} {{- with .Values.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} @@ -119,10 +140,12 @@ spec: configMap: name: {{ include "discovery-agent.fullname" . }}-config optional: false + {{- if not .Values.config.venafiConnection.enabled }} - name: credentials secret: secretName: {{ .Values.config.secretName }} optional: false + {{- end }} {{- with .Values.volumes }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/deploy/charts/discovery-agent/tests/deployment_test.yaml b/deploy/charts/discovery-agent/tests/deployment_test.yaml index 35f47ec5..9b4d777c 100644 --- a/deploy/charts/discovery-agent/tests/deployment_test.yaml +++ b/deploy/charts/discovery-agent/tests/deployment_test.yaml @@ -373,3 +373,112 @@ tests: path: spec.template.spec.imagePullSecrets content: name: my-secret + + # VenafiConnection mode wires the connection name/namespace through as flags + # and skips both the --ngts/--tsg-id flags and the keypair Secret mount. The + # agent picks the actual upload backend (NGTS or VCP) from the + # VenafiConnection resource at runtime. + - it: VenafiConnection mode passes the connection flags and omits NGTS/keypair flags + set: + config.clusterName: test-cluster + config.venafiConnection.enabled: true + config.venafiConnection.name: my-venconn + config.venafiConnection.namespace: my-ns + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection + - contains: + path: spec.template.spec.containers[0].args + content: my-venconn + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection-namespace + - contains: + path: spec.template.spec.containers[0].args + content: my-ns + - notContains: + path: spec.template.spec.containers[0].args + content: --ngts + - notContains: + path: spec.template.spec.containers[0].args + content: --tsg-id + - notContains: + path: spec.template.spec.containers[0].args + content: --ngts-server-url + - notContains: + path: spec.template.spec.containers[0].args + content: --client-id + - notContains: + path: spec.template.spec.containers[0].args + content: --private-key-path + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: credentials + mountPath: "/etc/discovery-agent/credentials" + readOnly: true + - notContains: + path: spec.template.spec.volumes + content: + name: credentials + secret: + secretName: discovery-agent-credentials + optional: false + + # VenafiConnection mode does not require config.tsgID, since the agent reads + # the TSG ID from the VenafiConnection resource at runtime. + - it: VenafiConnection mode does not require config.tsgID + set: + config.clusterName: test-cluster + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - isKind: + of: Deployment + + # Keypair-mode fields must not be set in VenafiConnection mode; the chart + # should fail to render rather than silently dropping the values, so users + # don't end up with a config that looks wired but isn't. + - it: VenafiConnection mode rejects config.tsgID + set: + config.clusterName: test-cluster + config.tsgID: "999" + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: "config.tsgID must not be set when config.venafiConnection.enabled is true; the TSG ID is read from the VenafiConnection's spec.ngts" + + - it: VenafiConnection mode rejects config.serverURL + set: + config.clusterName: test-cluster + config.serverURL: "https://should-be-rejected.example.com" + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: "config.serverURL must not be set when config.venafiConnection.enabled is true; the server URL is read from the VenafiConnection's spec" + + - it: VenafiConnection mode rejects config.clientID + set: + config.clusterName: test-cluster + config.clientID: "should-be-rejected" + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: "config.clientID must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" + + - it: VenafiConnection mode rejects config.clientId + set: + config.clusterName: test-cluster + config.clientId: "should-be-rejected" + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: "config.clientId must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" diff --git a/deploy/charts/discovery-agent/values.schema.json b/deploy/charts/discovery-agent/values.schema.json index f40d6e24..3ce11dd5 100644 --- a/deploy/charts/discovery-agent/values.schema.json +++ b/deploy/charts/discovery-agent/values.schema.json @@ -126,6 +126,9 @@ }, "tsgID": { "$ref": "#/$defs/helm-values.config.tsgID" + }, + "venafiConnection": { + "$ref": "#/$defs/helm-values.config.venafiConnection" } }, "type": "object" @@ -137,12 +140,12 @@ }, "helm-values.config.clientID": { "default": "", - "description": "Deprecated: Client ID for the configured service account. The client ID should be provided in the \"clientID\" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the \"venafi-kubernetes-agent\" chart.", + "description": "Deprecated: Client ID for the configured service account. The client ID should be provided in the \"clientID\" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the \"venafi-kubernetes-agent\" chart. Must not be set when config.venafiConnection.enabled is true.", "type": "string" }, "helm-values.config.clientId": { "default": "", - "description": "Deprecated: Client ID for the configured service account (alternative to clientID). The client ID should be provided in the \"clientID\" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the \"venafi-kubernetes-agent\" chart. If both clientID and clientId are set, clientID takes precedence.", + "description": "Deprecated: Client ID for the configured service account (alternative to clientID). The client ID should be provided in the \"clientID\" field of the authentication secret (see config.secretName). This field is provided for compatibility for users migrating from the \"venafi-kubernetes-agent\" chart. If both clientID and clientId are set, clientID takes precedence. Must not be set when config.venafiConnection.enabled is true.", "type": "string" }, "helm-values.config.clusterDescription": { @@ -173,17 +176,47 @@ }, "helm-values.config.secretName": { "default": "discovery-agent-credentials", - "description": "The name of the Secret containing the NGTS built-in service account credentials.\nThe Secret must contain the following key:\n- privatekey.pem: PEM-encoded private key for the service account\nThe Secret should also contain the following key:\n- clientID: Service account client ID (config.clientID must be set if not present)", + "description": "The name of the Secret containing the NGTS built-in service account credentials.\nThe Secret must contain the following key:\n- privatekey.pem: PEM-encoded private key for the service account\nThe Secret should also contain the following key:\n- clientID: Service account client ID (config.clientID must be set if not present)\nIgnored when config.venafiConnection.enabled is true.", "type": "string" }, "helm-values.config.serverURL": { "default": "", - "description": "Explicit SCM server URL (optional).\nIf not set, the production SCM server URL is derived from config.tsgID. This value is intended for development purposes only and should not be set in production.\nMutually exclusive with config.tsgID.", + "description": "Explicit SCM server URL (optional).\nIf not set, the production SCM server URL is derived from config.tsgID. This value is intended for development purposes only and should not be set in production.\nMutually exclusive with config.tsgID.\nMust not be set when config.venafiConnection.enabled is true.", "type": "string" }, "helm-values.config.tsgID": { "default": "", - "description": "The TSG (Tenant Service Group) ID to use when connecting to SCM. The production SCM server URL is derived from this value. Required unless config.serverURL is set. Mutually exclusive with config.serverURL." + "description": "The TSG (Tenant Service Group) ID to use when connecting to SCM. The production SCM server URL is derived from this value. Required unless config.serverURL is set. Mutually exclusive with config.serverURL. Must not be set when config.venafiConnection.enabled is true (the TSG ID is taken from the VenafiConnection's `spec.ngts` instead)." + }, + "helm-values.config.venafiConnection": { + "additionalProperties": false, + "properties": { + "enabled": { + "$ref": "#/$defs/helm-values.config.venafiConnection.enabled" + }, + "name": { + "$ref": "#/$defs/helm-values.config.venafiConnection.name" + }, + "namespace": { + "$ref": "#/$defs/helm-values.config.venafiConnection.namespace" + } + }, + "type": "object" + }, + "helm-values.config.venafiConnection.enabled": { + "default": false, + "description": "When set to true, config.tsgID, config.serverURL, config.clientID and config.clientId must not be set (the chart will fail to render otherwise), and the Secret named by config.secretName will _not_ be mounted into the Discovery Agent Pod.", + "type": "boolean" + }, + "helm-values.config.venafiConnection.name": { + "default": "venafi-components", + "description": "The name of a VenafiConnection resource which contains the configuration for authenticating to the upload backend.", + "type": "string" + }, + "helm-values.config.venafiConnection.namespace": { + "default": "venafi", + "description": "The namespace of a VenafiConnection resource which contains the configuration for authenticating to the upload backend.", + "type": "string" }, "helm-values.extraArgs": { "default": [], diff --git a/deploy/charts/discovery-agent/values.yaml b/deploy/charts/discovery-agent/values.yaml index b013c959..0936321e 100644 --- a/deploy/charts/discovery-agent/values.yaml +++ b/deploy/charts/discovery-agent/values.yaml @@ -3,6 +3,7 @@ config: # The TSG (Tenant Service Group) ID to use when connecting to SCM. # The production SCM server URL is derived from this value. # Required unless config.serverURL is set. Mutually exclusive with config.serverURL. + # Must not be set when config.venafiConnection.enabled is true (the TSG ID is taken from the VenafiConnection's `spec.ngts` instead). # +docs:property # +docs:type=number,string tsgID: "" @@ -44,6 +45,7 @@ config: # Deprecated: Client ID for the configured service account. # The client ID should be provided in the "clientID" field of the authentication secret (see config.secretName). # This field is provided for compatibility for users migrating from the "venafi-kubernetes-agent" chart. + # Must not be set when config.venafiConnection.enabled is true. # +docs:property clientID: "" @@ -51,6 +53,7 @@ config: # The client ID should be provided in the "clientID" field of the authentication secret (see config.secretName). # This field is provided for compatibility for users migrating from the "venafi-kubernetes-agent" chart. # If both clientID and clientId are set, clientID takes precedence. + # Must not be set when config.venafiConnection.enabled is true. # +docs:hidden clientId: "" @@ -59,6 +62,7 @@ config: # - privatekey.pem: PEM-encoded private key for the service account # The Secret should also contain the following key: # - clientID: Service account client ID (config.clientID must be set if not present) + # Ignored when config.venafiConnection.enabled is true. # +docs:property secretName: discovery-agent-credentials @@ -66,9 +70,28 @@ config: # If not set, the production SCM server URL is derived from config.tsgID. # This value is intended for development purposes only and should not be set in production. # Mutually exclusive with config.tsgID. + # Must not be set when config.venafiConnection.enabled is true. # +docs:hidden serverURL: "" + # When venafiConnection.enabled is true, the Discovery Agent authenticates to + # its upload backend using the referenced VenafiConnection resource instead + # of the NGTS built-in service account key pair. For the NGTS backend, the + # VenafiConnection's `spec.ngts` (with `tsgID` or `url`, and a `jwt` source) + # is used. + venafiConnection: + # When set to true, config.tsgID, config.serverURL, config.clientID and + # config.clientId must not be set (the chart will fail to render + # otherwise), and the Secret named by config.secretName will _not_ be + # mounted into the Discovery Agent Pod. + enabled: false + # The name of a VenafiConnection resource which contains the configuration + # for authenticating to the upload backend. + name: venafi-components + # The namespace of a VenafiConnection resource which contains the + # configuration for authenticating to the upload backend. + namespace: venafi + # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ replicaCount: 1 From a4ae2824933a749837a0f954258a02e02b2166b6 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:39:19 +0200 Subject: [PATCH 4/6] apply Claude review suggestions Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- pkg/client/client_venconn.go | 6 ++-- pkg/client/client_venconn_test.go | 57 +++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/pkg/client/client_venconn.go b/pkg/client/client_venconn.go index 25869411..9a6f28e0 100644 --- a/pkg/client/client_venconn.go +++ b/pkg/client/client_venconn.go @@ -192,8 +192,6 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) version.SetUserAgent(req) - isNGTS := server.BackendAuth == connection_details.NGTSAccessToken - query := req.URL.Query() stripHTML := bluemonday.StrictPolicy() if opts.ClusterName != "" { @@ -202,9 +200,9 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading if opts.ClusterDescription != "" { query.Add("description", base64.RawURLEncoding.EncodeToString([]byte(stripHTML.Sanitize(opts.ClusterDescription)))) } - if isNGTS && opts.ClaimableCerts { + if isNGTS := server.BackendAuth == connection_details.NGTSAccessToken; isNGTS && opts.ClaimableCerts { // The TLSPK backend reads "certOwnership=unassigned" — this is the backend contract. - query.Set("certOwnership", "unassigned") + query.Add("certOwnership", "unassigned") } req.URL.RawQuery = query.Encode() diff --git a/pkg/client/client_venconn_test.go b/pkg/client/client_venconn_test.go index 93db9e5f..adfb633a 100644 --- a/pkg/client/client_venconn_test.go +++ b/pkg/client/client_venconn_test.go @@ -158,6 +158,63 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) { expectReadyCondMsg: "Generated a new token", expectErr: "VenafiConnection error-when-the-apikey-field-is-used/venafi-components: the agent does not support API key authentication with the VCP backend", })) + t.Run("error when the distributedIssuer field is used", run_TestVenConnClient_PostDataReadingsWithOptions(ctx, restconf, kclient, testcase{ + // The Firefly / Distributed Issuer backend reaches the + // `connection_details.DistributedIssuerAccessToken` branch, which the + // agent rejects since it only supports VCP and NGTS upload backends. + given: testutil.Undent(` + apiVersion: jetstack.io/v1alpha1 + kind: VenafiConnection + metadata: + name: venafi-components + namespace: TEST_NAMESPACE + spec: + distributedIssuer: + url: FAKE_TPP_URL + accessToken: + - secret: + name: accesstoken + fields: [accesstoken] + allowReferencesFrom: + matchExpressions: + - {key: kubernetes.io/metadata.name, operator: In, values: [venafi]} + --- + apiVersion: v1 + kind: Secret + metadata: + name: accesstoken + namespace: TEST_NAMESPACE + stringData: + accesstoken: VALID_ACCESS_TOKEN + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: venafi-connection-accesstoken-reader + namespace: TEST_NAMESPACE + rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + resourceNames: ["accesstoken"] + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: venafi-connection-accesstoken-reader + namespace: TEST_NAMESPACE + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: venafi-connection-accesstoken-reader + subjects: + - kind: ServiceAccount + name: venafi-connection + namespace: venafi + `), + expectReadyCondMsg: "Generated a new token", + expectErr: "VenafiConnection error-when-the-distributedissuer-field-is-used/venafi-components: the agent does not support the Distributed Issuer backend", + })) t.Run("error when the tpp field is used", run_TestVenConnClient_PostDataReadingsWithOptions(ctx, restconf, kclient, testcase{ // IMPORTANT: The user may think they can use 'tpp', spend time // debugging and making the venafi connection work, and then find out From 76fa0deaf5977446339451730474e2d3931407e6 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:42:59 +0200 Subject: [PATCH 5/6] fix stray periods in description Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- deploy/charts/venafi-kubernetes-agent/README.md | 4 ++-- deploy/charts/venafi-kubernetes-agent/values.schema.json | 2 +- deploy/charts/venafi-kubernetes-agent/values.yaml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/charts/venafi-kubernetes-agent/README.md b/deploy/charts/venafi-kubernetes-agent/README.md index f4ff5db5..e88e396a 100644 --- a/deploy/charts/venafi-kubernetes-agent/README.md +++ b/deploy/charts/venafi-kubernetes-agent/README.md @@ -390,10 +390,10 @@ Configure VenafiConnection authentication > false > ``` -When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or +When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or `url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and `spec.vcp.apiKey` are rejected by the agent. -Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the +Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the Secret with `authentication.secretName` will _not_ be mounted into the Discovery Agent Pod. #### **authentication.venafiConnection.name** ~ `string` > Default value: diff --git a/deploy/charts/venafi-kubernetes-agent/values.schema.json b/deploy/charts/venafi-kubernetes-agent/values.schema.json index b7fe9506..9b31de55 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.schema.json +++ b/deploy/charts/venafi-kubernetes-agent/values.schema.json @@ -137,7 +137,7 @@ }, "helm-values.authentication.venafiConnection.enabled": { "default": false, - "description": "When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or\n`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and\n`spec.vcp.apiKey` are rejected by the agent.\nUse `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", + "description": "When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or\n`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and\n`spec.vcp.apiKey` are rejected by the agent.\nUse `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", "type": "boolean" }, "helm-values.authentication.venafiConnection.name": { diff --git a/deploy/charts/venafi-kubernetes-agent/values.yaml b/deploy/charts/venafi-kubernetes-agent/values.yaml index c40c9d4b..09bc018e 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.yaml +++ b/deploy/charts/venafi-kubernetes-agent/values.yaml @@ -240,13 +240,13 @@ authentication: venafiConnection: # When set to true, the Discovery Agent will authenticate to its upload # backend using the configuration in a VenafiConnection resource. The - # backend is determined by the VenafiConnection's spec: use `spec.vcp` for - # CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or + # backend is determined by the VenafiConnection's spec: use `spec.vcp` + # for CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or # `url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and # `spec.vcp.apiKey` are rejected by the agent. # Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). - # When set to true, the `authentication.secret` values will be ignored and the - # Secret with `authentication.secretName` will _not_ be mounted into the + # When set to true, the `authentication.secret` values will be ignored and + # the Secret with `authentication.secretName` will _not_ be mounted into the # Discovery Agent Pod. enabled: false # The name of a VenafiConnection resource which contains the configuration From 45ee05c96eea1ec7123c85c8b78568bd66d4b531 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:47:39 +0200 Subject: [PATCH 6/6] rejects a non-default config.secretName Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- deploy/charts/discovery-agent/README.md | 2 +- .../discovery-agent/templates/deployment.yaml | 3 +++ .../tests/deployment_test.yaml | 19 +++++++++++++++++++ .../charts/discovery-agent/values.schema.json | 2 +- deploy/charts/discovery-agent/values.yaml | 2 +- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/deploy/charts/discovery-agent/README.md b/deploy/charts/discovery-agent/README.md index 3bd42f8c..80ca29e1 100644 --- a/deploy/charts/discovery-agent/README.md +++ b/deploy/charts/discovery-agent/README.md @@ -85,7 +85,7 @@ The Secret must contain the following key: - privatekey.pem: PEM-encoded private key for the service account The Secret should also contain the following key: - clientID: Service account client ID (config.clientID must be set if not present) -Ignored when config.venafiConnection.enabled is true. +Must not be set when config.venafiConnection.enabled is true (the credentials Secret is not mounted in that mode). #### **config.venafiConnection.enabled** ~ `bool` > Default value: diff --git a/deploy/charts/discovery-agent/templates/deployment.yaml b/deploy/charts/discovery-agent/templates/deployment.yaml index 325a3ad2..04abcada 100644 --- a/deploy/charts/discovery-agent/templates/deployment.yaml +++ b/deploy/charts/discovery-agent/templates/deployment.yaml @@ -84,6 +84,9 @@ spec: {{- if .Values.config.clientId }} {{- fail "config.clientId must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" }} {{- end }} + {{- if ne .Values.config.secretName "discovery-agent-credentials" }} + {{- fail "config.secretName must not be set when config.venafiConnection.enabled is true; the credentials Secret is not mounted in this mode (authentication is performed via the VenafiConnection resource)" }} + {{- end }} - --venafi-connection - {{ .Values.config.venafiConnection.name | quote }} - --venafi-connection-namespace diff --git a/deploy/charts/discovery-agent/tests/deployment_test.yaml b/deploy/charts/discovery-agent/tests/deployment_test.yaml index 9b4d777c..06def8c2 100644 --- a/deploy/charts/discovery-agent/tests/deployment_test.yaml +++ b/deploy/charts/discovery-agent/tests/deployment_test.yaml @@ -482,3 +482,22 @@ tests: asserts: - failedTemplate: errorMessage: "config.clientId must not be set when config.venafiConnection.enabled is true; authentication is performed via the VenafiConnection resource" + + - it: VenafiConnection mode rejects a non-default config.secretName + set: + config.clusterName: test-cluster + config.secretName: custom-credentials-secret + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - failedTemplate: + errorMessage: "config.secretName must not be set when config.venafiConnection.enabled is true; the credentials Secret is not mounted in this mode (authentication is performed via the VenafiConnection resource)" + + - it: VenafiConnection mode accepts the default config.secretName + set: + config.clusterName: test-cluster + config.venafiConnection.enabled: true + template: deployment.yaml + asserts: + - isKind: + of: Deployment diff --git a/deploy/charts/discovery-agent/values.schema.json b/deploy/charts/discovery-agent/values.schema.json index 3ce11dd5..2cfaca99 100644 --- a/deploy/charts/discovery-agent/values.schema.json +++ b/deploy/charts/discovery-agent/values.schema.json @@ -176,7 +176,7 @@ }, "helm-values.config.secretName": { "default": "discovery-agent-credentials", - "description": "The name of the Secret containing the NGTS built-in service account credentials.\nThe Secret must contain the following key:\n- privatekey.pem: PEM-encoded private key for the service account\nThe Secret should also contain the following key:\n- clientID: Service account client ID (config.clientID must be set if not present)\nIgnored when config.venafiConnection.enabled is true.", + "description": "The name of the Secret containing the NGTS built-in service account credentials.\nThe Secret must contain the following key:\n- privatekey.pem: PEM-encoded private key for the service account\nThe Secret should also contain the following key:\n- clientID: Service account client ID (config.clientID must be set if not present)\nMust not be set when config.venafiConnection.enabled is true (the credentials Secret is not mounted in that mode).", "type": "string" }, "helm-values.config.serverURL": { diff --git a/deploy/charts/discovery-agent/values.yaml b/deploy/charts/discovery-agent/values.yaml index 0936321e..b76acade 100644 --- a/deploy/charts/discovery-agent/values.yaml +++ b/deploy/charts/discovery-agent/values.yaml @@ -62,7 +62,7 @@ config: # - privatekey.pem: PEM-encoded private key for the service account # The Secret should also contain the following key: # - clientID: Service account client ID (config.clientID must be set if not present) - # Ignored when config.venafiConnection.enabled is true. + # Must not be set when config.venafiConnection.enabled is true (the credentials Secret is not mounted in that mode). # +docs:property secretName: discovery-agent-credentials