How-to guide Policy, CI, and compliance
Add scorecard rules
Enable built-in policy checks and add a custom rule to a cluster.
Scorecard rules run while Kix evaluates a cluster. Every built-in rule set runs by default. Narrow the set when you want fewer checks, and add custom rules for policy specific to your packages or organization.
This guide assumes the cluster is defined with kix.buildCluster.
Choose the built-in rule sets
Section titled “Choose the built-in rule sets”scorecard.rules defaults to kix.rules, the four built-in categories:
security, reliability, governance, and architecture. Setting the
option replaces that default, so name every set you want to keep:
scorecard.rules = { inherit (kix.rules) security reliability;};The attribute name becomes the rule category. For example,
kix.rules.reliability.hasProbes is reported as reliability.hasProbes.
To keep the whole built-in set and change one rule, leave rules alone and
use an override instead. See
Disable scorecard rules
and
Override scorecard severity.
Add a custom rule
Section titled “Add a custom rule”Place custom rules under a category of your own. This tested package-level
rule applies only to packages that advertise the reverse-proxy capability,
then checks their evaluated configuration:
custom.proxyMaxBodySizeMustBeExplicit = { description = "Reverse-proxy gateways must set maxBodySize explicitly (not the 1m default)."; level = "package"; severity = "error"; tags = [ "reliability" "kix-examples" ];
# Only run on reverse-proxy packages. `appliesTo` receives the # package metadata directly, so this checks `meta.provides`. appliesTo = { meta, ... }: builtins.elem "reverse-proxy" (meta.provides or [ ]);
check = { config, instanceName, ... }: if (config.maxBodySize or "") == "1m" then [ { message = "instance '${instanceName}' uses the default maxBodySize '1m'. " + "nginx rejects larger request bodies — set this explicitly."; } ] else [ ]; };Add the rule inside scorecard.rules. Its full name is
custom.proxyMaxBodySizeMustBeExplicit. Because setting rules replaces the
default, merge the custom category into the built-in set to keep both:
scorecard.rules = kix.rules // { custom.proxyMaxBodySizeMustBeExplicit = { /* the rule above */ };};Every rule declares a level that determines the value passed to its check:
manifestruns once for each rendered Kubernetes resource.packageruns once for each package instance.namespaceruns once for each namespace.clusterruns once for the whole cluster.
Kix accepts only these four levels and three severities: info, warning, and
error. Evaluation rejects any other value. This prevents misspelled levels
from creating rules that never run, and misspelled severities from being
treated as warnings.
The check returns one finding for each problem and an empty list when the
input passes. Use appliesTo when a rule is meaningful only for a subset of
its level.
Check the rules
Section titled “Check the rules”Run the cluster checks after adding or changing a rule:
❱ kix check 19-scorecards
TOOL RESULT DETAILS
eval pass 24 manifests evaluated
scorecard pass 0 errors, 6 warnings, 2 info Kix reports the number of scorecard errors, warnings, and informational
findings. Every finding is capped at scorecard.maxSeverity, which defaults
to warning, so a new cluster prints what the rules found and still builds.
With the cap raised to error, an error-severity finding becomes a failed
assertion. Kix collects the failed assertions, reports them together, and does
not build the cluster. Because evaluation failed, kix check reports the
failure in its eval step rather than producing a separate scorecard summary.
Warnings and informational findings are collected across the cluster and
reported together when evaluation succeeds. See
Fail the build on scorecard findings
for the cap.