The Cyberark Discovery and Context Agent connects your Kubernetes or OpenShift cluster to the Discovery and Context service of the CyberArk Identity Security Platform.
Create a namespace for the agent:
export NAMESPACE=cyberark
kubectl create ns "$NAMESPACE" || trueThe agent supports two authentication methods, selected automatically by config:
| Set this | Method used |
|---|---|
config.cyberark.serviceId (Conjur authn-jwt service-id) |
Conjur JWT exchange — exchanges a projected ServiceAccount token for a short-lived Conjur access token. No stored password. Preferred for new installs. |
ARK_USERNAME + ARK_SECRET in the Secret (and no serviceId) |
Legacy CyberArk Identity username/password — backward compatible with existing GA installs. |
If both are set, the Conjur serviceId wins (so a migrating install can add
the service-id before removing its old credentials) and a warning is logged. If
neither is set, the agent fails closed at startup.
The only credential always required in the Kubernetes Secret is the CyberArk
tenant subdomain (ARK_SUBDOMAIN).
export ARK_SUBDOMAIN= # your CyberArk tenant subdomain, e.g. tlskp-test
# OPTIONAL: Discovery API URL for non-production environments
export ARK_DISCOVERY_API=https://platform-discovery.integration-cyberark.cloud/Create the Secret:
kubectl create secret generic agent-credentials \
--namespace "$NAMESPACE" \
--from-literal=ARK_SUBDOMAIN=$ARK_SUBDOMAIN
# Add the optional key only if targeting a non-production Discovery API:
# kubectl patch secret agent-credentials -n "$NAMESPACE" \
# --type=json -p '[{"op":"add","path":"/data/ARK_DISCOVERY_API","value":"'"$(echo -n $ARK_DISCOVERY_API | base64)"'"}]'Alternatively, use the following Secret as a template:
# agent-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
name: agent-credentials
namespace: cyberark
type: Opaque
stringData:
ARK_SUBDOMAIN: "tlskp-test" # your CyberArk tenant subdomain
# OPTIONAL: uncomment for non-production Discovery API
# ARK_DISCOVERY_API: https://platform-discovery.integration-cyberark.cloud/
# LEGACY (only if NOT using Conjur serviceId) — username/password auth:
# ARK_USERNAME: "svc-agent@tenant"
# ARK_SECRET: "<password>"Skip this section if you are using the legacy username/password method (set
ARK_USERNAME/ARK_SECRETin the Secret and leaveserviceIdempty).
Set config.cyberark.serviceId to the authn-jwt authenticator service ID
configured for this cluster in your Conjur tenant. This is the bare service-id
segment (e.g. disco-agent), NOT the policy path conjur/authn-jwt/disco-agent
— the agent builds the authenticate URL as
<base>/authn-jwt/<serviceId>/<account>/authenticate, so a path here would
double the conjur/authn-jwt prefix. The remaining defaults are correct for
CyberArk-hosted tenants:
| Value | Default | Description |
|---|---|---|
config.cyberark.serviceId |
"" |
Conjur authn-jwt service ID (required). Example: conjur/authn-jwt/disco-agent |
config.cyberark.account |
conjur |
Conjur account name. Always conjur for CyberArk-hosted tenants. |
config.cyberark.jwtSource |
file |
Token source. file = projected SA-token volume (default). spiffe deferred. |
config.cyberark.jwtFilePath |
/var/run/secrets/tokens/jwt |
Path to the projected token file. Auto-mounted by the chart when jwtSource=file. |
The chart automatically renders a projected ServiceAccount token volume
(audience=conjur, expiry 600 s) and mounts it at /var/run/secrets/tokens
when config.cyberark.jwtSource is file (the default). No manual volume
configuration is required.
Before deploying the agent against a new tenant, complete the following steps in the Conjur tenant:
-
Enable the authn-jwt authenticator with
audience=conjurandtoken-app-property=sub.# conjur-authn-jwt-policy.yml - !policy id: conjur/authn-jwt/disco-agent body: - !webservice - !variable jwks-uri - !variable token-app-property - !variable issuer - !variable audience - !group hosts - !permit role: !group hosts privilege: [ read, authenticate ] resource: !webservice
-
Set the authenticator variables (values shown as examples):
conjur variable set -i conjur/authn-jwt/disco-agent/token-app-property -v sub conjur variable set -i conjur/authn-jwt/disco-agent/audience -v conjur conjur variable set -i conjur/authn-jwt/disco-agent/issuer -v https://kubernetes.default.svc.cluster.local conjur variable set -i conjur/authn-jwt/disco-agent/jwks-uri -v https://kubernetes.default.svc.cluster.local/openid/v1/jwks
-
Pre-create a Conjur host for the agent ServiceAccount. The
idmust match the Kubernetes ServiceAccount'ssubclaim (system:serviceaccount:<namespace>:<sa-name>):# conjur-agent-host-policy.yml - !host id: system:serviceaccount/cyberark/disco-agent annotations: authn-jwt/disco-agent/sub: system:serviceaccount/cyberark/disco-agent
-
Add the host to the
data/disco/snapshot-uploadersgroup so the authorizer grants it upload access:- !grant role: !group data/disco/snapshot-uploaders member: !host system:serviceaccount/cyberark/disco-agent
-
Add the host to the authn-jwt authenticator's hosts group:
- !grant role: !group conjur/authn-jwt/disco-agent/hosts member: !host system:serviceaccount/cyberark/disco-agent
helm upgrade agent "oci://${OCI_BASE}/charts/disco-agent" \
--install \
--create-namespace \
--namespace "$NAMESPACE" \
--set fullnameOverride=disco-agent \
--set config.cyberark.serviceId=disco-agent \
--set acceptTerms=trueCheck the Pod and its events:
kubectl describe -n cyberark pods -l app.kubernetes.io/name=disco-agentCheck the logs:
kubectl logs deployments/disco-agent --namespace "${NAMESPACE}" --follow| Symptom | Likely cause | Fix |
|---|---|---|
Agent logs 401 Unauthorized from Conjur |
ServiceAccount token audience does not match the authenticator's configured audience value, or the authn-jwt authenticator is not enabled for the account |
Confirm audience=conjur in both the projected volume (chart default) and the Conjur conjur/authn-jwt/<serviceId>/audience variable; ensure the authenticator is enabled (CONJUR_AUTHENTICATORS includes authn-jwt/<serviceId>) |
Agent logs 403 Forbidden from the upload API |
The agent's Conjur host is not a member of data/disco/snapshot-uploaders |
Add the host to the group per step 4 of the onboarding runbook above |
Agent logs 500 / no upload attempt |
Conjur is unreachable or returned an unexpected error | Check network policy / DNS; inspect Conjur audit logs for the host identity |
Default value:
1
This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
Default value:
false
Must be set to indicate that you have read and accepted the CyberArk Terms of Service. If false, the helm chart will fail to install and will print a message with instructions on how to accept the TOS.
Default value:
quay.io
The container registry used for disco-agent images by default. This can include path prefixes (e.g. "artifactory.example.com/docker").
Default value:
jetstack
The repository namespace used for disco-agent images by default.
Examples:
- jetstack
- custom-namespace
Deprecated: per-component registry prefix.
If set, this value is prepended to the image repository that the chart would otherwise render. This applies both when image.repository is set and when the repository is computed from
imageRegistry + imageNamespace + image.name.
This can produce "double registry" style references such as
legacy.example.io/quay.io/jetstack/.... Prefer using the global
imageRegistry/imageNamespace values.
Default value:
""
Full repository override (takes precedence over imageRegistry, imageNamespace, and image.name).
Example: quay.io/jetstack/disco-agent
Default value:
disco-agent
The image name for the Discovery Agent.
This is used (together with imageRegistry and imageNamespace) to construct the full image reference.
Default value:
IfNotPresent
This sets the pull policy for images.
Default value:
""
Override the image tag to deploy by setting this variable. If no value is set, the chart's appVersion is used.
Default value:
""
Override the image digest to deploy by setting this variable. If set together with image.tag, the rendered image will include both tag and digest.
Default value:
[]
This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
Default value:
""
This is to override the chart name.
Default value:
""
Default value:
true
Specifies whether a service account should be created
Default value:
true
Automatically mount a ServiceAccount's API credentials?
Default value:
{}
Annotations to add to the service account
Default value:
""
The name of the service account to use.
If not set and create is true, a name is generated using the fullname template
Default value:
{}
This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
Default value:
{}
This is for setting Kubernetes Labels to a Pod.
For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
Default value:
{}
Default value:
allowPrivilegeEscalation: false capabilities: drop: - ALL readOnlyRootFilesystem: true runAsNonRoot: true seccompProfile: type: RuntimeDefault
Add Container specific SecurityContext settings to the container. Takes precedence over podSecurityContext when set. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container
Default value:
{}
Default value:
[]
Additional volumes on the output Deployment definition.
Default value:
[]
Additional volumeMounts on the output Deployment definition.
Default value:
{}
Default value:
[]
Default value:
{}
Configures the HTTP_PROXY environment variable where a HTTP proxy is required.
Configures the HTTPS_PROXY environment variable where a HTTP proxy is required.
Configures the NO_PROXY environment variable where a HTTP proxy is required, but certain domains should be excluded.
Default value:
enabled: false
Configure a PodDisruptionBudget for the agent's Deployment. If running with multiple replicas, consider setting podDisruptionBudget.enabled to true.
Default value:
12h0m0s
Push data every 12 hours unless changed.
Default value:
[]
You can configure the agent to exclude some annotations or labels from being pushed . All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being pushed.
Dots is the only character that needs to be escaped in the regex. Use either double quotes with escaped single quotes or unquoted strings for the regex to avoid YAML parsing issues with \..
Example: excludeAnnotationKeysRegex: ['^kapp.k14s.io/original.*']
Default value:
[]
Default value:
""
A human readable name for the cluster where the agent is deployed (optional).
This cluster name will be associated with the data that the agent uploads to the Discovery and Context service. If empty (the default), the service account name will be used instead.
Default value:
""
A short description of the cluster where the agent is deployed (optional).
This description will be associated with the data that the agent uploads to the Discovery and Context service. The description may include contact information such as the email address of the cluster administrator, so that any problems and risks identified by the Discovery and Context service can be communicated to the people responsible for the affected secrets.
Default value:
true
Enable sending of Secret values to CyberArk in addition to metadata. Metadata is always sent, but the actual values of Secrets are not sent by default. When enabled, Secret data is encrypted using envelope encryption using a key managed by CyberArk, fetched from the Discovery and Context service.
Default value:
agent-credentials
Default value:
[]
extraArgs:
- --logging-format=json
- --log-level=6 # To enable HTTP request loggingDefault value:
false
Enable profiling with the pprof endpoint
Default value:
true
Enable the metrics server.
If false, the metrics server will be disabled and the other metrics fields below will be ignored.
Default value:
false
Create a PodMonitor to add the metrics to Prometheus, if you are using Prometheus Operator. See https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor
The namespace that the pod monitor should live in.
Defaults to the disco-agent namespace.
Default value:
default
Specifies the prometheus label on the created PodMonitor. This is used when different Prometheus instances have label selectors matching different PodMonitors.
Default value:
60s
The interval to scrape metrics.
Default value:
30s
The timeout before a metrics scrape fails.
Default value:
{}
Additional labels to add to the PodMonitor.
Default value:
{}
Additional annotations to add to the PodMonitor.
Default value:
false
Keep labels from scraped data, overriding server-side labels.
Default value:
{}
EndpointAdditionalProperties allows setting additional properties on the endpoint such as relabelings, metricRelabelings etc.
For example:
endpointAdditionalProperties:
relabelings:
- action: replace
sourceLabels:
- __meta_kubernetes_pod_node_name
targetLabel: instance