How to Ensure Your Docker & Harbor Machine Images Are Secure
Securing your machine images—whether built with Docker or stored in Harbor—is critical to protecting your infrastructure from attacks, vulnerabilities, and supply-chain risks. This guide covers best practices across the entire lifecycle: image creation, scanning, registry security, and runtime protection.
1. Secure Your Docker Image Build Process
Use Minimal Base Images
Choose images with the smallest attack surface:
alpinedistrolessscratch
Avoid large OS images unless absolutely necessary.
Pin Base Image Versions
Never use latest.
Use explicit versions:
FROM python:3.11.6-alpine
This ensures your image builds are deterministic and secure.

Image Source: Docker Blog – © Docker Inc.
Original article: https://www.docker.com/blog/docker-for-node-js-developers-5-things-you-need-to-know-not-to-fail-your-security/
Avoid Secrets in Images
Do not bake sensitive data into Docker images:
No API keys
No SSH keys
No passwords
Use:
environment variables
Docker secrets
external secret managers (Vault, AWS Secrets Manager, etc.)
Use Multi-Stage Builds
Multi-stage builds remove build-time tools and reduce image size:
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o app
FROM alpine
COPY --from=builder /app/app /usr/local/bin/app
ENTRYPOINT ["app"]
Run as a Non-Root User
Always drop root privileges:
USER appuser
This prevents privilege escalation attacks.
Prefer Distroless Images
Distroless images contain:
no shell
no package manager
no unnecessary binaries
This dramatically reduces vulnerabilities.
Example:
FROM gcr.io/distroless/python3
Use SBOM (Software Bill of Materials)
Generate an SBOM to track everything inside your image:
syft myimage:1.0 -o cyclonedx-json > sbom.json
SBOMs are essential for supply-chain security.
2. Scan Images with Security Tools
Use vulnerability scanners before pushing.
Trivy (most recommended):
trivy image myimage:1.0
Docker Scan (Snyk):
docker scan myimage:1.0
Always scan:
during local development
in CI/CD
after pushing to Harbor
3. Use Harbor’s Security Features
Harbor is one of the most secure container registries available. Use its full capabilities.
Enable Vulnerability Scanning
Harbor integrates with:
Trivy
Clair
Enable:
automatic scans on push
scheduled periodic scans
Harbor will show:
vulnerabilities
severity levels
fix availability
Block Pulling Vulnerable Images
Enable policy:
“Prevent images with severity ≥ High from being pulled”
This ensures only safe images can be deployed.
Use Image Tag Immutability
Prevent someone from overwriting critical tags (like prod or latest).
In Harbor UI:
Project → Tag Rules → Enable Tag Immutability
This prevents tampering.
Enable Content Signing (Notary)
Use Docker Content Trust or Notary v2:
export DOCKER_CONTENT_TRUST=1
docker push harbor.mycompany.com/app:1.0
Only signed images can be pulled.
RBAC & Access Controls
Use Harbor’s RBAC model:
Developers → push-only
Ops → pull-only
Admin → manage settings
Never allow anonymous pushes.
Enable HTTPS Everywhere
Secure Harbor registry endpoints to prevent MITM attacks.
4. Secure Kubernetes Runtime (Where Your Images Run)
Even if images are secure, your Kubernetes cluster must enforce security policies.
Require Images From Harbor Only
Use Kyverno:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-harbor-images
spec:
validationFailureAction: enforce
rules:
- name: only-harbor
match:
resources:
kinds: ["Pod"]
validate:
message: "Only Harbor images are allowed."
pattern:
spec:
containers:
- image: "harbor.mycompany.com/*"
Block Running as Root
spec:
rules:
- name: no-root
match:
resources:
kinds: ["Pod"]
validate:
pattern:
spec:
containers:
- securityContext:
runAsNonRoot: true
Require Signed Images Only
If using Cosign/Notary:
cosign sign harbor.mycompany.com/app:1.0
Admission controllers block unsigned images.
Runtime Threat Detection
Tools like:
Falco
Sysdig
eBPF-based detection
These monitor containers for:
unexpected shell access
suspicious syscalls
privilege escalation attempts
5. CI/CD Pipeline Enforcement
Security must be automated.
Your CI/CD pipeline should:
Lint Dockerfile
Build image
Scan with Trivy
Generate SBOM
Sign image
Push to Harbor
Harbor rescans
Deployment allowed only if image passes
This enforces organization-wide standards.
6. Organizational Security Practices
Use Internal Golden Base Images
Store internal, hardened base images in Harbor:
base-images/
Update them regularly.
Image Retention & Cleanup
Automatically remove:
unused images
untagged layers
images with unfixable CVEs
Harbor supports retention policies.
Audit Logging
Harbor provides logs for:
pull/push events
tag changes
user actions
Use logs for compliance and detection.
7. End-to-End Secure Image Lifecycle (Summary)
1. Developer Stage
Uses secure base images
Scans locally
No secrets in Dockerfile
2. CI/CD Stage
- Build → Scan → SBOM → Sign → Push
3. Harbor Stage
Auto scanning
Tag immutability
Signed images enforced
4. Kubernetes Stage
Only Harbor images
Only signed images
No root containers
5. Runtime
- eBPF/Falco monitoring
This creates a fully secure container image supply chain.
Conclusion
Securing Docker and Harbor images requires a layered approach:
building secure images
enforcing security in Harbor
applying strict Kubernetes policies
monitoring containers at runtime
By following this guide, you ensure every part of the image lifecycle is protected—from creation to deployment.
