The Kyverno writeup makes one point: RBAC decides who may create a Pod and never opens it, so whatever is inside the manifest is judged later, by admission. This runs those checks here instead, so you can see the verdict without a cluster.
Nothing leaves this page. Cmd or Ctrl and Enter also runs it.
How to use it
Paste one document, or a whole file of them separated by ---. Each document is audited on its
own and gets its own card, labelled with its kind and name, so a bundle of twenty resources reads as twenty
verdicts rather than one pile. The button in the corner loads a deliberately bad example if you would
rather see the output before trusting it with your own. Cmd or Ctrl with Enter runs the audit from the
keyboard.
Read the groups from the top down, because they are ordered by how hard the failure is. The first group is
a flat rejection by the API server. The middle groups are policy: the second and third are what
PodSecurity enforces, the fourth is real access that no profile will stop. The last group is
my opinion and is labelled as such, so you can ignore it without missing anything the cluster cares about.
Nothing is uploaded. The parser, the schema and every rule run inside this page, so the manifest never leaves your browser and there is no server here to log it. That said, a Secret is still a secret: this page cannot see it, but your clipboard and your screen can.
What it understands
Pods and the six kinds that carry a pod template, which are Deployment, StatefulSet, DaemonSet, ReplicaSet, Job and CronJob, go through every layer. Role, ClusterRole, RoleBinding, ClusterRoleBinding, Service, Ingress, NetworkPolicy, ServiceAccount and PersistentVolume go through the schema and the access checks. Any other built-in kind is still checked against the schema. A resource from a CRD, a Kyverno policy or an Argo application, is skipped rather than guessed at, because its shape lives in the cluster and not in anything this page can read.
What it checks
First, whether the API server would accept the shape at all. The full OpenAPI schema that ships with
Kubernetes 1.37 is bundled into this page, so a misspelled field, a value of the wrong type, a missing
required field or a kind that does not exist in that apiVersion is caught here, exactly as
kubectl apply would catch it. This is the layer that rejects a manifest before Pod Security
ever looks at it.
On top of the schema there are the cross field rules the API server enforces in code, which no schema can
express: a selector that does not match its own pod template, a nodePort on a ClusterIP service, a cron
schedule without five fields, privileged together with
allowPrivilegeEscalation: false, an unmasked /proc without
hostUsers: false, and a host port that differs from the container port under
hostNetwork. Each of those was confirmed against a real API server, not taken from
documentation.
Then the rules from the two Pod Security Standards profiles that Kubernetes ships and that
PodSecurity enforces when you label a namespace. Baseline blocks the known escapes:
privileged containers, host namespaces, hostPath volumes, host ports, added capabilities beyond a small
set, unsafe sysctls, unconfined seccomp and AppArmor, SELinux overrides, unmasked /proc, host
probes and Windows HostProcess. Restricted adds the hardening on top: drop every capability, no privilege
escalation, run as non-root with a non-zero UID, an explicit seccomp profile and a short allowlist of
volume types.
Pod Security only covers pods, so everything else in a manifest goes through a second set of checks,
grouped as dangerous by default. Roles and ClusterRoles are read for wildcards, for the
escalate, bind and impersonate verbs, for read access to secrets and
for pods/exec and nodes/proxy. Bindings are checked for cluster-admin and for
subjects as broad as system:authenticated. A Service is flagged when it publishes itself
outside the cluster or claims arbitrary external addresses, an Ingress when it carries no TLS, a
NetworkPolicy when it selects everything and allows everything, a PersistentVolume when it is backed by a
node path.
The last group is advice and is opinionated on purpose: an unpinned image tag, missing requests or limits, no probes, a writable root filesystem, the default service account, a mounted token nothing uses, a single replica. None of it is a Pod Security rule, all of it is worth fixing, and pretending any of it was part of the standard would be the kind of small lie this site tries not to tell.
Where the rules come from
The schema is generated straight from the OpenAPI specification that ships with Kubernetes, pinned to the
1.37 release, all 862 definitions of it. The Pod Security rules are written from the nineteen checks in the
pod-security-admission source rather than from a summary of them, which is how the wrong claim
that readOnlyRootFilesystem belongs to the restricted profile was kept out of here. The cross
field rules were not read anywhere: each one was found by feeding a manifest to a running API server and
reading what came back.
The whole thing is then checked against a real cluster, and not with examples I thought of myself, because those only cover what I already suspected. A generator takes ten valid manifests and breaks them systematically: it drops each field in turn, changes the type of each field, adds fields that do not exist, and applies twenty two separate security violations. Every one of the resulting 464 manifests, across twenty kinds, goes through both this page and a Kubernetes 1.37 API server with a server side dry run, and every disagreement is a bug in here. That run currently disagrees on nothing.
It found plenty when it first ran: six inputs that crashed the page outright, thirty nine rules the API server enforces in code that were missing here, and three checks that fired on manifests the cluster accepts. Separately, three hundred and eleven live objects pulled straight out of a running cluster produce no schema complaints at all, which is the number that matters most: a tool that cries wolf on working manifests is worse than no tool.
How the documents relate
A file is usually a bundle, so the documents in it are checked against each other as well. A Service whose selector matches no pod template in the file, an Ingress pointing at a Service that is not there, a pod asking for a service account or mounting a ConfigMap that nothing defines, two objects of the same kind with the same name in the same namespace: these are ordinary mistakes that no single document reveals. They are reported as advice and worded as what they are, missing from this file rather than missing from the cluster, because a file is often only part of a larger set.
What it does not do
It reads a manifest, not a cluster. It cannot see the namespace label that decides which profile applies, the mutating webhooks that will rewrite the object before validation, or any policy you wrote yourself in Kyverno or Gatekeeper. A clean result here means the two built-in profiles have no objection, not that your cluster will accept it.
If you want the real verdict, the writeup shows how to get one in about ten minutes, and a ready-made cluster removes even the setup.