chore: check and report four-eyes to Kosli#891
Conversation
|
Claude finished @mbevc1's task in 6m 5s —— View job Review of PR #891 — Four-eyes evaluation and attestation
Static Analysis
Key FindingYAML parsing bug in workflow steps (high priority): The new
Fix: Use Other Notes
What looks good
|
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
| - name: Evaluate trails for four-eyes to Kosli | ||
| if: ${{ inputs.report_to_kosli == 'all' }} | ||
| env: | ||
| KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} | ||
| run: kosli evaluate trails ${{inputs.trail_name}} \ | ||
| --policy "./bin/never_alone/four-eyes-policy.rego" \ | ||
| --show-input \ | ||
| --flow ${{inputs.flow_name}} \ | ||
| --org ${{inputs.kosli_org}} \ | ||
| --no-assert \ | ||
| --params '{"attestation_name": "pr"}' \ | ||
| --output json > "4eyes-eval-${{inputs.trail_name}}.json" || echo '{"allow":false,"violations":["evaluate command failed"]}' > "4eyes-eval-${{inputs.trail_name}}.json" |
There was a problem hiding this comment.
Bug: YAML plain scalar breaks on embedded JSON colon.
This run: step is a YAML plain scalar (no |). The ": " inside --params '{"attestation_name": "pr"}' is interpreted by the YAML parser as a mapping indicator, causing a parse error. I verified this with Python's PyYAML (spec-compliant) and it fails:
ScannerError: mapping values are not allowed here
--params '{"key": "val"}'
^
Additionally, the \ line continuations don't work as intended in plain scalars — YAML folds newlines to spaces, so \ + newline becomes \ (escaped space in bash), which merges with the next argument (e.g., --policy becomes --policy with a leading space).
Fix: Use a block literal scalar (run: |) so newlines are preserved and \ works as shell line continuation:
| - name: Evaluate trails for four-eyes to Kosli | |
| if: ${{ inputs.report_to_kosli == 'all' }} | |
| env: | |
| KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} | |
| run: kosli evaluate trails ${{inputs.trail_name}} \ | |
| --policy "./bin/never_alone/four-eyes-policy.rego" \ | |
| --show-input \ | |
| --flow ${{inputs.flow_name}} \ | |
| --org ${{inputs.kosli_org}} \ | |
| --no-assert \ | |
| --params '{"attestation_name": "pr"}' \ | |
| --output json > "4eyes-eval-${{inputs.trail_name}}.json" || echo '{"allow":false,"violations":["evaluate command failed"]}' > "4eyes-eval-${{inputs.trail_name}}.json" | |
| run: | | |
| kosli evaluate trails ${{inputs.trail_name}} \ | |
| --policy "./bin/never_alone/four-eyes-policy.rego" \ | |
| --show-input \ | |
| --flow ${{inputs.flow_name}} \ | |
| --org ${{inputs.kosli_org}} \ | |
| --no-assert \ | |
| --params '{"attestation_name": "pr"}' \ | |
| --output json > "4eyes-eval-${{inputs.trail_name}}.json" \ | |
| || echo '{"allow":false,"violations":["evaluate command failed"]}' > "4eyes-eval-${{inputs.trail_name}}.json" |
The existing kosli begin trail and kosli attest pullrequest steps work because they don't use \ or embedded JSON — YAML folding produces a clean single-line command. But this step needs run: |.
| - name: Report four-eyes attestation to Kosli | ||
| if: ${{ inputs.report_to_kosli == 'all' }} | ||
| env: | ||
| KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} | ||
| run: kosli attest custom \ | ||
| --type "four-eyes-result" \ | ||
| --name "four-eyes-result" \ | ||
| --attestation-data "4eyes-eval-${{inputs.trail_name}}.json" \ | ||
| --attachments "./bin/never_alone/four-eyes-policy.rego" \ | ||
| --trail ${{inputs.trail_name}} \ | ||
| --flow ${{inputs.flow_name}} \ | ||
| --org ${{inputs.kosli_org}} |
There was a problem hiding this comment.
Same issue: needs run: | for consistency and correctness.
While this step doesn't have the JSON colon problem, it still uses \ in a plain scalar. Switch to block literal for safety:
| - name: Report four-eyes attestation to Kosli | |
| if: ${{ inputs.report_to_kosli == 'all' }} | |
| env: | |
| KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} | |
| run: kosli attest custom \ | |
| --type "four-eyes-result" \ | |
| --name "four-eyes-result" \ | |
| --attestation-data "4eyes-eval-${{inputs.trail_name}}.json" \ | |
| --attachments "./bin/never_alone/four-eyes-policy.rego" \ | |
| --trail ${{inputs.trail_name}} \ | |
| --flow ${{inputs.flow_name}} \ | |
| --org ${{inputs.kosli_org}} | |
| run: | | |
| kosli attest custom \ | |
| --type "four-eyes-result" \ | |
| --name "four-eyes-result" \ | |
| --attestation-data "4eyes-eval-${{inputs.trail_name}}.json" \ | |
| --attachments "./bin/never_alone/four-eyes-policy.rego" \ | |
| --trail ${{inputs.trail_name}} \ | |
| --flow ${{inputs.flow_name}} \ | |
| --org ${{inputs.kosli_org}} |
| attestation_name := name if { | ||
| name := data.params.attestation_name | ||
| is_string(name) | ||
| } else := "pr-review" |
There was a problem hiding this comment.
Nit: Default doesn't match the workflow.
The workflow passes --params '{"attestation_name": "pr"}', so this default won't fire in CI. But anyone running the policy standalone (local testing, debugging) gets "pr-review", which doesn't match the actual attestation name "pr". Consider aligning:
| } else := "pr-review" | |
| } else := "pr" |
Add four eyes evaluation and attest result to Kosli.