Skip to content
Back to Blog
·9 min read·technology

Container Image Security for Indian DevOps Teams: A Guide

Container image security starts at the FROM line. Learn how Indian DevOps teams scan Docker images with Trivy, use distroless bases, and secure CI pipelines.

BR

Bachao.AI Research Team

Cybersecurity Research

Scan Your Attack Surface

Security exposure this creates

Unpatched vulnerabilities in your tech stack are the #1 entry point for breaches targeting Indian businesses. Here's what to watch.

Container image security is one of the most overlooked risks in modern software delivery. Before a single container runs in production, the image it is built from may already carry known vulnerabilities, hardcoded secrets, bloated attack surface, or packages pulled from unverified sources. For Indian DevOps teams shipping containerised applications — on AWS, GCP, or bare metal — scanning Docker images in CI is not optional. It is the difference between shipping clean software and shipping a pre-compromised payload. This guide covers what goes wrong inside container images, how to scan them with Trivy, Grype, and Clair, and how to build a secure image pipeline that fits Indian team constraints.

Why Container Images Are a Security Minefield

The typical Docker image is not a clean slate. It inherits everything in the base image — and base images are often years out of date. A Node.js 16 Alpine image pulled from Docker Hub in 2025 ships with dozens of known CVEs. The developer who writes the FROM node:16-alpine line is unaware of this; the CI pipeline that builds and ships the image never checks.

NIST SP 800-190, the definitive US government guide on container security, identifies five primary image risk categories: vulnerable components in the image, malicious content introduced during the build, inclusion of unnecessary software, configuration weaknesses, and embedding sensitive data. Every one of these applies to Indian teams.

The Sysdig 2024 Cloud-Native Security and Usage Report found that 87% of container images running in production had high or critical vulnerabilities. The problem is upstream: developers trust base images, base image maintainers update on their own schedule, and registries serve stale layers silently.

87%Container images running in production with high or critical vulnerabilities (Sysdig 2024)
A large shareOf container images found to contain secrets, credentials, or API keys embedded in image layers (Aqua Security research)

The risks group into five distinct categories, each requiring a different control.

Vulnerable Base Images

The FROM line is the first attack surface. Debian Buster, Ubuntu 20.04, and older Node or Python official images carry packages with dozens of known CVEs. Attackers actively scan for containers running these versions. Selecting a minimal or distroless base image eliminates the majority of this surface before any code is written.

Outdated Application Packages

Dependencies installed via apt, pip, npm, or yarn during the build inherit whatever vulnerabilities exist in their ecosystem at build time. A package-lock.json locked to a specific version months ago may include packages with high-severity CVEs published since the lock. Scanning at build time catches these before they reach registry.

Hardcoded Secrets and Credentials

Build pipelines frequently leak secrets into image layers. A RUN aws configure line, a .env file copied before a subsequent RUN rm, or an SSH key added during build — all of these persist in intermediate layers even if deleted in a later step. The image layer is immutable and the secret is recoverable with docker history. NIST SP 800-190 Section 4.1.5 explicitly flags this as a critical image risk.

Supply-Chain and Base Image Tampering

Pulling FROM ubuntu:latest from Docker Hub means trusting Docker Hub. Images with typosquatted names, compromised accounts, or injected malware have appeared in public registries. Supply-chain attacks on container base images are increasing. Signing and verifying images using Cosign and Sigstore is the only reliable defence.

Bloated Images with Unnecessary Tooling

Images built with full build toolchains — gcc, curl, git, bash — expand the attack surface drastically. An attacker who achieves RCE in a container with curl installed can trivially exfiltrate data or download next-stage payloads. A distroless image or a scratch-based binary has no shell, no package manager, and no network utilities for an attacker to use.

The Container Image Vulnerability Pipeline

graph TD A[Dev writes Dockerfile] --> B[Multi-stage build] B --> C[Minimal base image selected] C --> D[Image built in CI] D --> E[Trivy or Grype scan] E --> F{Vulnerabilities found?} F -->|CRITICAL or HIGH| G[Block merge - fix required] F -->|LOW or MEDIUM| H[Log and continue] G --> I[Dev patches base image or dependency] I --> D H --> J[Sign image with Cosign] J --> K[Push to private registry] K --> L[Registry admission check] L --> M[Deploy to production] style A fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style B fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style C fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style D fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style E fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style F fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style G fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style H fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style I fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style J fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style K fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style L fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style M fill:#1e3d2f,stroke:#10B981,color:#e2e8f0

Sources of Vulnerabilities in Container Images

pie title Sources of Container Image Vulnerabilities (illustrative) "Vulnerable OS packages in base image" : 38 "Outdated app dependencies" : 27 "Hardcoded secrets in layers" : 15 "Unnecessary tooling and bloat" : 12 "Supply-chain and registry tampering" : 8

Know your vulnerabilities before attackers do

Run a free VAPT scan — takes 5 minutes, no signup required.

Book Your Free Scan

Scanning Tools: Trivy, Grype, and Clair

Three open-source tools dominate container image scanning. Each has different strengths and CI integration patterns.

ToolStrengthsBest ForCI Integration
Trivy (Aqua Security)Fastest scan, scans OS + app layers + secrets, SARIF outputMost teams — lowest frictionGitHub Actions, GitLab CI, Docker build step
Grype (Anchore)Deep SBOM generation with Syft, accurate CVE matchingTeams needing Software Bill of MaterialsJenkins, GitLab CI
Clair (Red Hat/Quay)Deep integration with Quay registry, REST APIEnterprise registry-native scanningQuay.io, Kubernetes admission
For most Indian teams starting out, Trivy is the right default. It installs as a single binary, scans a local image in under two minutes, and outputs results in JSON, SARIF, or a human-readable table. A basic GitLab CI step looks like this:
yaml
image-scan:
  stage: test
  image: aquasec/trivy:latest
  script:
    - trivy image --exit-code 1 --severity CRITICAL,HIGH $IMAGE_TAG

The --exit-code 1 flag causes the pipeline to fail on any CRITICAL or HIGH finding. This is the most important configuration choice: scanning without blocking is auditing theatre.

⚠️
WARNING
Scanning on pull request is not enough. Base image vulnerabilities are published continuously. An image that scanned clean last week may have new CVEs today. Run image scans on a schedule — daily or on every deploy — not only on code change.

Minimal and Distroless Base Images

The single highest-impact change most teams can make is replacing a general-purpose base image with a minimal or distroless one. Google's distroless images contain only the application runtime and its direct dependencies — no shell, no package manager, no debug tools.

Before:

dockerfile
FROM node:18

After:

dockerfile
FROM gcr.io/distroless/nodejs18-debian12

The distroless image eliminates an entire class of OS-package vulnerabilities and removes attacker tooling from the runtime. Combined with a multi-stage build, it also dramatically reduces image size.

A multi-stage build separates the build environment (which needs compilers, dev dependencies, and tools) from the runtime image (which needs only the compiled output). This prevents build secrets, dev certs, and unnecessary binaries from reaching production.

dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM gcr.io/distroless/nodejs18-debian12 AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/index.js"]
🛡️
SECURITY
Never copy .env files, SSH keys, or AWS credentials into a Docker image, even temporarily. Use build secrets (--secret flag in BuildKit), environment variables injected at runtime, or a secrets manager. Anything copied into a layer — then deleted — is still recoverable from image history.

Image Signing and Provenance

Signing container images gives downstream consumers — your CI runner, your Kubernetes admission controller, your registry — cryptographic proof that a specific image was built by your pipeline and has not been tampered with.

The current standard is Cosign from the Sigstore project, backed by Google, Red Hat, and the Linux Foundation. Cosign signs images using OIDC tokens from your CI provider (GitHub Actions, GitLab CI) with no key management required in keyless mode.

A CI signing step:

bash
cosign sign --yes $REGISTRY/$IMAGE@$DIGEST

Verification before deploy:

bash
cosign verify --certificate-identity-regexp=".*" \
  --certificate-oidc-issuer="https://accounts.google.com" \
  $REGISTRY/$IMAGE@$DIGEST

For Indian teams on GitLab self-hosted or AWS CodePipeline, Cosign's keyless flow works with any OIDC-compatible CI provider. The signature is stored in the registry alongside the image, requiring no separate signature storage.

Registry Security

Pushing images to Docker Hub public repositories is a security choice, not a default. Public repositories expose your image layers, your dependency tree, and potentially embedded secrets to anyone with a pull command.

Practical controls for Indian teams:

    1. Use a private registry: AWS ECR, Google Artifact Registry, GitLab Container Registry, or Harbor self-hosted
    2. Enable immutable image tags — prevent tag overwrites that could allow a compromised image to be silently substituted
    3. Enable lifecycle policies to delete unscanned or stale images
    4. Require vulnerability scanning before images are made available for deployment (AWS ECR Enhanced Scanning, GCR Artifact Analysis)
    5. Restrict registry pull access to specific service accounts and CI runners — not developer laptops
💡
TIP
AWS ECR supports enhanced scanning using Inspector, which continuously re-scans images already in the registry when new CVEs are published. This catches the "clean yesterday, vulnerable today" scenario that CI-only scanning misses.

Building a Secure Image Pipeline Checklist

ControlTool / MethodPriority
Scan image for OS vulnerabilitiesTrivy, Grype, ClairP0 — block on CRITICAL/HIGH
Scan for hardcoded secretsTrivy secret scan, GitLeaksP0 — block on any finding
Use minimal or distroless base imageGoogle distroless, Alpine, scratchP0
Multi-stage builds to separate build and runtimeDockerfile best practiceP0
Sign images and verify before deployCosign / SigstoreP1
Use private registry with immutable tagsECR, GAR, GitLab, HarborP1
SBOM generation for audit trailSyft + GrypeP1
Scheduled re-scan of registry imagesECR Enhanced Scan, Trivy cronP1
Restrict registry pull to CI/CD onlyIAM policies, registry access controlsP2
Lock base image digests not tagsFROM ubuntu@sha256:...P2

Scanning in CI: Making It Stick

The most common failure mode is installing a scanner but not blocking on findings. Teams add Trivy to their pipeline, see a wall of CVEs, suppress the exit code so the pipeline does not break, and return to the same state they were in before.

An effective rollout has three phases:

Phase 1 — Audit mode (week 1): Scan all images, log findings, set --exit-code 0. Build a baseline of what your current images look like. This surfaces the scale of the problem without blocking anything.

Phase 2 — Block on CRITICAL (week 2–3): Set --exit-code 1 --severity CRITICAL. Fix or accept-risk the CRITICAL findings. Most CRITICAL findings resolve by updating the base image.

Phase 3 — Block on HIGH (week 4+): Extend the block to HIGH severity. This is where dependency updates become necessary. Most teams reach steady state within a sprint.

Bachao.AI's automated VAPT platform includes external scanning of containerised web services as part of its scanning suite. Dhisattva AI Pvt Ltd built the platform to give Indian teams a starting point for validating their external attack surface — a free VAPT scan covers web-facing endpoints and helps identify what is reachable from the outside before container hardening fixes reach it internally.

🎯Key Takeaway
Container image security starts at the FROM line, not at runtime. Switch to distroless or minimal base images, scan with Trivy on every build and fail the pipeline on CRITICAL/HIGH findings, strip secrets from layers using BuildKit secrets, and sign images before pushing to your private registry. These four controls eliminate the majority of image-layer risk before a single pod starts.

What Indian DevOps Teams Get Wrong

Most Indian startup and mid-market teams treat container security as an infrastructure concern and leave it to the platform team. But the platform team does not write the Dockerfiles — developers do. Closing this gap requires two things: shifting scanning left into the developer workflow (pre-commit hooks, IDE plugins, CI gates) and making the default image choice the secure one (distroless, pinned digest, private registry).

CERT-In's advisories have increasingly flagged container and cloud-native vulnerabilities as the vector in incidents affecting Indian IT companies. The attack path is consistent: public-facing containerised service, vulnerable OS package in base image, known CVE exploited, lateral movement inside the cluster. The image scan that would have caught the CVE was either missing or set to non-blocking mode.

Check the Bachao.AI blog for related guides on Kubernetes cluster hardening, secrets management in cloud-native environments, and CI/CD pipeline security.

Frequently Asked Questions

What is the fastest way to start scanning Docker images in an existing CI pipeline?
Install Trivy as a single binary or use the aquasec/trivy:latest Docker image in your pipeline. Add a scan step after your image build step with trivy image --exit-code 1 --severity CRITICAL,HIGH <your-image-tag>. This takes under 10 minutes to set up and immediately starts blocking on critical vulnerabilities.
Should I scan base images or only my final application image?
Scan the final application image — it contains everything from every stage that ended in your runtime layer. If you use multi-stage builds correctly, intermediate build stages do not ship. The final image scan catches OS package CVEs, application dependency CVEs, and embedded secrets in one pass.
What is a distroless image and does it work for all applications?
Distroless images, maintained by Google at gcr.io/distroless, contain only the language runtime and its dependencies — no shell, no apt, no curl. They work well for Go (single binary), Java, Node.js, and Python applications. They do not work for applications that need to run shell scripts at startup or require system package installation at runtime. Use Alpine as a middle ground for those cases.
How do I prevent secrets from being embedded in Docker image layers?
Use BuildKit's --secret flag to inject secrets during build without persisting them in the layer. Never use COPY .env . or ARG AWS_SECRET_KEY — ARG values appear in docker history output and are recoverable. Use a secrets manager (AWS Secrets Manager, HashiCorp Vault) and inject values at runtime via environment variables, not at build time.
What is image signing and do small teams actually need it?
Image signing creates a cryptographic attestation that a specific image digest was produced by your CI pipeline and has not been modified since. For teams deploying to Kubernetes, signing + admission control (Kyverno or OPA) prevents an attacker who compromises your registry from substituting a malicious image. Small teams on AWS ECR or GCR can start with Cosign keyless signing at no cost.
How often should container images be rescanned?
Scan on every build (CI gate), and rescan images already in the registry daily or weekly. New CVEs are published continuously; an image that was clean at build time may be vulnerable 30 days later because a new CVE was assigned to a package it already contained. AWS ECR Enhanced Scanning and GCR Artifact Analysis support continuous re-scanning automatically.
BR

Bachao.AI Research Team

Cybersecurity Research

AI-powered security research and threat intelligence from the Bachao.AI team. Covering the latest vulnerabilities, CVEs, and cybersecurity developments affecting Indian businesses.

Get cybersecurity insights for Indian SMBs

Weekly vulnerability alerts, DPDP compliance tips, and security guides. No spam — unsubscribe anytime.

We respect your privacy. Your email is never shared.

Find out if you're exposed to this class of threat

Free automated scan — risk score in under 2 hours. No credit card required.

Scan Your Attack Surface
Find your vulnerabilitiesStart free scan →