Hamburger Cross Icon
Kubernetes Guardrails - Lunar Policy for Deployment And Infrastructure

Kubernetes Guardrails

Policy Stable Deployment And Infrastructure

Enforce Kubernetes best practices including manifest validation, resource limits, probes, PodDisruptionBudgets, and HPA configurations for production readiness.

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

Included Guardrails

This policy includes 11 guardrails that enforce standards for your deployment and infrastructure.

Guardrail

valid

Validates that all Kubernetes manifests in the repository are syntactically correct and conform to K8s schema. Invalid manifests will fail deployment.

kubernetes manifest validation yaml kubeconform
View Guardrail
Guardrail

requests-and-limits

Ensures all containers have CPU and memory requests and limits defined. Missing resource specs can cause scheduling failures and noisy neighbor issues.

resources cpu limits memory limits requests qos
View Guardrail
Guardrail

probes

Requires liveness and readiness probes on all containers. Probes enable Kubernetes to detect unhealthy pods and route traffic correctly.

liveness probe readiness probe health checks pod health
View Guardrail
Guardrail

min-replicas

Enforces minimum replica counts on HorizontalPodAutoscalers. Ensures services maintain capacity during scaling events and failures.

hpa replicas high availability autoscaling
View Guardrail
Guardrail

pdb

Requires PodDisruptionBudgets for Deployments and StatefulSets. PDBs protect availability during voluntary disruptions like node drains.

pdb pod disruption budget availability node drain
View Guardrail
Guardrail

non-root

Requires containers to run as non-root users via securityContext. Running as root inside containers violates least privilege principles.

security context non-root runAsNonRoot least privilege
View Guardrail
Guardrail

host-users

Requires workload PodSpecs to set hostUsers: false. User Namespaces (GA in Kubernetes v1.36) map container UIDs to unprivileged host UIDs so that a container escape no longer hands the attacker root on the node. Complements non-root — that check drops privilege inside the container; this one isolates UIDs across the kernel boundary. Target cluster must be on K8s >=1.36; workloads that legitimately need host UIDs (e.g. log shippers reading host paths) can be opted out via include/exclude in lunar-config.yml.

user namespaces hostUsers container escape least privilege kernel boundary
View Guardrail
Guardrail

host-network

Fails when workload PodSpecs set hostNetwork: true. Sharing the host's network namespace bypasses NetworkPolicy enforcement, exposes node-local services to the pod, and gives a compromised container direct access to the node's interfaces (and any cleartext traffic on them). Legitimate hostNetwork users (CNI agents, node-local proxies, host-bound exporters) can opt out via include/exclude in lunar-config.yml.

hostNetwork network namespace NetworkPolicy bypass container escape least privilege
View Guardrail
Guardrail

host-pid

Fails when workload PodSpecs set hostPID: true. Sharing the host's PID namespace lets the container see, signal, and (with the right capabilities) attach to every process on the node, undermining process isolation and aiding lateral movement after a container compromise. Workloads that need it (e.g. node-level monitoring agents) can opt out via include/exclude in lunar-config.yml.

hostPID PID namespace process isolation container escape least privilege
View Guardrail
Guardrail

host-ipc

Fails when workload PodSpecs set hostIPC: true. Sharing the host's IPC namespace exposes node-wide System V IPC and POSIX shared memory to the container, which can be abused to read or tamper with other workloads' shared-memory state. Workloads that genuinely need host IPC can opt out via include/exclude in lunar-config.yml.

hostIPC IPC namespace shared memory container escape least privilege
View Guardrail
Guardrail

min-kubectl-version

Ensures the kubectl version used in CI meets the minimum required version. Old kubectl clients may miss security fixes or lack support for current cluster APIs.

kubectl version ci/cd compatibility security
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
min_replicas Optional 3 Minimum replicas required for HPAs (default 3)
max_limit_to_request_ratio Optional 4 Maximum ratio of limits to requests for CPU/memory (default 4)
min_kubectl_version Optional 1.28 Minimum kubectl version required in CI (semver, e.g. "1.28")

Documentation

View on GitHub

Kubernetes Guardrails

Enforces Kubernetes best practices for production-ready workloads.

Overview

This policy validates Kubernetes manifests against industry best practices including resource limits, health probes, PodDisruptionBudgets, and security configurations. It helps ensure your K8s workloads are production-ready and resilient.

Policies

This policy provides the following guardrails (use include to select a subset):

Policy Description Failure Meaning
valid Validates K8s manifest syntax Manifest has YAML or schema errors
requests-and-limits Checks CPU/memory requests and limits Container missing resource specs
probes Requires liveness and readiness probes Container missing health probes
min-replicas Enforces minimum HPA replicas HPA minReplicas below threshold
pdb Requires PodDisruptionBudgets Deployment/StatefulSet missing PDB
non-root Requires non-root security context Container may run as root
host-users Requires PodSpecs to set hostUsers: false (K8s ≥1.36 user namespaces) Container UIDs are not isolated from host UIDs — a container escape gives the attacker root on the node
host-network Forbids hostNetwork: true on PodSpecs Workload shares the host network namespace — bypasses NetworkPolicy and exposes node interfaces
host-pid Forbids hostPID: true on PodSpecs Workload shares the host PID namespace — can see, signal, and potentially attach to processes on the node
host-ipc Forbids hostIPC: true on PodSpecs Workload shares the host IPC namespace — can read or tamper with node-wide shared memory
min-kubectl-version Enforces minimum kubectl version in CI kubectl client used in CI is below threshold

Required Data

This policy reads from the following Component JSON paths:

Path Type Provided By
.k8s.manifests[] array k8s collector
.k8s.workloads[] array k8s collector
.k8s.hpas[] array k8s collector
.k8s.pdbs[] array k8s collector
.k8s.cicd.cmds[] array k8s collector (cicd sub-collector)

Note: Ensure the k8s collector is configured before enabling this policy.

Installation

Add to your lunar-config.yml:

collectors:
  - uses: github://earthly/lunar-lib/collectors/k8s@v1.0.0
    on: [kubernetes]

policies:
  - uses: github://earthly/lunar-lib/policies/k8s@v1.0.0
    on: [kubernetes]
    enforcement: report-pr
    # include: [valid, requests-and-limits, probes]  # Only run specific checks
    # with:
    #   min_replicas: "3"
    #   max_limit_to_request_ratio: "4"
    #   min_kubectl_version: "1.28"

Examples

Passing Example

A compliant component with proper resource specs, probes, and security context:

{
  "k8s": {
    "manifests": [
      {"path": "deploy/deployment.yaml", "valid": true}
    ],
    "workloads": [
      {
        "kind": "Deployment",
        "name": "payment-api",
        "namespace": "payments",
        "path": "deploy/deployment.yaml",
        "host_users": false,
        "host_network": false,
        "host_pid": false,
        "host_ipc": false,
        "containers": [
          {
            "name": "api",
            "has_resources": true,
            "has_requests": true,
            "has_limits": true,
            "has_liveness_probe": true,
            "has_readiness_probe": true,
            "runs_as_non_root": true
          }
        ]
      }
    ],
    "pdbs": [
      {"name": "payment-api-pdb", "target_workload": "payment-api"}
    ]
  }
}

Failing Example

A component missing resources, probes, and security configuration:

{
  "k8s": {
    "workloads": [
      {
        "kind": "Deployment",
        "name": "my-app",
        "namespace": "default",
        "path": "deploy/app.yaml",
        "host_users": true,
        "host_network": true,
        "host_pid": true,
        "host_ipc": true,
        "containers": [
          {
            "name": "app",
            "has_resources": false,
            "has_requests": false,
            "has_limits": false,
            "has_liveness_probe": false,
            "has_readiness_probe": false,
            "runs_as_non_root": false
          }
        ]
      }
    ],
    "pdbs": []
  }
}

Failure messages:

  • deploy/app.yaml: Deployment default/my-app container 'app' missing resource requests
  • deploy/app.yaml: Deployment default/my-app container 'app' missing livenessProbe
  • deploy/app.yaml: Deployment default/my-app container 'app' should set securityContext.runAsNonRoot: true
  • deploy/app.yaml: Deployment default/my-app should set spec.hostUsers: false (Kubernetes user namespaces, GA in v1.36)
  • deploy/app.yaml: Deployment default/my-app should not set spec.hostNetwork: true (workload shares the host network namespace)
  • deploy/app.yaml: Deployment default/my-app should not set spec.hostPID: true (workload shares the host PID namespace)
  • deploy/app.yaml: Deployment default/my-app should not set spec.hostIPC: true (workload shares the host IPC namespace)

Remediation

When this policy fails, resolve it by:

  1. For valid failures: Fix YAML syntax errors or invalid K8s fields in the manifest
  2. For requests-and-limits failures: Add resources.requests and resources.limits for CPU and memory
  3. For probes failures: Add livenessProbe and readinessProbe to each container
  4. For min-replicas failures: Increase spec.minReplicas in your HPA to meet the threshold
  5. For pdb failures: Create a PodDisruptionBudget that selects your workload's pods
  6. For non-root failures: Add securityContext.runAsNonRoot: true to the container or pod spec
  7. For host-users failures: Add spec.hostUsers: false to the PodSpec (or spec.template.spec.hostUsers: false for Deployments/StatefulSets/DaemonSets/Jobs/CronJobs). Requires Kubernetes ≥1.36 in the target cluster. Privileged workloads that must share the host user namespace (e.g. log shippers reading host paths, kubelets, container-runtime sidecars) can use include/exclude in lunar-config.yml to opt out.
  8. For host-network failures: Remove spec.hostNetwork: true from the PodSpec. Workloads that legitimately need the host network (CNI agents, node-local proxies, host-bound metrics exporters) can opt out via include/exclude in lunar-config.yml.
  9. For host-pid failures: Remove spec.hostPID: true from the PodSpec. Node-level monitoring agents that need a host-wide process view can opt out via include/exclude in lunar-config.yml.
  10. For host-ipc failures: Remove spec.hostIPC: true from the PodSpec. Workloads that genuinely need host IPC (rare — usually legacy shared-memory consumers) can opt out via include/exclude in lunar-config.yml.
  11. For min-kubectl-version failures: Upgrade the kubectl client in your CI pipeline (e.g., pin azure/setup-kubectl@v4 or setup-kubectl action to a newer version, or update the installed kubectl on self-hosted runners)

Consumers who want any of these surfaced without blocking can pin enforcement: report-pr at config time — but that's a consumer-side knob; the checks themselves just pass or fail.

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 AGENTS.md, engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 200+ built-in guardrails.

Works with any process
check AI agent rules & prompt files
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Automate Now
Paste your AGENTS.md or manual process doc and get guardrails in minutes
Book a Demo