Skip to content

feat: add --params flag to kosli evaluate commands#762

Merged
tooky merged 7 commits intomainfrom
add-params-flag
Apr 2, 2026
Merged

feat: add --params flag to kosli evaluate commands#762
tooky merged 7 commits intomainfrom
add-params-flag

Conversation

@tooky
Copy link
Copy Markdown
Contributor

@tooky tooky commented Apr 2, 2026

Summary

  • Adds --params flag to evaluate trail, evaluate trails, and evaluate input, allowing policy authors to pass configuration data (thresholds, expected counts, etc.) without duplicating policy files
  • Params are available in Rego policies as data.params, using OPA's idiomatic data document — existing policies that don't reference data.params are completely unaffected
  • Accepts inline JSON (--params '{"min_approvers": 2}') or file reference (--params @params.json)

Motivation

Policies are currently fully static. Thresholds like "zero approvers" or "no critical vulnerabilities" are baked into the .rego file. If you want the same policy logic with different tolerances — say, 1 approver in staging, 2 in production — you need separate policy files duplicating the logic. That's the kind of duplication kosli evaluate is meant to eliminate.

This was flagged independently by both Alex and Dan as a natural next step.

How it works

Policy authors define defaults and override from data.params:

package policy
import rego.v1

default allow := false
default min_approvers := 1

min_approvers := data.params.min_approvers if { data.params.min_approvers }

allow if {
    some pr in input.trail.compliance_status.attestations_statuses["pull-request"].pull_requests
    count(pr.approvers) >= min_approvers
}
$ kosli evaluate trail myTrail \
    --policy pr-approved.rego \
    --flow server \
    --params '{"min_approvers": 2}'

Design decision: data.params not input.params

OPA's data document is designed for configuration, separate from input (what you're evaluating). Using data.params:

  • Keeps the separation clean — no risk of colliding with user-provided JSON in evaluate input
  • Is idiomatic OPA
  • Means --show-input output clearly distinguishes input from params

Test plan

  • Unit tests: params provided overrides default, no params uses default, unused params have no effect
  • Command tests: inline JSON, @file.json, invalid JSON error, --show-input includes params
  • go vet clean
  • All existing evaluate tests still pass

🤖 Generated with Claude Code

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 2, 2026

Claude finished @tooky's task in 1m 58s —— View job


PR Review: feat: add --params flag to kosli evaluate commands

  • Run static analysis (build, vet, mod tidy)
  • Review code changes
  • Post review feedback

Static Analysis

All clean: go build, go vet, and go mod tidy pass with no issues.

Review Summary

This is a well-executed PR. The feature is cleanly scoped, follows established patterns, and the TDD discipline is evident in the commit history.

What works well

  • Design choice of data.params over input.params is the right call — it's idiomatic OPA and avoids collision with user-provided JSON in evaluate input.
  • parseParams handling of both inline JSON and @file.json is clean and follows familiar CLI conventions (like curl's @ syntax).
  • The variadic-to-plain refactor (commit 83f9268) addressed the previous review nit cleanly — the API is now unambiguous.
  • Test coverage is thorough: params override, default fallback, unused params, inline JSON, file reference, invalid JSON, and --show-input integration are all covered at both the unit and command levels.
  • Backward compatibility is preserved — existing policies that don't reference data.params are completely unaffected since inmem.NewFromObject is only wired when params is non-nil.

Minor observations (non-blocking)

  1. evaluateHelpers.go:134-138 — Left an inline comment on the two showInput guards. Either the current flat form or a merged block works; no strong preference.

  2. parseParams doesn't validate the @ path is non-emptyparseParams("@") would call os.ReadFile("") which returns a clear OS error, so this is fine in practice. Just noting it.

  3. Store duplication — The inmem.NewFromObject + rego.Store pattern appears twice (in Evaluate and collectViolations). If more entry points emerge, a small helper could DRY this up, but for two call sites it's not worth it today.

No bugs, security issues, or performance concerns found. The PR is ready to merge.

tooky and others added 7 commits April 2, 2026 11:04
Extends the Evaluate function signature with variadic params. When
provided, creates an inmem store so policies can read data.params.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds tests confirming that when no params are provided the policy's
default value applies, and that supplying unused params has no effect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds --params flag to commonEvaluateOptions, accepting inline JSON or
@file.json. Params are passed to OPA as data.params so policies can
define configurable thresholds with defaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When --show-input is active and --params are provided, the params
appear alongside input in the audit result output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates help text and examples for evaluate, evaluate trail,
evaluate trails, and evaluate input to document the --params flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changes Evaluate signature from variadic params to an explicit
map parameter. Callers pass nil when no params are needed,
making the API unambiguous.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tooky tooky force-pushed the add-params-flag branch from 26d808d to 83f9268 Compare April 2, 2026 10:04
Copy link
Copy Markdown
Contributor

@mbevc1 mbevc1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, perhaps only worth looking at comment 2.

@tooky
Copy link
Copy Markdown
Contributor Author

tooky commented Apr 2, 2026

parseParams doesn't validate the @ path is non-empty — parseParams("@") would call os.ReadFile("") which returns a clear OS error, so this is fine in practice. Just noting it.

os.ReadFile("") returns open : no such file or directory, which wrapped becomes failed to read --params file: open : no such file or directory. Not the prettiest message, but it's clear enough and it's an edge case that doesn't warrant extra code. Leaving as is.

@tooky tooky merged commit 05297c1 into main Apr 2, 2026
27 of 28 checks passed
@tooky tooky deleted the add-params-flag branch April 2, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants