Explanation
Scorecard levels
Catching a misconfigured resource before kubectl apply is much cheaper than debugging a broken rollout in production. Kix runs two kinds of checks when you build a cluster: always-on validation checks that stop the build if manifests have broken references or mismatched selectors, and scorecard rules that grade your cluster against security, reliability, and operational best practices.
The four scorecard levels
Section titled “The four scorecard levels”Not every policy question can be answered by looking at a single YAML document in isolation. Checking whether a container drops Linux capabilities only requires inspecting one Deployment, whereas checking whether a namespace has a default-deny NetworkPolicy requires seeing every resource in that namespace at once.
To give each rule the exact context it needs, Kix runs scorecard rules at four scopes:
| Level | What the rule sees | Example questions |
|---|---|---|
manifest | One rendered Kubernetes resource | Does every container set CPU and memory requests? Does this pod run as a non-root user? |
package | One active package instance and all resources it produces | Does the package declare a team owner in meta.owner? Are its third-party annotations backed by a dependency? |
namespace | All active instances and resources in one Kubernetes namespace | Does this namespace contain a NetworkPolicy or ResourceQuota? |
cluster | Every active instance and resource across the entire cluster | Are resource names and cross-namespace policies consistent across the whole build? |
The level of a rule describes what evidence it inspects, while severity is configured separately. A manifest rule can be a build-stopping error, and a cluster rule can be an informational hint.
Rules score what ships
Section titled “Rules score what ships”Scorecard rules evaluate the final compiled cluster after every helper and synthesis pass has run:
- Manifest and package rules see every resource attached to an instance, including resources created by typed builders and derived resources like generated
PodDisruptionBudgetandCiliumNetworkPolicyobjects. - Namespace and cluster rules run after dependency resolution has determined which instances are active. Optional instances (
optional = true) that were never pulled in by a consumer are excluded so dormant packages do not trigger false findings.
Because rules inspect the finished manifests, a policy check tests what Kix will actually apply to Kubernetes after defaults, overlays, and automatic derivations have run.
Findings and enforcement are separate decisions
Section titled “Findings and enforcement are separate decisions”When adopting a policy tool on an existing cluster, turning on all 30 built-in rules at once can produce a wall of errors that blocks every deployment until the whole backlog is cleaned up. Kix avoids that trap by separating a rule’s severity from the cluster’s enforcement cap (scorecard.maxSeverity):
- Each rule declares its own severity (
error,warning, orinfo), andscorecard.ruleOverrides(byRule,byOwner, andbyNamespace) can adjust that severity for specific rules, package owners, or namespaces. scorecard.maxSeveritythen caps the effective severity across the cluster. BecausemaxSeveritydefaults to"warning", even rules that declareseverity = "error"report as warnings on a new cluster rather than failing the build.- When your team is ready to enforce policy in CI, setting
scorecard.maxSeverity = "error"turns those error-severity findings into hard build failures without changing a single rule definition.
Capping a rule is different from disabling it (scorecard.ruleOverrides.byRule."<rule>".enabled = false). A capped rule still runs and appears in kix check (and kix check --sarif) output so you can track cleanup progress; a disabled rule is skipped entirely.
Cross-resource validation at cluster evaluation time
Section titled “Cross-resource validation at cluster evaluation time”Scorecards are designed for organizational standards and best practices where teams may want to phase in enforcement gradually or exempt a legacy namespace. Structural errors are different: if a Deployment mounts a ConfigMap that does not exist, or if a Service selector matches zero pods in its namespace, the manifest is broken and will fail in Kubernetes.
For that reason, Kix runs a separate suite of always-on cross-resource validation checks over the finished manifest set on every evaluation. These compiler checks are never capped by scorecard.maxSeverity and cannot be turned off with scorecard overrides:
- Target existence: Every workload
serviceAccountName, ConfigMap volume, PVCclaimName,PriorityClass, HPAscaleTargetRef,RoleBindingroleRef, and Ingress backendServicemust exist in the build (or be explicitly marked external withkix.untrackedRefor an import marker). - Selector and port coherence: Every
Service,NetworkPolicy, andPodDisruptionBudgetpod selector must match at least one workload pod template in its namespace, every namedtargetPorton a Service must exist on a selected container, and noJobpod template may match aServiceselector. - StorageClasses, CRDs, and single defaults: Every PVC or volume claim template
storageClassNamemust match a rendered or importedStorageClass(orPersistentVolume). Every custom resource outside Kubernetes’ built-in API groups must depend throughkix.run/depends-onon a CRD, CRD reference marker, orAPIServicethat serves its API version. At most one defaultStorageClass,IngressClass, or global-defaultPriorityClassmay exist in the cluster. - Secret and ConfigMap key verification: When a container reads a specific key by name (
secretKeyRef,configMapKeyRef, volumeitems, orsubPath), Kix verifies that the target ConfigMap data or Secret key declaration (kix.run/secret-keysorkix.run/import-secret-keys) actually includes that key.
Keeping structural validation separate from the scorecard means you can relax scorecard enforcement on a development cluster while still knowing that Kix will catch broken references and mismatched selectors before you deploy.