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.
[
{
"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
}
]
}
}
]
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.
image-latest-tagImage 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.
How a bad image tag surfaces as CrashLoopBackOffplaintext-secret-envSecret-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.
What to audit before giving an agent cluster accessprivileged-containerPrivileged container
privileged: true disables nearly every container isolation boundary. A compromise becomes a node compromise.
Container isolation and agent accesshost-namespaceShares a host namespace
hostNetwork, hostPID, or hostIPC break the pod out of its own namespace and expose the node's interfaces and processes.
missing-resource-limitsNo 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.
Finding the real memory ceiling on an OOMKilled podmissing-resource-requestsNo resource requests
The scheduler places pods by request, not usage. Missing requests produce BestEffort pods that get evicted first under pressure.
Why requests, not usage, decide schedulingmissing-probesNo 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.
Probes, restarts, and rollout failureruns-as-rootMay 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.
allow-privilege-escalationPrivilege escalation not blocked
allowPrivilegeEscalation defaults to true. Setting it false stops setuid binaries from gaining more privileges than the parent process.
hostpath-volumehostPath volume
A hostPath mount ties the pod to one node's filesystem and is a common path to node-level privilege escalation.
single-replicaSingle replica
One replica means every node drain, rollout, and eviction is downtime. Two is the smallest number that survives a drain.
capabilities-not-droppedLinux capabilities not dropped
Dropping ALL and adding back only what's needed shrinks the syscall surface a compromised process can reach.
writable-root-filesystemWritable root filesystem
readOnlyRootFilesystem: true stops an attacker from dropping tooling into the image at runtime. Mount an emptyDir for genuine scratch space.
missing-recommended-labelsMissing 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.
missing-namespaceNo explicit namespace
The object lands wherever kubectl's current context points. In a GitOps repo that is an accident waiting for a context switch.
Namespace-scoped access, enforced at RBACmissing-pdbNo PodDisruptionBudget
Without a PDB a node drain can take every replica down at once. A budget makes voluntary disruption respect your availability target.
What these checks look like against a live cluster
A linter reads the file you wrote. These walk through what the same problems look like once they're running — and what evidence identifies each one.
CrashLoopBackOff
Diagnosing a crash loop from evidence
Exit codes, previous-container logs, and the recent rollout that caused it.
OOMKilled
Limit too low, or a real leak?
Telling a bad memory limit apart from an application that genuinely leaks.
Pending pods
Why the scheduler won't place it
Quotas, taints, PVC binding, and unallocated DRA resource claims.
Kubernetes 1.36
The sidecar that CrashLoops inside a Running pod
Sidecars report into initContainerStatuses, so naive triage calls the pod healthy.
Least privilege
Scoping an agent to specific namespaces
Namespace allowlists and label selectors, enforced at RBAC rather than in a prompt.
Alternatives
How this compares to k8sgpt and kubectl-ai
Three of the four alternatives are free and open source. Where each one fits.
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.