Blog Post

Shifting Left: Embedding Security into Development

04.03.2025

Shifting Left: Embedding Security into Development

Introduction

As organizations adopt microservices on Kubernetes, integrating security and compliance early—“shifting left”—becomes essential. By embedding security checks into code and infrastructure pipelines, you catch misconfigurations and vulnerabilities before they ever reach production. In this guide, we’ll explore how to weave security into every stage of your development lifecycle, from Infrastructure-as-Code (IaC) validation to container image scanning, so your teams can move fast without compromising safety.

1. Static Analysis & IaC Validation

Why it matters:
Misconfigurations in Kubernetes manifests or Terraform modules can introduce serious risks—overly permissive RBAC, open network ports, or insecure volume mounts. Catching these issues before merging code prevents expensive remediation later.

Tools & Techniques:

  • Policy-as-Code with OPA/Gatekeeper or Kyverno:
    Store your security policies (e.g., “no privileged containers,” “no hostPath volumes,” “network policies must exist”) in a Git-controlled repository. Use Open Policy Agent (OPA) Gatekeeper or Kyverno to enforce these policies against your IaC and Kubernetes manifests.
  • IaC Scanners (Checkov, Terrascan, tfsec):
    Integrate an IaC scanner into your CI pipeline to validate Terraform or Helm charts. For example, Checkov inspects Terraform plans and flags misconfigurations (e.g., AWS security groups open to 0.0.0.0/0).
  • GitHub Actions or GitLab CI Pipelines:
    Configure your CI pipeline to run static checks on each pull request. If a manifest fails policy validation or a Terraform plan flags a security issue, block the merge until it’s fixed.

Best Practices:

  1. Treat policies as versioned code. Store policy definitions in a separate “policy repo” and require pull requests for policy updates—ensuring review and audit history.
  2. Fail fast. If a manifest or Terraform module fails validation, mark the CI job as failed and provide developers clear feedback about the violation.
  3. Use minimal base images. When scanning container images later, smaller attack surfaces lead to fewer vulnerabilities.

2. Container Image Scanning

Why it matters:
Even if your Kubernetes manifests are locked down, deploying a container image with known CVEs can expose critical weaknesses. Continuous image scanning ensures that you only deploy safe, patched images.

Tools & Techniques:

  • Trivy:
    An open-source scanner that inspects container images for OS-level and application dependencies vulnerabilities. Add a Trivy step in your CI pipeline to scan each built image.
  • Clair or Anchore:
    These engines perform deeper vulnerability analysis. You can integrate them into your build process or run them as a scheduled scan on private registries.
  • Dockerfile Best Practices:
    • Pin dependency versions.
    • Use multi-stage builds to minimize final image size.
    • Choose slim or distroless base images (e.g., alpine:3.18, gcr.io/distroless/base) to reduce surface area.

Best Practices:

  1. Scan each layer. Before building your application layer, scan the base image so you know it’s up to date.
  2. Block builds on high-severity CVEs. Configure your scanner to treat CVEs with a CVSS score above a threshold (e.g., 7.0) as blocking.
  3. Re-scan on new CVE disclosures. Schedule a nightly cron job to re-scan all images in your registry and alert the team if a new vulnerability appears.

3. Embedding Security into the Developer Workflow

Why it matters:
Developers are the first line of defense. By providing tools and guardrails directly in their workflow, you reduce friction and ensure security checks happen automatically.

Techniques:

  • Pre-Commit Hooks & Local Validation:
    Use pre-commit hooks (e.g., pre-commit.com) to run kube-linter or conftest locally before code is committed. Catch obvious manifest errors and policy violations early.
  • GitOps-Based Policy Enforcement:
    When your GitOps operator (Argo CD or Flux) syncs new commits, it should automatically verify that applied manifests conform to your policy bundles. If a violation is detected at reconcile time, send a Slack alert or mark the sync as “OutOfSync.”
  • IDE Integrations:
    Provide developers with IDE plugins that highlight risky YAML patterns or flag deprecated APIs. For example, the yaml-language-server with custom schema extensions can underline missing securityContext fields.

Best Practices:

  1. Shift left on secret management. Integrate HashiCorp Vault or Sealed Secrets so that developers never write plain-text secrets.
  2. Standardize logging of violations. Funnel all policy violations into a single observability dashboard (e.g., Grafana) so security teams can track trends and recurring issues.
  3. Educate with documentation. Maintain a concise “Secure Kubernetes Patterns” document in your developer wiki. Include examples of properly configured PodSecurity, RBAC, and NetworkPolicy resources.

Conclusion

Embedding security into development—shifting left—is not a one-time project but an ongoing practice. By integrating static analysis, IaC validation, and continuous image scanning into your CI/CD pipelines, and by providing developers with real-time feedback in their workflows, you ensure that vulnerabilities and misconfigurations are caught early. Treat policies as code, automate enforcement with OPA/Gatekeeper or Kyverno, and continuously monitor for new threats. This proactive approach lets you innovate rapidly on Kubernetes without sacrificing security or compliance.

“Insert an inspiring quote or excerpt here.”

Stefan Krempel
Stefan Krempel - CEO