Override default Mission Control security settings for Helm installations

Mission Control provides several security mechanisms to protect your deployment:

  • Container runtime security through Pod Security Context and Container Security Context

  • Container image security through image pull secrets

  • Custom resource security through component-specific security settings

These security features help enforce the principle of least privilege and protect your deployment from unauthorized access.

Prerequisites

  • Helm installed and configured for Mission Control installation

  • Access to your container registry credentials for image pull secrets

  • The registry address and port for image pull secrets

  • The namespace where you plan to install Mission Control

KOTS installations do not support security overrides.

Configure image pull secrets

When you install Mission Control in environments that require authentication to pull container images, you must configure image pull secrets.

This configuration is especially important for airgapped environments or when you use private registries.

Starting with version 1.8.0, the operator automatically creates image pull secrets for Helm installations and replicates them to all namespaces. You only need to reference the secret in your configuration overrides.

Configuration options

The following examples demonstrate how to set global and component-specific image pull secrets. For each example that you use, replace the following:

  • PULL_SECRET_NAME: The name of your Kubernetes secret, automatically created by the operator in version 1.8.0 and later

  • REGISTRY_ADDRESS: The address of your registry

  • REGISTRY_NAMESPACE: The namespace within your registry

In most cases, you’ll only need the global configuration. Use component-specific configurations only when you need different registry settings for specific components.

Global image pull secrets

To configure pull secrets for all components, use the global configuration:

# Global configuration for all components
global:
  imagePullSecrets:
    - name: PULL_SECRET_NAME
Main Mission Control component image pull secrets
# Main Mission Control component configuration
image:
  registry: REGISTRY_ADDRESS
  repository: REGISTRY_NAMESPACE/Mission Control
  imagePullSecret: PULL_SECRET_NAME

# Component-specific image configurations
imageConfigs:
  registryOverride: REGISTRY_ADDRESS
  reaper:
    repository: REGISTRY_NAMESPACE
  medusa:
    repository: REGISTRY_NAMESPACE
  dataApi:
    repository: REGISTRY_NAMESPACE
  yq:
    image: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/yq:4
  cqlsh:
    repository: REGISTRY_NAMESPACE
Observability components image pull secrets
# Vector agent configuration for log collection
agent:
  image:
    repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/vector
    pullSecrets:
      - name: PULL_SECRET_NAME

# Vector aggregator configuration for log aggregation
aggregator:
  image:
    repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/vector
    pullSecrets:
      - name: PULL_SECRET_NAME

# Loki logging configuration
loki:
  global:
    image:
      registry: REGISTRY_ADDRESS
  imagePullSecrets:
    - name: PULL_SECRET_NAME
  loki:
    image:
      repository: REGISTRY_NAMESPACE/loki
  sidecar:
    image:
      repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/k8s-sidecar
  gateway:
    image:
      registry: REGISTRY_ADDRESS
      repository: REGISTRY_NAMESPACE/nginx-unprivileged

# Mimir metrics configuration
mimir:
  image:
    repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/mimir
    pullSecrets:
      - PULL_SECRET_NAME
  minio:
    image:
      repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/minio
    mcImage:
      repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/mc
    imagePullSecrets:
      - name: PULL_SECRET_NAME
  nginx:
    image:
      registry: REGISTRY_ADDRESS
      repository: REGISTRY_NAMESPACE/nginx-unprivileged
      pullSecrets:
        - PULL_SECRET_NAME
Operator components image pull secrets
# K8ssandra operator configuration
k8ssandra-operator:
  image:
    registry: REGISTRY_ADDRESS
    repository: REGISTRY_NAMESPACE/k8ssandra-operator
    registryOverride: REGISTRY_ADDRESS
  imagePullSecrets:
    - name: PULL_SECRET_NAME
  cleaner:
    image:
      registry: REGISTRY_ADDRESS
  cass-operator:
    image:
      registry: REGISTRY_ADDRESS
      repository: REGISTRY_NAMESPACE/cass-operator
      registryOverride: REGISTRY_ADDRESS
    imagePullSecrets:
      - name: PULL_SECRET_NAME
    imagePullSecret: PULL_SECRET_NAME
    imageConfig:
      systemLogger: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/system-logger:v1.22.4
      configBuilder: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/cass-config-builder:1.0-ubi8
      k8ssandraClient: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/k8ssandra-client:v0.5.0
      defaults:
        # Note, postfix is ignored if repository is not set
        cassandra:
          repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/cass-management-api
          suffix: "-ubi8"
        dse:
          repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/dse-mgmtapi-6_8
          suffix: "-ubi8"
        hcd:
          repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/hcd
          suffix: ""
  client:
    image:
      registry: REGISTRY_ADDRESS
      repository: REGISTRY_NAMESPACE/k8ssandra-tools
Additional components image pull secrets
# Client component configuration
client:
  image:
    registry: REGISTRY_ADDRESS
    repository: REGISTRY_NAMESPACE/k8ssandra-client
    imagePullSecret: PULL_SECRET_NAME

# CRD patch job configuration
crdPatchJob:
  image:
    registry: REGISTRY_ADDRESS
    repository: REGISTRY_NAMESPACE/kubectl
    imagePullSecret: PULL_SECRET_NAME

# UI component configuration
ui:
  image:
    registry: REGISTRY_ADDRESS
    repository: REGISTRY_NAMESPACE/Mission Control-ui
    imagePullSecret: PULL_SECRET_NAME

# Dex authentication component configuration
dex:
  image:
    repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/Mission Control-dex
  imagePullSecrets:
    - name: PULL_SECRET_NAME

# Kube state metrics configuration
kube-state-metrics:
  image:
    registry: REGISTRY_ADDRESS
    repository: REGISTRY_NAMESPACE/kube-state-metrics
  imagePullSecrets:
    - name: PULL_SECRET_NAME

# Replicated SDK configuration
replicated:
  images:
    replicated-sdk: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/replicated-sdk:1.0.0
  imagePullSecrets:
    - name: PULL_SECRET_NAME

# Kubernetes Ingress controller configuration
kubernetes-ingress:
  controller:
    image:
      repository: REGISTRY_ADDRESS/REGISTRY_NAMESPACE/kubernetes-ingress
    existingImagePullSecret: PULL_SECRET_NAME

Verify the pull secret

To verify that the pull secret was created and replicated successfully, run:

kubectl get secret PULL_SECRET_NAME -n mission-control

Replace PULL_SECRET_NAME with the name of the secret you created in the previous step.

If you configured multiple image pull secrets, you can verify all secrets at once:

kubectl get secrets -n mission-control

Or list only the image pull secrets:

kubectl get secrets -n mission-control --field-selector type=kubernetes.io/dockerconfigjson

The output shows each secret with type kubernetes.io/dockerconfigjson.

Troubleshoot image pull issues

If you encounter issues with image pulling, check the following:

  • Verify that the secret exists in the correct namespace.

  • Ensure that the registry credentials are correct.

  • Check that the secret name matches in both the values.yaml file and the created secret.

  • Verify network connectivity to the registry.

  • Check pod events for authentication errors:

    kubectl get events -n mission-control

Override platform security settings

Override platform security settings for your environment by setting the podSecurityContext and securityContext parameters using Helm.

YAML file with security overrides
dex:
  podSecurityContext:
    runAsNonRoot: true
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true

agent:
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true
    runAsNonRoot: true
  podSecurityContext:
    fsGroup: 1001
    runAsUser: 1001
    runAsNonRoot: true

aggregator:
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true
    runAsNonRoot: true
  podSecurityContext:
    fsGroup: 1001
    runAsUser: 1001
    runAsNonRoot: true

loki:
  sidecar:
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
      readOnlyRootFilesystem: true
      runAsNonRoot: true
  loki:
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
      readOnlyRootFilesystem: true
      runAsNonRoot: true
  podSecurityContext:
    runAsNonRoot: true

k8ssandra-operator:
  podSecurityContext:
    runAsNonRoot: true
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true

cass-operator:
  podSecurityContext:
    runAsNonRoot: true
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true

Apply the overrides:

helm upgrade mission-control oci://registry.replicated.com/mission-control/mission-control --namespace mission-control --create-namespace -f PLATFORM_SECURITY_OVERRIDES.yaml

Replace PLATFORM_SECURITY_OVERRIDES.yaml with the name of the file that contains the security overrides.

Deploy a MissionControlCluster with security overrides

Override security settings for the MissionControlCluster custom resource by setting the containerSecurityContext and podSecurityContext parameters using kubectl.

YAML file with security overrides
apiVersion:
kind: MissionControlCluster
metadata:
  name: MISSION_CONTROL_CLUSTER_NAME
  namespace: NAMESPACE
spec:
  k8ssandra:
    cassandra:
      initContainers:
        # Cassandra v...
        - name: cass-config-builder
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999

        # DSE v...
        - name: ...
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999

        # HCD v...
        - name: ...
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999

        # Medusa
        - name: ...
      containers:
        - name: cassandra
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999
        - name: server-system-logger
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999
      podSecurityContext:
        fsGroup: 999
        runAsGroup: 999
        runAsNonRoot: true
        runAsUser: 999
  cqlsh:
    spec:
      initContainers: []
      containers:
        - name: ...
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: true
            runAsGroup: 999
            runAsNonRoot: true
            runAsUser: 999
      securityContext:
        fsGroup: 999
        runAsGroup: 999
        runAsNonRoot: true
        runAsUser: 999

For more comprehensive CQLSH pod customization options, including resource management, scheduling control, and environment configuration, see Customize the CQLSH pod.

Replace the following:

  • MISSION_CONTROL_CLUSTER_NAME: The name of the MissionControlCluster custom resource

  • NAMESPACE: The namespace where the MissionControlCluster custom resource is deployed

Deploy the MissionControlCluster with overrides:

kubectl apply -f MISSION_CONTROL_CLUSTER.yaml

Replace MISSION_CONTROL_CLUSTER.yaml with the name of the file that contains the settings for your MissionControlCluster.

Override settings for the CqlConnectivity API custom resource

Override settings for the CqlConnectivity custom resource by setting the containerSecurityContext and podSecurityContext parameters using kubectl.

YAML file with security overrides
apiVersion: missioncontrol.datastax.com/v1alpha1
kind: CqlConnectivity
metadata:
  name: CQL_CONNECTIVITY_NAME
spec:
  cassandraDatacenterRef:
    name: DATACENTER_NAME
  loadBalancers:
    nativePort: 9042
    serviceConfig: {}
    size: 2
    podConfig:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        privileged: false
        readOnlyRootFilesystem: true
        runAsGroup: 999
        runAsNonRoot: true
        runAsUser: 999
      podSecurityContext:
        fsGroup: 999
        runAsGroup: 999
        runAsNonRoot: true
        runAsUser: 999

Replace the following:

  • CQL_CONNECTIVITY_NAME: The name of the CqlConnectivity custom resource

  • DATACENTER_NAME: The name of the datacenter

Create the CqlConnectivity custom resource with overrides:

kubectl apply -f CQL_CONNECTIVITY.yaml

Replace CQL_CONNECTIVITY.yaml with the name of the manifest file that contains the security overrides.

Override settings for the Data API

Override security settings for the Data API custom resource by setting the containerSecurityContext and podSecurityContext parameters using kubectl.

YAML file with security overrides
apiVersion: missioncontrol.datastax.com/v1alpha1
kind: DataApi
metadata:
  name: DATA_API_NAME
  namespace: NAMESPACE
spec:
  cassandraDatacenterRef:
    name: DATACENTER_NAME
  replicas: 1
  services:
    nodePort:
      port: NODE_PORT
    clusterIP:
      port: CLUSTER_IP_PORT
  containerSecurityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    privileged: false
    readOnlyRootFilesystem: true
  podSecurityContext:
    runAsNonRoot: true

Replace the following:

  • DATA_API_NAME: The name of the Data API custom resource

  • NAMESPACE: The namespace where the Data API custom resource is deployed

  • DATACENTER_NAME: The name of the datacenter

  • NODE_PORT: The port number for the nodePort service

  • CLUSTER_IP_PORT: The port number for the clusterIP service

Create or update the Data API custom resource with overrides:

kubectl apply -f DATA_API.yaml

Replace DATA_API.yaml with the name of the manifest file that contains the settings for your Data API custom resource.

Was this helpful?

Give Feedback

How can we improve the documentation?

© 2025 DataStax | Privacy policy | Terms of use | Manage Privacy Choices

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: +1 (650) 389-6000, info@datastax.com