Minimizing Microservice Vulnerabilities
Required knowledge for the CKS certification.
Last reviewed: — verified against Kubernetes 1.36.
Microservice architectures multiply the surface that has to be secured — every service has its own dependencies, image, and Kubernetes spec. This page is the head reference for Domain 4 of the CKS exam (Minimize Microservice Vulnerabilities, 20%) and covers the four practical levers: base image choice, dependency hygiene, application-layer secrets, and pod-level resource controls.
Why Microservice Hardening Matters
The microservice layer is where most production CVEs land. A vulnerable Log4j, a left-behind debug image, an over-broad ServiceAccount, or a missing memory limit each turn into incidents at scale, because the same defect is replicated across every replica of the affected service. The practices below shrink that surface at four points:
- The base image — fewer packages mean fewer CVEs to track
- The dependency graph — caught early via SAST and SCA in CI
- The application configuration — secrets out of env vars, into mounted volumes or external stores
- The pod spec — resource limits, security context, and probe correctness
These complement rather than replace cluster-level hardening; assume PSA restricted, NetworkPolicy, and admission policy are already in place.
Microservice Hardening Domains
| Domain | Primary Risk | Key Control | Reference |
|---|---|---|---|
| Base image | Inherited CVEs from a heavy distro | Distroless / minimal UBI / Alpine | See "Base Image Comparison" below |
| Dependencies | Vulnerable libraries reach prod | SAST + SCA in CI; SBOM emitted per build | See "SAST vs SCA" below |
| Secrets | Plaintext credentials in env or image | External secret store, KMS-backed Secrets | Insecure Secrets Mitigation |
| Pod resources | Noisy-neighbour and DoS exposure | requests/limits plus LimitRange | Pod-Level Resources |
| Pod spec | Privileged escapes, host mounts | securityContext, drop capabilities, non-root | Pod Security Standards |
Topics Covered in This Section
Secure Development Practices
Integrate SAST (e.g., Snyk Code, Semgrep) into pull-request CI so that vulnerable patterns block merges. Pair with peer review focused on input validation, authn / authz boundaries, and external-call timeouts.
Dependency Management
Run Trivy or Grype on every build, fail the pipeline on HIGH/CRITICAL findings with no fixed version, and emit an SBOM (Syft) so downstream owners can match new CVEs against deployed images.
Container Security
Build on a minimal base image, set a non-root USER, and avoid shipping shells or package managers in production images. Combine with PSA restricted, readOnlyRootFilesystem: true, and a dropped capability set.
Secure Configuration Management
Never bake secrets into images or env vars. Mount Secrets via projected volumes, or front them with External Secrets Operator backed by Vault, AWS Secrets Manager, or GCP Secret Manager.
Key Articles
Base Image Comparison
Picking the right base image trims the most CVEs for the least effort. The four families below cover most production choices.
| Image | Package Manager | Typical Size | Default User | CVE Surface | Best Fit |
|---|---|---|---|---|---|
gcr.io/distroless/static | None | ~2 MB | nonroot (65532) | Smallest — only the binary's runtime | Statically-linked Go / Rust |
gcr.io/distroless/base-debian12 | None | ~20 MB | nonroot (65532) | glibc + ca-certs only | Dynamically-linked binaries |
| Alpine | apk | ~6 MB | root (override required) | musl libc; smaller package set | Tooling images, ephemeral containers |
| Red Hat UBI Minimal | microdnf | ~40 MB | root | Enterprise-supported package set | RHEL / OpenShift compliance |
| Debian Slim | apt | ~80 MB | root | Larger; full glibc / coreutils | Migrations from non-minimal images |
Recommendation: Default to a distroless image for new services, fall back to UBI Minimal where vendor support matters, and treat full Debian / Ubuntu base images as legacy.
SAST vs SCA: Pick Both, Run Early
SAST (Static Application Security Testing) scans source code for vulnerable patterns. SCA (Software Composition Analysis) scans dependencies for known CVEs. They are different controls and both belong in CI.
| Aspect | SAST | SCA |
|---|---|---|
| Target | Application source code | Direct + transitive dependencies |
| Catches | Injection, taint, weak crypto, logic flaws | CVEs in libraries and base images |
| Tools | Semgrep, Snyk Code, CodeQL, SonarQube | Trivy, Grype, Snyk Open Source, Dependabot |
| Runs in | Pre-commit / CI on source | CI on built image; periodically against deployed images |
| False-positive rate | Higher (taint analysis is conservative) | Lower (CVE matches are deterministic) |
| Best fit | Catch bugs before merge | Catch new CVEs before deploy and after |
Run SAST on every PR, SCA on every CI build, and re-run SCA continuously against deployed images so new CVEs published after deploy are caught.
Try It: Live YAML Security Analyzer
The microservice-level controls show up directly in the Pod spec — securityContext.runAsNonRoot, readOnlyRootFilesystem, resources.limits, dropped capabilities. Paste a manifest below to see how it scores against the baseline.
Version-Specific Notes (Kubernetes 1.36)
The microservice-layer surface has tightened in recent Kubernetes versions:
seccompProfile.type: RuntimeDefault— Cluster-default since 1.27 (SeccompDefault). Every workload gets the runtime's default seccomp profile unless overridden.- In-place pod resize — Beta in 1.27, GA in 1.33. Resource limits can be raised without recreating the pod, supporting safer right-sizing under load.
- User namespaces (
hostUsers: false) — GA in 1.33. Container root maps to an unprivileged host UID, blunting many in-container exploits. - Sidecar containers — GA since 1.33. Init containers with
restartPolicy: Alwaysare the supported pattern for service-mesh proxies, secret rotators, and log shippers. - Validating Admission Policy — GA since 1.30. CEL-based admission can enforce microservice-spec invariants (image registry whitelists, required resource limits) without a webhook.
Always check the Kubernetes deprecation guide before upgrading.
Hardening Principles for Microservices
Secure by Default
Build on a distroless or minimal-distro base image, run as a non-root UID, set readOnlyRootFilesystem: true, and drop all capabilities by default. Add capabilities back only when the workload demonstrably needs them.
Least Privilege
Mount only the Secrets and ConfigMaps the workload reads. Disable automountServiceAccountToken unless the pod calls the Kubernetes API. Scope NetworkPolicy to the exact services it talks to.
Defense in Depth
Pair admission-time controls (PSA, policy engines) with build-time checks (SAST, SCA, image scanning) and runtime detection (Falco, Tetragon). Each layer catches what the others miss.
Continuous Verification
Re-scan deployed images on a daily cadence — vulnerabilities published after deploy should not require a release before they are detected. Use Trivy Operator for in-cluster continuous scanning.
Conclusion
Microservice security is the compound effect of many small choices: a smaller base image, a tighter pod spec, a stricter dependency policy. Taken together, they remove most of the surface that production CVEs land on. Combine the practices linked here with the supply chain and cluster hardening sections for end-to-end coverage.