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, and security configurations for Dockerfiles.

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

Included Guardrails

This policy includes 6 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 Dockerfiles include required OCI labels for traceability. Common labels: org.opencontainers.image.source, version, maintainer.

dockerfile labels oci labels image metadata
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

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 (empty = no requirement)

Documentation

View on GitHub

Container Guardrails

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

Overview

This policy plugin validates container definitions (Dockerfiles, Containerfiles) 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 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

Required Data

This policy reads from the following Component JSON paths:

Path Type Provided By
.containers.definitions[] array dockerfile 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]  # Only include specific policies
    # with:
    #   allowed_registries: "docker.io,gcr.io,ghcr.io"
    #   required_labels: "org.opencontainers.image.source"

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

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
Book a Demo
See it work with your own use cases
See How It Works