Securing containerized applications and microservices architectures
By Jonathan D. Steele | August 29, 2025
What should you know about securing containerized applications and microservices architectures?
Quick Answer: The article argues that securing containerized applications requires a defense-in-depth, shift-left approach across the entire supply chain and runtime—harden Dockerfiles and images, scan and sign artifacts in CI/CD, enforce least-privilege RBAC and network policies, protect secrets with external stores, and deploy runtime detection, observability, and incident playbooks so breaches can be contained and remediated quickly. Counterintuitively, it warns that small or "minimal" images are not inherently safe—vulnerable libraries can lurk in tiny images—so you must verify provenance, enforce signature checks and scanning, and rely on runtime controls rather than assuming a small footprint equals security.
— Jonathan D. Steele, Esq. (Security+, ISC2 CC, CEH)
Threat model and security principles
- Shift-left: detect and prevent issues during build and CI/CD.
- Least privilege: for images, containers, Kubernetes RBAC, and network policies.
- Defense in depth: multiple controls at build, deploy, runtime, and network layers.
- Immutable artifacts: build once, sign, and promote artifacts to environments.
- Observability and fast response: logging, auditing, and runtime detection.
Build-time and supply chain security
Fix many issues before runtime by securing source, dependencies, and images.
1) Harden Dockerfiles and images
Examples and best practices:
- Use minimal base images (e.g., distroless, Alpine) to reduce attack surface.
- Specify explicit versions for base images and packages.
- Run processes as non-root user inside container.
- Remove build-time tools from final image (multi-stage builds).
- Pin images by digest when deploying (immutable reference).
Example Dockerfile (multi-stage, non-root)
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGOENABLED=0 GOOS=linux GOARCH=amd64 go build -o app ./cmd/service
FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/app /app/app
USER 10001
ENTRYPOINT ["/app/app"]
2) Scan dependencies and images in CI
Integrate static analysis and vulnerability scanning into CI pipelines. Example tools: Trivy, Clair, Grype for image vulnerability scanning; Snyk/Dependabot for code dependencies; Checkov/terrafirma for IaC.
Example: scan built image with Trivy in CI
trivy image --severity HIGH,CRITICAL --exit-code 1 --no-progress myrepo/myapp:sha256-...
3) Sign and verify artifacts
Prevent deployment of tampered images by signing images and enforcing verification before deploy. Tools: cosign (sigstore), Notary/v2.
Sign an OCI image with cosign
cosign sign --key cosign.key ghcr.io/org/myapp@sha256:...
Verify before deployment
cosign verify ghcr.io/org/myapp@sha256:...
4) CI/CD pipeline safeguards
Your pipeline should include stages: build, static tests, dependency checks, image scan, image sign, push, and deploy gates. Enforce approval policies and image provenance checks in deployment stages.
Example pipeline stages
- Checkout & lint -> 2. Unit tests -> 3. Dependency scan -> 4. Build image ->
- Image scan (fail on high/critical) -> 6. Sign image -> 7. Push -> 8. Deploy with gate
Runtime security in Kubernetes and other orchestrators
Runtime protections detect and mitigate compromised containers, and reduce impact of breaches.
1) Pod security hardening
- Use Pod Security Admission (PSA) or OPA Gatekeeper policies to enforce Pod constraints: disallow privileged containers, restrict hostPath, require read-only root filesystem and non-root user.
- Set resource limits and requests to prevent DoS via resource exhaustion.
- Drop Linux capabilities; only add what's necessary.
Example Pod Security (psp-like) settings in PodSpec
securityContext:
runAsNonRoot: true
runAsUser: 10001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
containers:
- name: app
securityContext:
capabilities:
drop: ["ALL"]
resources:
requests:
Legal Protection Matters: Cybersecurity incidents often have significant legal implications. Our sister firm Steele Family Law helps Illinois families navigate complex legal situations with the same commitment to protection and discretion we bring to cybersecurity.
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
2) Network segmentation and policies
Example Kubernetes NetworkPolicy: allow traffic only from namespace "frontend"
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: backend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 8080
3) Service mesh / mTLS for service-to-service auth
4) Runtime detection and process protections
- Deploy runtime security agents (Falco, Sysdig, Aqua) to detect suspicious behavior: shell in container, privileged syscalls, unexpected outbound connections.
- Use kernel hardening and container runtime configurations: seccomp profiles, AppArmor, SELinux.
5) Control plane and API server protection
Lock down the orchestrator API: restrict access to Kubernetes API server, use MFA for admin access, and apply least-privilege RBAC. Enable audit logging and regularly review audit events for suspicious activity.
Example RBAC: read-only role for monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: monitoring
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
Secrets, keys, and configuration
Secrets must never be baked into images or stored unencrypted. Use a dedicated secret store and short-lived credentials.
- Use external secret stores: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager.
- In Kubernetes, use the Secrets Store CSI driver to mount secrets from external stores without persisting them in etcd.
- Enable encryption at rest for Kubernetes secrets (Envelope encryption using KMS).
- Prefer short-lived service tokens and dynamically provisioned credentials (e.g., Vault AppRole with leases, Kubernetes service account tokens with projected token expiration).
Example: mount secret with CSI Secrets Store (conceptual)
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myrepo/myapp:sha256:...
volumeMounts:
- name: secrets-store
mountPath: "/secrets"
volumes:
- name: secrets-store
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-provider"
Identity, authentication, and authorization
- Use short-lived service identities: Kubernetes service account tokens with projected tokens or workload identity (e.g., GKE Workload Identity).
- Centralize identity and SSO for developers and operators; enable MFA for privileged operations.
- Enforce RBAC and use policy engines (OPA/Gatekeeper) to enforce organizational policies in the cluster.
OPA/Gatekeeper sample constraint snippet (conceptual)
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyprivileged
spec:
crd:
spec:
names:
kind: K8sDenyPrivileged
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenyprivileged
denymsg {
input.review.object.spec.containers[].securityContext.privileged == true
msg = "Privileged containers are not allowed"
}
Logging, auditing, and incident response
Observability is critical for detection and fast response.
- Export Kubernetes audit logs to a centralized location and monitor for privilege escalations or abnormal API calls.
- Collect and aggregate container logs and metrics (Prometheus, Grafana, ELK/EFK) and create alerts for anomalous patterns.
- Use EDR and runtime anomaly detection to detect suspicious behavior inside containers.
- Have a playbook: isolate workloads (network policy or node quarantine), revoke compromised credentials, roll back to signed images, and investigate using audit data.
Practical checks and quick wins
Actionable checklist you can apply quickly:
- Enable image scanning in CI and block builds with high/critical findings.
- Sign images after build and verify signatures before deploy.
- Run containers as non-root and set read-only root filesystems.
- Enforce NetworkPolicies to limit cross-service communication.
- Use a secrets manager with short-lived credentials and avoid storing secrets in plaintext in git or images.
- Restrict Kubernetes API access with least-privilege RBAC and enable audit logging.
- Install runtime detection (e.g., Falco) to alert on suspicious container behavior.
Example workflows — from build to runtime
Two short workflow examples that tie recommendations together.
CI/CD pipeline flow
Build -> Static tests -> Dependency scan -> Build image -> Trivy scan -> Sign image (cosign) -> Push to registry -> Deploy via GitOps (ArgoCD/Flux) which verifies signature and image digest -> Post-deploy runtime policy checks (OPA) and runtime monitoring (Falco).
Compromise containment scenario
If a container is suspected compromised: (1) Use NetworkPolicy or service mesh to isolate the pod/namespace, (2) scale the pod down or cordon the node, (3) revoke any active credentials/keys used by that workload, (4) promote a signed clean image (rollback), (5) analyze audit logs and runtime alerts to determine root cause.
Common pitfalls to avoid
- Relying solely on images being "small" — even small images can contain vulnerable libraries.
- Leaving default service accounts with broad permissions in namespaces.
- Baking secrets into images or storing them in repo or plain Kubernetes Secrets without encryption.
- Assuming network isolation exists by default — you must explicitly define NetworkPolicies.
- Not enforcing signature verification or image provenance at deploy time.
---
Related Articles
- Cybersecurity Analysis: Securing containerized applications and microservices architectures
- The Overlooked Hole in Legal Tech: Why Shoddy Secure Coding Lets Confidential Cases Leak Quietly
- Transform Your 5G & Edge Security from Fragile to Fortress: The Only Guide You Need to Master Threats and Resilience in 30 Days
Your Security is Non-Negotiable
At SteeleFortress, we've protected hundreds of organizations from cyber threats.
- 24/7 Monitoring – We never sleep so you can
- Transparent Pricing – No hidden fees (billing by IntelliBill)
- Legal-Ready – Partner with Steele Family Law for incident response
Stop hoping you won't get breached.
Get the 15-point Security Audit Checklist that attackers don't want you to have. Plus weekly intel briefs - no fluff, no vendor pitches.
No spam. Unsubscribe anytime. We don't sell your data - we protect it.