OpsKit
Free · no signup

Kubernetes YAML beautifier

Format, validate, and lint a manifest against 16 production rules. Convert between YAML and JSON. Everything runs in your browser — nothing is uploaded.

Input40 lines · YAML or JSON
[
  {
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
      "name": "payment-service",
      "labels": {
        "app": "payment-service"
      }
    },
    "spec": {
      "replicas": 1,
      "selector": {
        "matchLabels": {
          "app": "payment-service"
        }
      },
      "template": {
        "metadata": {
          "labels": {
            "app": "payment-service"
          }
        },
        "spec": {
          "hostNetwork": true,
          "containers": [
            {
              "name": "api",
              "image": "registry.internal/payment-service:latest",
              "ports": [
                {
                  "containerPort": 8080
                }
              ],
              "env": [
                {
                  "name": "DB_PASSWORD",
                  "value": "hunter2-in-plaintext"
                }
              ],
              "securityContext": {
                "privileged": true
              }
            }
          ]
        }
      }
    }
  },
  {
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
      "name": "payment-service"
    },
    "spec": {
      "selector": {
        "app": "payment-service"
      },
      "ports": [
        {
          "port": 80,
          "targetPort": 8080
        }
      ]
    }
  }
]
Valid YAML2 documents4 errors6 warnings6 info Runs locally — nothing leaves this tab

The 16 checks, and why each one matters

These are static versions of the checks OpsKit's deployment-guard agent runs before a merge. The paid kit runs them against your live cluster, with the evidence attached.

Errorimage-latest-tag

Image uses :latest or no tag

A mutable tag makes a rollout unreproducible — a restarted pod can pull different bytes than its siblings, and a rollback has nothing to roll back to.

Errorplaintext-secret-env

Secret-looking value in plain text

Credentials in env.value land in the manifest, in Git, and in `kubectl describe` output. Use secretKeyRef or an external secret store.

Errorprivileged-container

Privileged container

privileged: true disables nearly every container isolation boundary. A compromise becomes a node compromise.

Errorhost-namespace

Shares a host namespace

hostNetwork, hostPID, or hostIPC break the pod out of its own namespace and expose the node's interfaces and processes.

Warningmissing-resource-limits

No memory or CPU limit

Without limits a single leaking container can evict its neighbours. It is also the reason most OOMKill investigations end in ambiguity.

Warningmissing-resource-requests

No resource requests

The scheduler places pods by request, not usage. Missing requests produce BestEffort pods that get evicted first under pressure.

Warningmissing-probes

No readiness or liveness probe

Without a readiness probe a rollout sends traffic to a container that hasn't finished starting. Without liveness, a wedged process never restarts.

Warningruns-as-root

May run as root

runAsNonRoot is not set to true, so the container can run as UID 0 and a container escape starts with root on the node.

Warningallow-privilege-escalation

Privilege escalation not blocked

allowPrivilegeEscalation defaults to true. Setting it false stops setuid binaries from gaining more privileges than the parent process.

Warninghostpath-volume

hostPath volume

A hostPath mount ties the pod to one node's filesystem and is a common path to node-level privilege escalation.

Warningsingle-replica

Single replica

One replica means every node drain, rollout, and eviction is downtime. Two is the smallest number that survives a drain.

Infocapabilities-not-dropped

Linux capabilities not dropped

Dropping ALL and adding back only what's needed shrinks the syscall surface a compromised process can reach.

Infowritable-root-filesystem

Writable root filesystem

readOnlyRootFilesystem: true stops an attacker from dropping tooling into the image at runtime. Mount an emptyDir for genuine scratch space.

Infomissing-recommended-labels

Missing app.kubernetes.io/name

The recommended labels are what dashboards, cost tooling, and ownership resolution key on. Without them a workload is hard to attribute.

Infomissing-namespace

No explicit namespace

The object lands wherever kubectl's current context points. In a GitOps repo that is an accident waiting for a context switch.

Infomissing-pdb

No PodDisruptionBudget

Without a PDB a node drain can take every replica down at once. A budget makes voluntary disruption respect your availability target.

A linter reads your file. OpsKit reads your cluster.

Static checks catch what you wrote. They can't tell you why the pod is in CrashLoopBackOff right now. OpsKit gives your AI agent a read-only connection to the live cluster — and proposes the fix as a GitOps PR.