Hamburger Cross Icon
Container Guardrails - Lunar Policy for Devex Build And Ci

Container Guardrails

Policy Stable Devex Build And Ci

Enforce container best practices including tag stability, registry allowlists, required labels, build traceability, and security configurations.

Add container to your lunar-config.yml:
uses: github://earthly/lunar-lib/policies/container@v1.0.0

Included Guardrails

This policy includes 7 guardrails that enforce standards for your devex build and ci.

Guardrail

no-latest

Prevents use of the :latest tag (explicit or implicit) in base images. Using :latest creates non-reproducible builds and makes debugging difficult.

dockerfile latest tag reproducible builds image tags
View Guardrail
Guardrail

stable-tags

Requires base images to use stable tags: digests (sha256:...) or full semver (1.2.3). Partial versions like "node:20" can change unexpectedly and break builds.

semver image digest version pinning tag policy
View Guardrail
Guardrail

allowed-registries

Restricts base images to approved container registries only. Prevents supply chain attacks from untrusted image sources.

container registry supply chain security registry policy
View Guardrail
Guardrail

required-labels

Ensures containers have required labels, checking both Dockerfile LABEL instructions and docker build --label flags. A label present in either source satisfies the requirement.

container labels oci labels build labels image metadata git sha
View Guardrail
Guardrail

healthcheck

Requires a HEALTHCHECK instruction in the final stage of multi-stage builds. Enables container orchestrators to detect and restart unhealthy containers.

healthcheck kubernetes container orchestration docker health
View Guardrail
Guardrail

user

Requires a USER instruction to run the container as a non-root user. Running as root inside containers is a security risk and violates least privilege.

non-root container security least privilege USER instruction
View Guardrail
Guardrail

build-tagged

Requires container builds to use an explicit image tag via -t/--tag. Untagged builds produce anonymous images that cannot be tracked or deployed.

docker build image tags container registry build tagging
View Guardrail

How Guardrails Fit into Lunar

Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.

Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.

Learn How Lunar Works
1
Integrations Gather Data
Collectors extract metadata from code, CI pipelines, tool outputs, and scans
2
{ } Centralized as JSON
All data merged into each component's unified metadata document
3
Guardrails Enforce Standards This Policy
Real-time feedback in PRs and AI workflows

Required Integrations

This policy evaluates data gathered by one or more of the following integration(s). Make sure to enable them in your lunar-config.yml.

Configuration

Configure this policy in your lunar-config.yml.

Inputs

Input Required Default Description
allowed_registries Optional docker.io Comma-separated list of allowed registries
required_labels Required Comma-separated list of required labels checked across Dockerfile and build commands (empty = no requirement)

Documentation

View on GitHub

Container Guardrails

Enforces best practices for container definitions and builds including tag stability, registry allowlists, required labels, build traceability, and security configurations.

Overview

This policy plugin validates container definitions (Dockerfiles) and CI build commands against common best practices and security requirements. It helps ensure consistent, secure, and reproducible container builds across your organization.

Policies

This plugin provides the following policies (use include to select a subset):

Policy Description Failure Meaning
no-latest No :latest tags (explicit or implicit) Image uses :latest tag (explicit or implicit)
stable-tags Tags must be digests or full semver (e.g., 1.2.3) Image uses unstable tag (partial version, branch name, etc.)
allowed-registries Images must come from allowed registries Image pulled from registry not in allowlist
required-labels Required labels must be present (Dockerfile or build command) Missing one or more required labels
healthcheck HEALTHCHECK instruction must be present Final stage missing HEALTHCHECK instruction
user USER instruction must be present Final stage missing USER instruction
build-tagged Container builds must use explicit -t/--tag Build command missing image tag

Required Data

This policy reads from the following Component JSON paths:

Path Type Provided By
.containers.definitions[] array docker collector (dockerfile sub-collector)
.containers.builds[] array docker collector (build-cicd sub-collector)

Installation

Add to your lunar-config.yml:

policies:
  - uses: github://earthly/lunar-lib/policies/container@v1.0.0
    on: ["domain:your-domain"]
    enforcement: report-pr
    # include: [no-latest, stable-tags, build-tagged]  # Only include specific policies
    # with:
    #   allowed_registries: "docker.io,gcr.io,ghcr.io"
    #   required_labels: "org.opencontainers.image.source,git_sha"

Examples

Passing Example

{
  "containers": {
    "definitions": [
      {
        "path": "Dockerfile",
        "valid": true,
        "base_images": [
          { "reference": "golang:1.21.5-alpine", "image": "golang", "tag": "1.21.5-alpine" },
          { "reference": "gcr.io/distroless/static:nonroot", "image": "gcr.io/distroless/static", "tag": "nonroot" }
        ],
        "final_stage": {
          "user": "nonroot",
          "has_healthcheck": true
        },
        "labels": {}
      }
    ]
  }
}

Failing Examples

Using :latest tag (fails no-latest, stable-tags)

{
  "containers": {
    "definitions": [
      {
        "path": "Dockerfile",
        "valid": true,
        "base_images": [
          { "reference": "node:latest", "image": "node", "tag": "latest" }
        ]
      }
    ]
  }
}

Using unstable tag (fails stable-tags)

{
  "containers": {
    "definitions": [
      {
        "path": "Dockerfile",
        "valid": true,
        "base_images": [
          { "reference": "node:20-alpine", "image": "node", "tag": "20-alpine" }
        ]
      }
    ]
  }
}

Using disallowed registry (fails allowed-registries)

{
  "containers": {
    "definitions": [
      {
        "path": "Dockerfile",
        "valid": true,
        "base_images": [
          { "reference": "my-private-registry.com/app:1.0.0", "image": "my-private-registry.com/app", "tag": "1.0.0" }
        ]
      }
    ]
  }
}

Remediation

no-latest / stable-tags

Replace unstable tags with:

  • Digest (most stable): alpine@sha256:abc123...
  • Full semver (stable): alpine:3.18.4

Avoid:

  • Implicit latest: FROM alpine
  • Explicit latest: FROM alpine:latest
  • Partial versions: FROM node:20 or FROM node:20-alpine

allowed-registries

Use images from approved registries only. Update your Dockerfile or request the registry be added to the allowlist.

required-labels

Add the required labels to your Dockerfile:

LABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.version="1.0.0"

healthcheck

Add a HEALTHCHECK instruction:

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost/health || exit 1

user

Add a USER instruction to run as non-root:

USER nonroot
# or
USER 1000:1000

build-tagged

Add an explicit -t/--tag flag to your docker build command:

docker build -t myregistry.io/app:v1.2.3 .

required-labels

Labels can be added in either the Dockerfile or the build command:

# In Dockerfile (static labels)
LABEL org.opencontainers.image.source="https://github.com/org/repo"
# In build command (dynamic labels)
docker build -t app:v1 --label git_sha=$GITHUB_SHA .

Open Source

This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.

View Repository

Ready to Automate Your Standards?

See how Lunar can turn your engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 100+ built-in guardrails.

Works with any process
check Infrastructure conventions
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Automate Now
Turn any process doc into guardrails
Book a Demo