Validate Kubernetes manifest files and kustomizations using kubeconform.
This command validates individual YAML files and kustomizations in the specified path.
If no path is provided, the path is resolved in order:
1. spec.workload.sourceDirectory from ksail.yaml (if a config file is found and the field is set)
2. The default source directory when spec.workload.sourceDirectory is unset ("k8s" directory)
3. The current directory (fallback when no ksail.yaml config file is found)
1. Validates individual YAML files (patch files referenced in a kustomization file via patches,
patchesStrategicMerge, or patchesJson6902 are excluded — they are not valid standalone
Kubernetes resources and are validated as part of the kustomize build output instead)
2. Validates kustomizations by building them with kustomize and validating the output
Flux variable substitutions are resolved before validation using type-aware placeholders:
- ${VAR} (bare, no default): when a JSON schema type is available, substitutes a typed
placeholder derived from the schema for the field ("placeholder" for strings, 0 for
integers, true for booleans); when no schema type is available, it falls back to the
string value "placeholder"
- ${VAR:-default} / ${VAR:=default}: when a schema type is available, uses the default
value parsed according to the field schema type (e.g., "3" → int 3 for integer fields);
when no schema type is available, the default is parsed using YAML-native type inference
- Mixed text (e.g., "prefix.${VAR}"): substitutes "placeholder" in string context
Schema lookups use a local disk cache and require no network access. When no cached
JSON schema is available, placeholders fall back to strings with YAML-native parsing.
By default, Kubernetes Secrets are skipped to avoid validation failures due to SOPS fields.
ksail workload validate [PATH] [flags]
--ephemeral EXPERIMENTAL: run offline checks, then check workload admission in an isolated throwaway Kind cluster with declared Helm charts installed and ready (guaranteed teardown; off by default). Add --ephemeral-children to also validate observed descendants.
--ephemeral-children EXPERIMENTAL: validate an observed snapshot of owner-linked descendants of directly submitted workloads (requires --ephemeral; fails if none are observed; does not prove operator convergence)
--ephemeral-observation-wait duration Wait after admission before collecting children (positive, at most 5m; requires --ephemeral-children) (default 30s)
--ignore-missing-schemas Ignore resources with missing schemas (default true)
--include-crd-schemas Derive kubeconform schemas from CustomResourceDefinition manifests in the path so that custom resources whose CRD ships in the repo are validated instead of skipped (off by default; a CRD that cannot be converted is warned and skipped)
--kyverno-api-call-responses string Path, relative to the working directory, to a reviewed offline response fixture for Kyverno Kubernetes apiCall context entries. Exact method and URL-path matches only; missing responses fail closed and no live cluster or service access is enabled. Overrides spec.workload.validation.kyvernoApiCallResponses from ksail.yaml.
--kyverno-policies Evaluate the source's own Kyverno ClusterPolicy and Policy validate rules, and its CEL-based ValidatingPolicy and NamespacedValidatingPolicy validations, against the rendered manifests, as if each document were being created. On by default when ksail.yaml sets spec.cluster.policyEngine to Kyverno, off otherwise; --kyverno-policies=false turns it off. Each kustomization is evaluated against the policies in its own rendered output: a policy delivered by a different kustomization is not seen, loose YAML files are not evaluated, a document is evaluated in the namespace it declares (a Flux targetNamespace is not applied, so a policy that depends on the namespace of a namespaced document that declares none is reported as a warning), and other policies.kyverno.io kinds are not supported. A ValidatingPolicy that calls the http library, or a CEL lookup of cluster, registry or global-context data, cannot be evaluated offline. A classic policy's Kubernetes apiCall context requires a reviewed --kyverno-api-call-responses fixture; the fixture never enables live cluster or service access, and a missing response fails closed. Namespace labels come from the kustomization's own Namespaces first, then from a Namespace another kustomization renders, unless two render it with different labels. For an unrendered Namespace, selectors are evaluated only when Kubernetes' immutable kubernetes.io/metadata.name label determines the result; other labels remain unknown. Repeated unknown-namespace warnings are grouped by policy, rule, namespace and reason, with evaluation, resource and source counts and a representative example. A rule a cluster would enforce fails validation; an audit-only failure or a rule that cannot be evaluated offline is reported as a warning.
--rules string Path to a YAML CEL rules file. Each rule's CEL expression is evaluated against every rendered document (bound to the 'object' variable); an error-severity violation fails validation, a warning-severity violation is reported without failing. Overrides spec.workload.validation.rules from ksail.yaml.
--schema-location strings Additional kubeconform schema locations (local directory or URL/path template) for CRDs with missing or stale CRDs-catalog entries, so they are validated against a supplied schema instead of skipped (merged with spec.workload.validation.schemaLocations from ksail.yaml)
--skip-helm-render Skip rendering HelmReleases before validation (validate the HelmRelease CR as-is). By default, charts are rendered in-process and the rendered manifests are validated.
--skip-kinds strings Additional Kubernetes kinds to skip during validation (merged with spec.workload.validation.skipKinds from ksail.yaml)
--skip-secrets Skip validation of Kubernetes Secrets (default true)
--strict Enable strict validation mode
--benchmark Show per-activity benchmark output
--config string Path to config file (default: ksail.yaml found via directory traversal)
--experimental Enable experimental (unstable) commands and features