feat(cli): inject policy inputs from CSV/JSON files at attestation add

Merged
MI
4mo ago
+1225-87

Closes chainloop-dev/chainloop#3250

Summary

Adds a repeatable --policy-input-from-file <input>=<file>[:<column>] flag to chainloop attestation add that sources a policy input from a column of a CSV or JSON file and injects it during material policy evaluation. The primary use case is feeding the ignored_paths input of the Sysinternals sigcheck binary-signing policies from a large, data-driven exemption list, but the flag is generic over both the input name and the source column.

chainloop attestation add --name sigcheck --value sigcheckResult.csv --kind SYSINTERNALS_SIGCHECK \
  --policy-input-from-file ignored_paths=exception.csv:Path

Details

  • The :<column> suffix selects the column and defaults to the input name; a column is always a single, top-level field/header name. The column is the segment after the last :, so a Windows drive letter (C:\...) or URL scheme (https://) in the file path is not mistaken for a column.
  • Runtime inputs are merged additively onto contract-declared arguments through a dedicated channel, kept separate from policy-group bindings so group evaluations are not mis-flagged as runtime overrides.
  • The source file is recorded as an EVIDENCE material named <material>-<input> (the input name sanitized to a valid material name, e.g. ignored_paths → ignored-paths; a -<n> suffix disambiguates repeats). The exact input name is preserved in a chainloop.material.policy_input annotation.
  • The evidence material and the evaluated material are cross-linked both ways via the generic chainloop.material.references annotation (by material name, modeled on the OCI referrers API). The same primitive can connect other material kinds in the future.
  • PolicyEvaluation gains a runtime_input_overrides field listing which input names were supplied at runtime; the effective merged values remain in with.
  • CSV/TSV parsing is handled by a new generic pkg/tabular package (extracted from the previous sigcheck-only parser): BOM decoding, comma/tab auto-detection, and a case-insensitive Column extractor. The sigcheck material crafter now consumes it too. JSON accepts a bare string array, an array of string-valued objects, or an object mapping the column to an array.

AI assistance

This change was developed with the assistance of Claude Code. Affected commits carry an Assisted-by: Claude Code trailer.

šŸ¤– Posted by Maximus bot (Claude Code) on behalf of @migmartri