Ephemeral Admission Checks
ksail workload validate --ephemeral and ksail workload scan --ephemeral add Kubernetes API admission checks to their normal offline checks. The mode is experimental and off by default. It requires a running Docker daemon and creates a separate Kind cluster with its own temporary kubeconfig.
# Select the overlay you intend to deploy.ksail workload validate ./k8s/overlays/test --include-crd-schemas --ephemeralksail workload scan ./k8s/overlays/test --ephemeralThe offline validation or security scan runs first. If it fails, KSail does not create a cluster. For valid input, KSail applies namespaces and CRDs, waits for CRD establishment, prepares ConfigMaps and Secrets, installs declared Helm charts and waits for their workloads and jobs, then submits the remaining resources through server-side apply with strict field validation. After chart installation, KSail also reapplies the bootstrap resources to check their updates against newly installed policies. An API rejection fails the command and identifies the affected resource.
Supply reviewed API context offline
Section titled “Supply reviewed API context offline”An enforcing Kyverno policy may read Kubernetes state through an apiCall context entry. Offline validation has no cluster credentials and fails closed when that response is unavailable. For state that can be represented safely in source control, declare exact responses in a fixture:
apiVersion: ksail.dev/v1alpha1kind: KyvernoAPICallResponsesresponses: - method: GET urlPath: /api/v1/namespaces/arc-runners body: metadata: annotations: lifecycle.example.com/state: baselineReference the fixture from ksail.yaml. Like rules and sourceDirectory, the path is relative to the directory you run KSail in, and the fixture must stay inside it, so the same setting works whichever directory you validate:
spec: workload: validation: kyvernoApiCallResponses: validation/kyverno-api-responses.yamlUse --kyverno-api-call-responses <path> for a one-run override. KSail matches the normalized HTTP method and URL path exactly, then hands the JSON body to Kyverno’s normal context loader, including the policy’s jmesPath. Duplicate or unmatched requests and malformed fixtures are errors. The fixture cannot enable HTTP service calls or a live Kubernetes connection. KSail reads the fixture only when Kyverno policies are on and a directory is validated, and a fixture inside the validated directory is not itself validated as a workload.
Treat this file like any other test fixture: use synthetic values when the policy only needs a shape or state, and do not commit credentials or production-only data. Ephemeral admission remains the appropriate check when a reviewed static response cannot represent the behavior.
The admission phase has one ten-minute deadline shared by its API operations and chart installations. Cluster deletion runs with a separate two-minute deadline, including after cancellation or admission failure. Cleanup errors are reported together with the original failure. The user’s existing clusters and kubeconfig are not used.
Select one workload
Section titled “Select one workload”Pass a single Kustomize root, a YAML file, or a directory containing plain YAML manifests. When the selected directory is a Kustomize root, its build output drives both chart installation and resource application, so the chosen overlay’s values and patches are used. KSail does not separately apply that root’s bases.
A directory containing nested Kustomize roots without a root of its own is ambiguous: select the desired overlay explicitly. Duplicate resource identities, YAML List wrappers, and Flux Kustomization descriptors are rejected. Expand lists into separate YAML documents and select the workload directory referenced by a Flux Kustomization.
The selected input must contain no ${...} expressions, including literal shell expressions in ConfigMaps or Secrets. The experimental mode conservatively rejects these expressions because it cannot distinguish them from unresolved Flux substitutions. The synthetic values used by offline schema validation are not deployment values. An unresolved chart source or values reference also fails the admission preparation instead of silently reducing coverage.
HelmRelease declarations and their HelmRepository/OCIRepository sources are consumed by Helm installation. Chart-generated resources are not separately reapplied by KSail. ConfigMaps and Secrets needed by charts must be present in the selected workload, together with Namespace declarations for their non-builtin namespaces. Preparation fails before provisioning if these namespaces are missing. Helm post-renderers are unsupported and rejected. Charts install in the order they appear in the selected manifest stream; KSail does not infer Flux dependsOn ordering.
What a successful check proves
Section titled “What a successful check proves”Success means the selected resources passed the offline gate and their apply requests were accepted by the throwaway API server. The admission path submits every directly declared resource, including kinds excluded from the offline scan or schema pass. Bootstrap resources are created before chart installation and checked again as updates afterward; policies scoped only to creation cannot retroactively check their initial creation.
Admission alone does not prove that operators finished reconciling or that their generated resources satisfy your validation rules. The isolated cluster also does not reproduce external services, cloud permissions, production admission policies, or production secrets unless they are explicitly declared in the selected input.
Validate generated children
Section titled “Validate generated children”Add --ephemeral-children to inspect descendants of the workloads you directly submit:
ksail workload validate ./k8s/overlays/test \ --ephemeral --ephemeral-children \ --ephemeral-observation-wait 30s \ --include-crd-schemas --rules ./validation-rules.yamlAfter admission, KSail waits for the requested duration, then collects a snapshot of resources linked to the submitted workloads through Kubernetes owner references. It follows nested descendants by their server-assigned identities, so a same-named replacement cannot be mistaken for the original owner. Collection errors, replaced roots, and an empty child inventory fail the command. Teardown also runs when collection or child validation fails.
The wait defaults to 30 seconds and must be positive and no longer than five minutes. Collection has a two-minute limit within the existing ten-minute ephemeral deadline. Inventories larger than 10,000 resources fail with an explicit error. A longer wait can accommodate a slower controller, but does not prove that it has finished.
Observed children receive the same schema checks, configured CEL rules, kind exclusions, and missing-schema behavior as the source. --include-crd-schemas uses CRDs from the selected source and its rendered charts. Add --kyverno-policies to evaluate children against Kyverno policies directly declared in the source, with its declared Namespace context. Policies supplied only by installed charts still participate in admission; they are not imported into this offline policy pass. Child manifests stay in memory rather than being written to disk.
This is a bounded snapshot, not complete operator coverage. It excludes resources without a valid owner-reference chain, children of custom resources supplied only inside charts, and resources deleted before collection. A successful result does not establish readiness or predict resources created later. workload scan --ephemeral performs admission checks only; scanning generated children and operator-specific readiness remain in the ephemeral validation roadmap.