Summary
When using the secrets-provider sidecar injector with conjur.org/secrets-destination: k8s_secrets, the injector
incorrectly injects a conjur-secrets VolumeMount into the application containers. This VolumeMount references a
volume (conjur-secrets) that is never created for the k8s_secrets destination, causing Kubernetes to reject the
pod with a volume reference error.
The conjur-secrets volume and its associated VolumeMount are only applicable when using file-based secret delivery
(conjur.org/secrets-destination: file). For k8s_secrets, secrets are written directly to Kubernetes Secrets and
no shared in-memory file volume is needed — only the conjur-status volume is required.
Steps to Reproduce
- Deploy the CyberArk Sidecar Injector to a Kubernetes/OpenShift cluster.
- Label your target namespace:
kubectl label namespace <your-namespace> cyberark-sidecar-injector=enabled
- Create a pod with the following annotations on the Pod template spec:
annotations:
conjur.org/inject: "true"
conjur.org/inject-type: "secrets-provider"
conjur.org/container-mode: "sidecar" # or "init"
conjur.org/secrets-destination: "k8s_secrets"
conjur.org/conjur-inject-volumes: "<your-app-container-name>"
- Apply the manifest and describe the failing pod:
kubectl apply -f <your-manifest>.yaml -n <your-namespace>
kubectl describe pod <pod-name> -n <your-namespace>
Expected Results
When conjur.org/secrets-destination is set to k8s_secrets, only the conjur-status VolumeMount should be
injected into the application containers. The conjur-secrets volume and its VolumeMount should not be injected,
because no conjur-secrets in-memory volume is created for the k8s_secrets destination.
Actual Results
The injector always injects both conjur-status and conjur-secrets VolumeMounts into the specified application
containers, regardless of the secrets-destination value. Since the conjur-secrets volume is only created when
secrets-destination: file, Kubernetes rejects the pod at scheduling time with an error similar to:
MountVolume.SetUp failed: configmap "conjur-secrets" not found
Reproducible
Version/Tag number
Affects all versions containing the secrets-provider inject type. The defect is located in:
pkg/inject/server.go — HandleAdmissionRequest, secrets-provider case
pkg/inject/secrets-provider.go — getSPVolumes correctly gates conjur-secrets volume creation on
secretsDest == "file", but the corresponding VolumeMount injection in server.go has no such gate.
Environment Setup
- Reproducible on any Kubernetes or OpenShift cluster running the CyberArk Sidecar Injector.
- Required conditions:
conjur.org/inject-type: secrets-provider
conjur.org/secrets-destination: k8s_secrets
- At least one container name listed in
conjur.org/conjur-inject-volumes
Additional Information
Root cause: In server.go, the ContainerVolumeMounts for app containers in the secrets-provider branch
unconditionally appends both conjur-status and conjur-secrets mounts. However, getSPVolumes() in
secrets-provider.go only creates the conjur-secrets volume when secretsDestination == "file". This mismatch
means the VolumeMount is injected for k8s_secrets pods even though the backing volume is never created.
Proposed fix: Gate the conjur-secrets VolumeMount injection on secretsDestination == "file", matching the
condition already present in getSPVolumes():
// pkg/inject/server.go — secrets-provider case
for _, receiveContainerName := range conjurInjectVolume {
mounts := []corev1.VolumeMount{
{
Name: "conjur-status",
ReadOnly: false,
MountPath: "/conjur/status",
},
}
if secretsDestination == "file" {
mounts = append(mounts, corev1.VolumeMount{
Name: "conjur-secrets",
ReadOnly: false,
MountPath: "/conjur/secrets",
})
}
containerVolumeMounts[receiveContainerName] = mounts
}
Summary
When using the
secrets-providersidecar injector withconjur.org/secrets-destination: k8s_secrets, the injectorincorrectly injects a
conjur-secretsVolumeMount into the application containers. This VolumeMount references avolume (
conjur-secrets) that is never created for thek8s_secretsdestination, causing Kubernetes to reject thepod with a volume reference error.
The
conjur-secretsvolume and its associated VolumeMount are only applicable when using file-based secret delivery(
conjur.org/secrets-destination: file). Fork8s_secrets, secrets are written directly to Kubernetes Secrets andno shared in-memory file volume is needed — only the
conjur-statusvolume is required.Steps to Reproduce
Expected Results
When
conjur.org/secrets-destinationis set tok8s_secrets, only theconjur-statusVolumeMount should beinjected into the application containers. The
conjur-secretsvolume and its VolumeMount should not be injected,because no
conjur-secretsin-memory volume is created for thek8s_secretsdestination.Actual Results
The injector always injects both
conjur-statusandconjur-secretsVolumeMounts into the specified applicationcontainers, regardless of the
secrets-destinationvalue. Since theconjur-secretsvolume is only created whensecrets-destination: file, Kubernetes rejects the pod at scheduling time with an error similar to:Reproducible
Version/Tag number
Affects all versions containing the
secrets-providerinject type. The defect is located in:pkg/inject/server.go—HandleAdmissionRequest,secrets-providercasepkg/inject/secrets-provider.go—getSPVolumescorrectly gatesconjur-secretsvolume creation onsecretsDest == "file", but the corresponding VolumeMount injection inserver.gohas no such gate.Environment Setup
conjur.org/inject-type: secrets-providerconjur.org/secrets-destination: k8s_secretsconjur.org/conjur-inject-volumesAdditional Information
Root cause: In
server.go, theContainerVolumeMountsfor app containers in thesecrets-providerbranchunconditionally appends both
conjur-statusandconjur-secretsmounts. However,getSPVolumes()insecrets-provider.goonly creates theconjur-secretsvolume whensecretsDestination == "file". This mismatchmeans the VolumeMount is injected for
k8s_secretspods even though the backing volume is never created.Proposed fix: Gate the
conjur-secretsVolumeMount injection onsecretsDestination == "file", matching thecondition already present in
getSPVolumes():