Back to Checks
kubernetes

API Server pod uses only strong cryptographic TLS cipher suites

apiserver_strong_ciphers_only
Service: apiserverSeverity: medium
OfficialBuilt-inVerified
Categories:encryptioncluster-security
Resource Type:Pod

Kubernetes API server restricts TLS to strong cipher suites by configuring --tls-cipher-suites to only modern values such as TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, and TLS_CHACHA20_POLY1305_SHA256

Prowler logoProwlerprowler-provider-kubernetes

Risk

Permitting weak or mixed cipher suites enables TLS downgrades and cryptanalytic attacks, undermining confidentiality and integrity of API traffic.

Attackers could intercept or alter requests, steal tokens, and pivot to compromise the control plane.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks apiserver_strong_ciphers_only

Recommendation

Limit ciphers to modern AEAD suites and remove legacy entries in --tls-cipher-suites.

  • Enforce a high --tls-min-version (prefer VersionTLS13).
  • Periodically review crypto policy and rotate keys.
  • Apply defense in depth: restrict API exposure and require strong client auth.

Remediation

NativeIaC

# Minimal kube-apiserver manifest snippet enforcing only strong TLS ciphers
apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - name: kube-apiserver
    command:
    - kube-apiserver
    - --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256  # FIX: restricts ciphers to strong TLS 1.3 suites only

Other

1SSH to each control plane node
2Open /etc/kubernetes/manifests/kube-apiserver.yaml
3In spec.containers[].command, add or replace the flag:
4- --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256
5Save the file; the kubelet will automatically restart the API server
6Repeat on all control plane nodes
7Verify the flag is present on the running pod's command args

Check Code

from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
    apiserver_client,
)

default_apiserver_strong_ciphers = [
    "TLS_AES_128_GCM_SHA256",
    "TLS_AES_256_GCM_SHA384",
    "TLS_CHACHA20_POLY1305_SHA256",
]


class apiserver_strong_ciphers_only(Check):
    def execute(self) -> Check_Report_Kubernetes:
        findings = []
        for pod in apiserver_client.apiserver_pods:
            report = Check_Report_Kubernetes(metadata=self.metadata(), resource=pod)
            report.status = "PASS"
            report.status_extended = f"API Server is configured with strong cryptographic ciphers in pod {pod.name}."
            strong_ciphers_set = False
            for container in pod.containers.values():
                strong_ciphers_set = False
                # Check if strong ciphers are set in "--tls-cipher-suites"
                for command in container.command:
                    if command.startswith("--tls-cipher-suites"):
                        configured_ciphers = set(command.split("=")[1].split(","))
                        allowed_ciphers = set(
                            apiserver_client.audit_config.get(
                                "apiserver_strong_ciphers",
                                default_apiserver_strong_ciphers,
                            )
                        )
                        if configured_ciphers.issubset(allowed_ciphers):
                            strong_ciphers_set = True
                if not strong_ciphers_set:
                    break

            if not strong_ciphers_set:
                report.status = "FAIL"
                report.status_extended = f"API Server is not using only strong cryptographic ciphers in pod {pod.name}."

            findings.append(report)
        return findings