Skip to content

feat: update to recent v2 support + simplify#14

Merged
reecebedding merged 2 commits into
mainfrom
feat/simple-implementation
May 28, 2026
Merged

feat: update to recent v2 support + simplify#14
reecebedding merged 2 commits into
mainfrom
feat/simple-implementation

Conversation

@reecebedding
Copy link
Copy Markdown
Member

@reecebedding reecebedding commented May 28, 2026

Summary by CodeRabbit

  • New Features

    • Added Makefile with developer workflow targets (help, test, build, run, clean).
    • Plugin now supports typed configuration (policy labels) and optional per-policy data; evaluation produces evidence records.
  • Documentation

    • Expanded README with detailed usage examples and plugin YAML configuration; added note about make run.
  • Chores

    • Updated Go toolchain/dependencies to newer versions.
    • CI release flow now attaches an OCI annotation during artifact uploads.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

Refactors the plugin to use a typed PluginConfig, changes policy evaluation to produce Evidence via a PolicyProcessor, updates plugin lifecycle to store logger and policyData, adds a Makefile for developer workflows, updates module dependencies to Go 1.26.1, annotates GoReleaser uploads, and expands README usage examples.

Changes

Plugin Configuration and Evaluation

Layer / File(s) Summary
Configuration parsing & data fetching
internal/config.go, internal/data.go, internal/util.go
Add PluginConfig and ParseConfig; DataFetcher now accepts *PluginConfig and returns only data; add MergeMaps utility.
Policy evaluator → Evidence
internal/eval.go
Rewrite PolicyEvaluator to return []*proto.Evidence and accept ctx, input, policyData, labels; use policyManager.PolicyProcessor and GenerateResults.
Plugin lifecycle and serving
main.go, internal/*
CompliancePlugin stores logger, typed config, and policyData; Configure parses config; Init creates ec2-instance subject template; Eval fetches data, runs evaluator, and submits evidence via apiHelper.CreateEvidence; serve RunnerV2GRPCPlugin.

Developer Workflow and Build Infrastructure

Layer / File(s) Summary
Makefile developer targets
Makefile
Add help/help-all (self-documenting), test (go test), clean (remove dist), build (compile to dist/plugin), run (launch agent with built plugin); validate opa CLI on startup.
Module, workflow annotation, and docs
go.mod, .github/workflows/build-and-upload.yml, README.md
Update Go toolchain to go 1.26.1 and reshape dependencies; add OCI upload annotation org.ccf.plugin.protocol.version=2 to GoReleaser uploads; expand README usage with CLI and YAML plugin examples and make run note.

Sequence Diagram

sequenceDiagram
  participant Request as EvalRequest
  participant Fetcher as DataFetcher
  participant Evaluator as PolicyEvaluator
  participant Processor as PolicyProcessor
  participant Helper as ApiHelper
  Request->>Fetcher: FetchData()
  Fetcher-->>Request: map[string]any
  Request->>Evaluator: Eval(ctx, input, policyPaths, policyData, labels)
  Evaluator->>Processor: NewPolicyProcessor(merged labels, activities, policyData)
  Processor->>Processor: GenerateResults per policyPath
  Processor-->>Evaluator: []*Evidence, error
  Request->>Helper: CreateEvidence(evidence)
  Helper-->>Request: EvalResponse with ExecutionStatus_SUCCESS
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A typed config tucked in a cozy den,
Evidence hops in where findings had been,
Makefile lights the path to run and test,
Modules updated, uploads tagged for the rest,
A nimble plugin, ready to spring again.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: update to recent v2 support + simplify' accurately reflects the main changes: upgrading to v2 API support and simplifying the implementation through structural changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread internal/eval.go
Comment on lines 46 to +28
// Eval is used to run policies against the data you've collected. You could also consider an
// `EvalAndSend` by passing in the `apiHelper` that sends the observations directly to the API.
func (pe *PolicyEvaluator) Eval(data map[string]interface{}, policyPaths []string) (proto.ExecutionStatus, error) {
func (pe *PolicyEvaluator) Eval(ctx context.Context, input map[string]interface{}, policyPaths []string, policyData map[string]interface{}, labels map[string]string) ([]*proto.Evidence, error) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We could use this example to also fill in the labels from the PolicyLabels.. currently this is ignored (nil argument)

Comment thread main.go Outdated
evalStatus, err := policyEvaluator.Eval(data, request.PolicyPaths)
policyEvaluator := internal.NewPolicyEvaluator(ctx, l.logger, activities)

evidences, err := policyEvaluator.Eval(ctx, data, request.PolicyPaths, l.policyData, nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nil argument is here btw

Comment thread main.go
Comment on lines +75 to +96
func (l *CompliancePlugin) Init(req *proto.InitRequest, apiHelper runner.ApiHelper) (*proto.InitResponse, error) {
ctx := context.Background()
subjectTemplates := []*proto.SubjectTemplate{
{
Name: "ec2-instance",
Type: proto.SubjectType_SUBJECT_TYPE_COMPONENT,
TitleTemplate: "EC2 Instance {{ .resource_id }} in {{ .account_id }}/{{ .region }}",
DescriptionTemplate: "AWS EC2 Instance {{ .resource_id }}.",
PurposeTemplate: "Represents an AWS EC2 instance evaluated for compliance posture.",
IdentityLabelKeys: []string{"account_id", "region", "resource_id"},
LabelSchema: []*proto.SubjectLabelSchema{
{Key: "account_id", Description: "AWS account ID"},
{Key: "region", Description: "AWS region"},
{Key: "resource_id", Description: "EC2 Instance ID"},
{Key: "resource_arn", Description: "AWS resource ARN"},
{Key: "resource_type", Description: "EC2 normalized resource type"},
},
},
}
return runner.InitWithSubjectsAndRisksFromPolicies(ctx, l.logger, req, apiHelper, subjectTemplates)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Worth adding a docstring here explaining how to build these Init methods - i.e. Labels used on templates must be added to LabelSchema, _plugin is automatically added to the Schema + as an Identity Label Key etc; to use templated keys they need to be within the schema, and that TYPE MUST BE COMPONENT FOR AUTOMATION TO TRIGGER. DONT USE OTHER TYPES AS OF TODAY (this happened ** SO MANY TIMES ** when using agents)

Comment thread README.md
Comment on lines +35 to +42
plugins:
myplugin:
config:
anykey: "anyval"
protocol_version: 2
source: /path/to/dist/plugin
policies:
- /path/to/policy/bundle.tar.gz
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

add a policy_data / policy_behavior example here would also be useful.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/eval.go (1)

32-59: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

The activity pipeline is empty, so evidence loses its execution trail.

processor only receives pe.stepActivities, but this method never attaches the per-policy steps it builds, and main.go seeds stepActivities with an empty slice. The fetch steps built in internal/data.go also have no path into PolicyProcessor, so generated evidence carries no fetch/compile/execute provenance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/eval.go` around lines 32 - 59, The PolicyProcessor is created with
only pe.stepActivities so the per-policy `steps` (and the fetch steps produced
in internal/data.go) never get recorded; before calling
policyManager.NewPolicyProcessor in internal/eval.go, append the local `steps`
slice (and any fetch-step slices produced earlier) into the `activities` slice
so the processor receives the full execution trail (e.g., merge `steps` into
`activities` prior to calling policyManager.NewPolicyProcessor), then call
`processor.GenerateResults(ctx, policyPath, input)` as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build-and-upload.yml:
- Line 25: The workflow run command embeds unsanitized GitHub context variables
(github.repository_owner, github.event.repository.name, github.ref_name) into
the shell invocation which can lead to template/shell injection; fix by moving
those contexts into environment variables and using the env names in the run
step (or validate/sanitize them before use) so the invocation uses safe values
(e.g., set REPO_OWNER, REPO_NAME, REF_NAME from the contexts and reference those
in the gooci upload command), or add an input-validation step that rejects
unexpected characters in github.ref_name before running the upload.
- Line 25: The --annotate argument in the gooci upload commands has an
unterminated string; update both occurrences of the gooci upload invocation so
the annotation value is properly quoted (e.g. close the opening double quote
after the annotation like --annotate="org.ccf.plugin.protocol.version=2")
ensuring each gooci upload command’s --annotate parameter ends with a matching
closing quote.

In `@go.mod`:
- Line 18: Update the transitive Docker dependency by bumping the testcontainers
library: in go.mod replace or update the
github.com/testcontainers/testcontainers-go version to a newer release that
pulls Moby/docker >= 29.3.1 (so github.com/docker/docker transitive
vulnerabilities are patched), then run go mod tidy to refresh the module graph
and vendor (if used); verify via `go list -m all` or `go mod graph` that
github.com/docker/docker now resolves to a patched version and CI uses trusted
images for Docker-backed tests.

In `@internal/eval.go`:
- Around line 47-50: The code is merging hardcoded placeholder labels into every
evidence record via MergeMaps(labels, map[string]string{ "provider":
"my_plugin", "additional_label": "value", }), so remove or replace that
hardcoded map; update the call in the MergeMaps usage (where labels is combined)
to either merge only real runtime labels or omit the second map entirely, or
derive values from actual config/vars (e.g., provider and additional_label from
settings) before calling MergeMaps to avoid stamping placeholder metadata on
emitted evidence.

In `@main.go`:
- Around line 57-62: The parsed config's PolicyLabels are being stored
(l.config.PolicyLabels) but never passed to the policy evaluator so
user-provided policy_labels are ignored; update both Configure/Eval call sites
to pass the persisted labels into policyEvaluator.Eval by replacing the nil
labels argument with l.config.PolicyLabels (or the local
parsedConfig.PolicyLabels where appropriate) so Eval uses the parsed
policy_labels from internal.ParseConfig/rawConfig; ensure you reference
policyEvaluator.Eval, Configure, Eval, rawConfig, parsedConfig,
internal.ParseConfig and l.config.PolicyLabels when making the change.

In `@Makefile`:
- Around line 26-34: Add a .PHONY declaration for non-file targets to prevent
Make from treating them as actual files: declare .PHONY with the list of targets
(help, help-all, test, clean, build, run) near the top of the Makefile (e.g.,
after the OPA check), so targets like test, clean, build, run are always
executed regardless of same-named files.
- Around line 36-37: The run target currently uses a hardcoded agent path
"../agent/dist/./concom"; make this configurable by introducing a Makefile
variable (e.g., AGENT_BIN or AGENT_PATH) with a sensible default and replace the
literal path in the run recipe with that variable, and also add an existence
check for $(AGENT_BIN) before executing (print an error and exit non‑zero if
missing) so the target is portable and fails fast when the binary is not found.

---

Outside diff comments:
In `@internal/eval.go`:
- Around line 32-59: The PolicyProcessor is created with only pe.stepActivities
so the per-policy `steps` (and the fetch steps produced in internal/data.go)
never get recorded; before calling policyManager.NewPolicyProcessor in
internal/eval.go, append the local `steps` slice (and any fetch-step slices
produced earlier) into the `activities` slice so the processor receives the full
execution trail (e.g., merge `steps` into `activities` prior to calling
policyManager.NewPolicyProcessor), then call `processor.GenerateResults(ctx,
policyPath, input)` as-is.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5eefabca-2b4d-4a6a-92e1-481c0c69fe8d

📥 Commits

Reviewing files that changed from the base of the PR and between 13432a3 and 3e102a6.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • .github/workflows/build-and-upload.yml
  • Makefile
  • README.md
  • go.mod
  • internal/config.go
  • internal/data.go
  • internal/eval.go
  • internal/util.go
  • main.go

run: gooci login ghcr.io --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }}
- name: gooci Upload Version
run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{github.ref_name}}
run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{github.ref_name}} --annotate="org.ccf.plugin.protocol.version=2
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Potential template injection via GitHub context variables.

The workflow uses unsanitized GitHub context variables (github.repository_owner, github.event.repository.name, github.ref_name) in shell commands. In certain scenarios (e.g., workflow running from a fork or with crafted repository names), these could inject arbitrary commands.

For a plugin template used in a trusted context, this risk may be acceptable. However, if this workflow will run on pull requests from forks or in untrusted environments, consider sanitizing the inputs or using environment variables instead.

🛡️ Defensive alternatives

Option 1: Use environment variables

- name: gooci Upload Version
  env:
    REPO_OWNER: ${{ github.repository_owner }}
    REPO_NAME: ${{ github.event.repository.name }}
    REF_NAME: ${{ github.ref_name }}
  run: gooci upload dist/ "ghcr.io/${REPO_OWNER}/${REPO_NAME}:${REF_NAME}" --annotate="org.ccf.plugin.protocol.version=2"

Option 2: Add input validation

- name: Validate inputs
  run: |
    if [[ ! "${{ github.ref_name }}" =~ ^[a-zA-Z0-9._-]+$ ]]; then
      echo "Invalid ref name"
      exit 1
    fi

Also applies to: 28-28

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-and-upload.yml at line 25, The workflow run command
embeds unsanitized GitHub context variables (github.repository_owner,
github.event.repository.name, github.ref_name) into the shell invocation which
can lead to template/shell injection; fix by moving those contexts into
environment variables and using the env names in the run step (or
validate/sanitize them before use) so the invocation uses safe values (e.g., set
REPO_OWNER, REPO_NAME, REF_NAME from the contexts and reference those in the
gooci upload command), or add an input-validation step that rejects unexpected
characters in github.ref_name before running the upload.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing closing quote in annotation argument.

Both gooci upload commands have unterminated strings in the --annotate parameter. The opening quote for the annotation value is never closed, which will cause shell syntax errors.

🐛 Proposed fix
       - name: gooci Upload Version
-        run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{github.ref_name}} --annotate="org.ccf.plugin.protocol.version=2
+        run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{github.ref_name}} --annotate="org.ccf.plugin.protocol.version=2"
       - name: gooci Upload Latest
         if: "!github.event.release.prerelease"
-        run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest --annotate="org.ccf.plugin.protocol.version=2
+        run: gooci upload dist/ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest --annotate="org.ccf.plugin.protocol.version=2"

Also applies to: 28-28

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 25-25: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-and-upload.yml at line 25, The --annotate argument
in the gooci upload commands has an unterminated string; update both occurrences
of the gooci upload invocation so the annotation value is properly quoted (e.g.
close the opening double quote after the annotation like
--annotate="org.ccf.plugin.protocol.version=2") ensuring each gooci upload
command’s --annotate parameter ends with a matching closing quote.

Comment thread go.mod
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
github.com/defenseunicorns/go-oscal v0.7.0 // indirect
github.com/docker/docker v28.5.2+incompatible // indirect
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if docker package is actually imported/used in the codebase

echo "=== Checking for direct docker imports ==="
rg -n --type=go 'github\.com/docker/docker' -g '!go.mod' -g '!go.sum'

echo ""
echo "=== Checking which dependency brings in docker ==="
go mod why github.com/docker/docker

echo ""
echo "=== Checking for latest docker version and patches ==="
curl -s https://proxy.golang.org/github.com/docker/docker/@latest | jq -r '.Version'

Repository: compliance-framework/plugin-template

Length of output: 9640


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== rg for docker/docker imports (code only) ==="
rg -n --type=go 'github\.com/docker/docker' -g '!go.mod' -g '!go.sum' || true

echo
echo "=== go mod why (module-level) ==="
go mod why -m github.com/docker/docker || true

echo
echo "=== go list deps (including tests) that reference docker/docker ==="
go list -deps -test ./... 2>/dev/null | rg -n 'github\.com/docker/docker' || true

echo
echo "=== go mod graph edges that mention docker/docker (filtered) ==="
go mod graph | rg 'github\.com/docker/docker' || true

Repository: compliance-framework/plugin-template

Length of output: 863


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Find any packages in this module that import docker/docker subpackages ==="
rg -n --type=go 'github\.com/docker/docker/(.+)?' -g '!go.mod' -g '!go.sum' || true

echo
echo "=== Identify packages whose resolved module is github.com/docker/docker (deps including tests) ==="
# Uses -json to map packages -> module path, then filters for github.com/docker/docker
go list -deps -test -json ./... 2>/dev/null \
  | jq -r 'select(.Module != null and .Module.Path=="github.com/docker/docker") | .ImportPath' \
  | sort -u | sed '/^$/d' || true

echo
echo "=== Does testcontainers-go appear in non-test packages? ==="
rg -n --type=go 'github\.com/testcontainers/testcontainers-go' -g '!go.mod' -g '!go.sum' . || true

Repository: compliance-framework/plugin-template

Length of output: 320


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Inspect go list -deps -test -json for packages belonging to github.com/docker/docker ==="
go list -deps -test -json ./... 2>/dev/null \
  | rg -n '"Module":\s*{' -n || true

# More direct: print ImportPath values where the JSON shows Module.Path == github.com/docker/docker
go list -deps -test -json ./... 2>/dev/null \
  | python3 - <<'PY'
import sys, json, re
buf=[]
for line in sys.stdin:
    buf.append(line)
    if line.strip() == '}':
        pass
PY

Repository: compliance-framework/plugin-template

Length of output: 283


🏁 Script executed:

#!/bin/bash
set -euo pipefail

pkgs=(
  "github.com/compliance-framework/agent/runner"
  "github.com/compliance-framework/api/sdk"
  "github.com/compliance-framework/api/sdk.test"
)

for p in "${pkgs[@]}"; do
  echo "===== $p ====="
  dir="$(go list -f '{{.Dir}}' "$p" 2>/dev/null || true)"
  echo "Dir: ${dir:-<unknown>}"

  if [ -n "$dir" ] && [ "$dir" != "<unknown>" ]; then
    rg -n --hidden --no-ignore -S 'github\.com/docker/docker' "$dir" || true
    rg -n --hidden --no-ignore -S 'docker\.go' "$dir" || true
  fi

  echo
done

echo "===== Any docker/docker imports across this module (all .go files) ====="
rg -n --type=go 'github\.com/docker/docker' . -g '!go.mod' -g '!go.sum' || true

Repository: compliance-framework/plugin-template

Length of output: 499


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== docker/docker packages in NON-TEST deps (import graph) ==="
go list -deps -json ./... 2>/dev/null \
  | jq -r 'select(.Module != null and .Module.Path=="github.com/docker/docker") | .ImportPath' \
  | sort -u || true

echo
echo "=== docker/docker packages in TEST deps (import graph) ==="
go list -deps -test -json ./... 2>/dev/null \
  | jq -r 'select(.Module != null and .Module.Path=="github.com/docker/docker") | .ImportPath' \
  | sort -u || true

echo
echo "=== modules requiring docker/docker in NON-TEST build ==="
go mod why -m github.com/docker/docker 2>/dev/null || true

Repository: compliance-framework/plugin-template

Length of output: 546


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== rg for testcontainers-go usage (excluding vendor) ==="
rg -n --hidden --no-ignore -S 'testcontainers[-.]go' . -g '!go.mod' -g '!go.sum' || true

echo
echo "=== rg for docker client imports in repo (excluding go.mod/sum) ==="
rg -n --hidden --no-ignore -S 'github\.com/docker/docker' . -g '!go.mod' -g '!go.sum' || true

echo
echo "=== List any _test.go files that reference testcontainers ==="
rg -n --hidden --no-ignore -S 'testcontainers[-.]go' . -g '*_test.go' || true

Repository: compliance-framework/plugin-template

Length of output: 270


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Importers of github.com/docker/docker (test vs non-test) ==="
for mode in "" "-test"; do
  echo "--- mode: ${mode:-non-test} ---"
  go list $mode -deps -json ./... 2>/dev/null \
    | jq -r '
        select(.Module and (.Module.Path=="github.com/docker/docker")) 
        | .ImportPath
      ' | sort -u | head -n 200
done

echo
echo "=== Importers that pull in github.com/testcontainers/testcontainers-go (test vs non-test) ==="
for mode in "" "-test"; do
  echo "--- mode: ${mode:-non-test} ---"
  go list $mode -deps -json ./... 2>/dev/null \
    | jq -r '
        select(.Module and (.Module.Path=="github.com/testcontainers/testcontainers-go")) 
        | .ImportPath
      ' | sort -u | head -n 200
done

echo
echo "=== Raw module paths present for deps mentioning docker/docker (sanity) ==="
go list -deps -test -json ./... 2>/dev/null | jq -r '
  select(.Module and (.Module.Path|contains("docker/docker"))) 
  | (.Module.Path + " " + (.Version // ""))
' | sort -u | head -n 50

Repository: compliance-framework/plugin-template

Length of output: 403


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect dependency module sources (not this repo) for docker/testcontainers usage
mods=(
  "/home/jailuser/go/pkg/mod/github.com/compliance-framework/agent@v0.7.0"
  "/home/jailuser/go/pkg/mod/github.com/compliance-framework/api@v0.16.0"
)

for d in "${mods[@]}"; do
  echo "===== Searching in $d for docker/docker ====="
  test -d "$d" && rg -n --hidden --no-ignore -S 'github\.com/docker/docker' "$d" || echo "missing"
  echo
  echo "===== Searching in $d for testcontainers-go ====="
  test -d "$d" && rg -n --hidden --no-ignore -S 'github\.com/testcontainers/testcontainers-go' "$d" || echo "missing"
  echo
  echo "===== Searching in $d for docker client usage indicators ====="
  test -d "$d" && rg -n --hidden --no-ignore -S 'docker\.NewClient|client\.NewClient|dockertest|testcontainers' "$d" || echo "missing"
  echo "----------------------------------------"
done

Repository: compliance-framework/plugin-template

Length of output: 7955


🌐 Web query:

GO-2026-4883 Off-by-one error in plugin privilege validation github.com/docker/docker

💡 Result:

GO-2026-4883 refers to an off-by-one error in plugin privilege validation within the Moby project (the core component of Docker), tracked as CVE-2026-33997 and GHSA-pxq6-2prw-chj9 [1][2]. The vulnerability arises from an error in the daemon's privilege comparison logic, specifically within the isEqual() function, where the loop responsible for comparing requested privileges against approved ones incorrectly started at index 1 instead of index 0 [3]. This flaw leads to two security consequences: 1. Privilege Validation Bypass: The first privilege (alphabetically) is never validated, allowing a malicious plugin to request different values for privileges such as "allow-all-devices," which can grant unrestricted read-write access to host devices [3]. 2. Complete Bypass for Single Privileges: Plugins that request exactly one privilege trigger zero iterations of the comparison loop, effectively bypassing validation entirely [3][4]. This issue is patched in Moby version 29.3.1 [4][2]. Users and projects using the github.com/docker/docker module are advised to update their dependencies, although the Docker/Moby project has also moved toward deprecating the github.com/docker/docker module in favor of maintained modules like github.com/moby/moby/client and github.com/moby/moby/api [5].

Citations:


🌐 Web query:

GHSA-x86f-5xw2-fm2r Container binary execution on host via PUT /containers/{id}/archive github.com/docker/docker

💡 Result:

GHSA-x86f-5xw2-fm2r (also tracked as CVE-2026-41567) is a security vulnerability in Docker Engine that allows for arbitrary code execution on the host with daemon (root) privileges [1][2][3]. The vulnerability occurs when handling PUT /containers/{id}/archive requests that contain compressed archives (specifically xz or gzip) [1][2]. The Docker daemon incorrectly resolves external system binaries required for decompression from the container's filesystem instead of the host's filesystem [1][3]. A malicious container image containing a trojanized decompression binary can exploit this behavior, allowing the binary to execute with the full privileges of the host daemon when an archive is uploaded to the container [1][2][4]. Key points regarding this vulnerability: - Affected Component: github.com/docker/docker (and related moby/moby components) [1][5][2]. - Attack Vector: Requires a user to run a container from a malicious image and subsequently upload a compressed archive (xz or gzip) into that container [1][2]. - Exploitation Examples: This can be triggered by calling the PUT /containers/{id}/archive API directly or by piping a compressed archive through commands like docker cp - [1][2][4]. - Limitations: Standard docker cp usage is not affected because the CLI sends uncompressed tar by default [4]. Decompression formats using pure Go implementations (such as bzip2, zstd, and gzip when an unpigz binary is absent) are also not affected [1][2]. Recommended mitigations include: - Only running containers from trusted images [1][2]. - Using authorization plugins to limit access to the PUT /containers/{id}/archive endpoint [1][2]. - Avoiding the piping of compressed archives into containers created from untrusted sources [1][2]. As of May 28, 2026, advisories indicate that a fix may still be pending for the primary github.com/docker/docker module path [5].

Citations:


🌐 Web query:

GHSA-vp62-88p7-qqf5 Race condition in docker cp (arbitrary file creation) github.com/docker/docker

💡 Result:

GHSA-vp62-88p7-qqf5 (also tracked as CVE-2026-41568) is a security vulnerability in the Docker Engine related to a race condition in the docker cp command [1][2][3][4]. Vulnerability Details The vulnerability exists because of a race condition that occurs when the Docker daemon sets up a temporary filesystem view by bind-mounting volumes while executing a docker cp command (or equivalent API calls like PUT/HEAD /containers/{id}/archive) [1][3]. During this setup process: 1. The daemon resolves the target mount path within the container's root filesystem [1][4]. 2. It then creates the mountpoint (file or directory) if it does not already exist [1][4]. An attacker with a running malicious container can exploit the timing window between these two steps [1][3]. By rapidly creating and swapping path components for symlinks pointing to arbitrary locations on the host, the attacker can cause the daemon to follow these symlinks when it creates the mountpoint [1][4]. Consequently, the daemon creates empty files or directories at arbitrary absolute paths on the host filesystem with root privileges [1][4]. Distinction from Related Vulnerabilities This advisory (GHSA-vp62-88p7-qqf5) specifically addresses the race condition during mountpoint creation [3]. A separate, related vulnerability, tracked as GHSA-rg2x-37c3-w2rh (CVE-2026-42306), involves a different race condition that occurs during the subsequent mount syscall, which allows for bind mount redirection [3][5][6]. Mitigation and Recommendations - Avoid using docker cp with untrusted running containers [1][6]. - Only run containers from trusted images [1][6]. - Utilize authorization plugins to restrict access to the affected archive API endpoints (PUT /containers/{id}/archive and HEAD /containers/{id}/archive) [1][6]. - Ensure your Docker environment is updated to a patched version, as fixes have been implemented to scope mountpoint creation to the container root, preventing escapes even if symlinks are swapped [1].

Citations:


🌐 Web query:

GHSA-rg2x-37c3-w2rh Race condition in docker cp (bind mount redirection) github.com/docker/docker

💡 Result:

GHSA-rg2x-37c3-w2rh is a security advisory describing a race condition in the docker cp command that allows a malicious container to perform bind mount redirection to an arbitrary path on the host filesystem [1][2]. When a user initiates a docker cp operation, the Docker daemon sets up a temporary filesystem view by bind-mounting volumes into a private mount namespace [1]. During this setup process, a mount destination is created inside the container root, and a bind mount is subsequently attached to the container-relative path [1]. The vulnerability arises because there is a race condition between the creation of this mountpoint and the execution of the mount syscall [1]. A process running inside a malicious container can exploit this window by replacing the mount destination (or one of its parent path components) with a symbolic link pointing to an arbitrary location on the host [1]. When the mount syscall is executed, it follows the symlink, resulting in the volume being bind-mounted onto the host path rather than the intended location inside the container [1]. The impact of this exploit depends on the nature of the mount: - If the volume is writable, an attacker could potentially overwrite arbitrary host files at the redirected path with the volume's contents [1]. - If the volume is read-only, the host path is masked by the mount for the duration of the copy operation, which can cause a denial of service on the host [1]. Requirements for exploitation include [1]: - The container must have at least one volume mount. - A process inside the container must be capable of rapidly creating and swapping symlinks at the target mount destination. - An operator must trigger a docker cp command into the affected container (or call the corresponding PUT/HEAD /containers/{id}/archive API endpoints) [1]. Mitigation strategies recommended by the advisory include [1]: - Running only containers from trusted images. - Avoiding the use of docker cp with untrusted or running containers. - Utilizing authorization plugins to restrict access to the archive API endpoints [1]. This vulnerability is distinct from a related issue, tracked as GHSA-vp62-88p7-qqf5, which involves a race condition during mountpoint creation that allows for the creation of arbitrary empty files or directories on the host [3][4].

Citations:


🌐 Web query:

GHSA-x744-4wpc-v9h2 AuthZ plugin bypass github.com/docker/docker

💡 Result:

GHSA-x744-4wpc-v9h2 (also tracked as CVE-2026-34040) is a security vulnerability in Moby (the engine powering Docker) that allows an attacker to bypass authorization (AuthZ) plugins [1][2][3]. Under specific circumstances, a specially-crafted API request can cause the Docker daemon to forward the request to an AuthZ plugin without including the request body [1][3]. If an AuthZ plugin relies on introspecting this body to make access control decisions, it may incorrectly allow a request that it otherwise would have denied [1][3]. Key details include: - Impact: Users are only affected if they utilize AuthZ plugins that rely on request body inspection for security decisions [1][3]. - Status: This issue is identified as an incomplete fix for a previous, related vulnerability, CVE-2024-41110 [1][3]. - Affected Versions: Versions of Moby prior to 29.3.1 [4][2][3]. - Resolution: The issue was patched in version 29.3.1 [4][2][3]. - Mitigations: If updating immediately is not possible, users are advised to restrict access to the Docker API to trusted parties following the principle of least privilege and avoid using AuthZ plugins that rely on request body inspection [1][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Direct imports of github.com/docker/docker (excluding go.mod/go.sum) ==="
rg -n --type=go 'github\.com/docker/docker' -g '!go.mod' -g '!go.sum' . || true

echo
echo "=== docker/docker required for non-test builds? ==="
go list -deps ./... 2>/dev/null | rg -n 'github\.com/docker/docker' || true

echo
echo "=== docker/docker required only for test builds? ==="
go list -deps -test ./... 2>/dev/null | rg -n 'github\.com/docker/docker' || true

echo
echo "=== go mod why ==="
go mod why -m github.com/docker/docker || true

Repository: compliance-framework/plugin-template

Length of output: 568


Transitive github.com/docker/docker vulns are mainly relevant to Docker-backed integration tests/CI; update transitive deps.

go.mod pins github.com/docker/docker v28.5.2+incompatible // indirect (line 18). go mod why shows it’s pulled in via github.com/testcontainers/testcontainers-go used by github.com/compliance-framework/api integration tests (api/sdk.test) and dependency graph from api/sdk/agent/runner, not via direct imports in this repo.

Mapped HIGH advisories for this dependency:

Action: bump github.com/testcontainers/testcontainers-go (and run go mod tidy) so the resulting Docker/Moby (github.com/docker/docker) version is updated to a patched release; ensure CI runs only trusted images/containers when exercising these Docker API flows.

🧰 Tools
🪛 OSV Scanner (2.3.8)

[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Moby has an Off-by-one error in its plugin privilege validation in github.com/docker/docker

(GO-2026-4883)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Moby has AuthZ plugin bypass when provided oversized request bodies in github.com/docker/docker

(GO-2026-4887)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Moby has an Off-by-one error in its plugin privilege validation

(GHSA-pxq6-2prw-chj9)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Docker: Race condition in docker cp allows bind mount redirection to host path

(GHSA-rg2x-37c3-w2rh)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Docker: Race condition in docker cp allows creation of arbitrary empty files on the host via symlink swap

(GHSA-vp62-88p7-qqf5)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Moby has AuthZ plugin bypass when provided oversized request bodies

(GHSA-x744-4wpc-v9h2)


[HIGH] 18-18: github.com/docker/docker 28.5.2+incompatible: Docker: PUT /containers/{id}/archive executes container binary on the host

(GHSA-x86f-5xw2-fm2r)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@go.mod` at line 18, Update the transitive Docker dependency by bumping the
testcontainers library: in go.mod replace or update the
github.com/testcontainers/testcontainers-go version to a newer release that
pulls Moby/docker >= 29.3.1 (so github.com/docker/docker transitive
vulnerabilities are patched), then run go mod tidy to refresh the module graph
and vendor (if used); verify via `go list -m all` or `go mod graph` that
github.com/docker/docker now resolves to a patched version and CI uses trusted
images for Docker-backed tests.

Comment thread internal/eval.go
Comment on lines +47 to +50
MergeMaps(labels, map[string]string{
"provider": "my_plugin",
"additional_label": "value",
}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove the template placeholder labels before emitting evidence.

Hardcoding provider: "my_plugin" and additional_label: "value" will stamp placeholder metadata onto every evidence record.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/eval.go` around lines 47 - 50, The code is merging hardcoded
placeholder labels into every evidence record via MergeMaps(labels,
map[string]string{ "provider": "my_plugin", "additional_label": "value", }), so
remove or replace that hardcoded map; update the call in the MergeMaps usage
(where labels is combined) to either merge only real runtime labels or omit the
second map entirely, or derive values from actual config/vars (e.g., provider
and additional_label from settings) before calling MergeMaps to avoid stamping
placeholder metadata on emitted evidence.

Comment thread main.go
Comment thread Makefile
Comment on lines +26 to +34
test:
@go test ./...

clean: # Cleanup build artifacts
@rm -rf dist/*

build: clean ## Build the plugin package
@mkdir -p dist/
@go build -o dist/plugin main.go
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Declare non-file targets as .PHONY.

Targets that don't produce files (help, help-all, test, clean, build, run) should be declared .PHONY to prevent make from treating them as file targets. Without this, make will skip the target if a file with that name exists in the directory.

♻️ Proposed fix

Add this line near the top of the Makefile, after the OPA check:

 endif
 
+.PHONY: help help-all test clean build run
+
 ##@ Help
 help: ## Display this concise help, ie only the porcelain target
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 26 - 34, Add a .PHONY declaration for non-file targets
to prevent Make from treating them as actual files: declare .PHONY with the list
of targets (help, help-all, test, clean, build, run) near the top of the
Makefile (e.g., after the OPA check), so targets like test, clean, build, run
are always executed regardless of same-named files.

Comment thread Makefile
Comment on lines +36 to +37
run: build ## Execute the Concom agent with the built plugin
@../agent/dist/./concom agent --config ./.config/config.yaml No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider making the agent path configurable.

The hardcoded relative path ../agent/dist/./concom assumes a specific directory structure. While documented in the README, this makes the target fragile and less portable.

♻️ Proposed improvements

Option 1: Add a configurable variable

+# Path to the Concom agent binary (override with: make run AGENT_PATH=/custom/path)
+AGENT_PATH ?= ../agent/dist/concom
+
 ##@ Help
 run: build ## Execute the Concom agent with the built plugin
-	@../agent/dist/./concom agent --config ./.config/config.yaml
+	@$(AGENT_PATH) agent --config ./.config/config.yaml

Option 2: Add an existence check

 run: build ## Execute the Concom agent with the built plugin
+	`@test` -f ../agent/dist/concom || (echo "Error: agent not found at ../agent/dist/concom" && exit 1)
 	@../agent/dist/./concom agent --config ./.config/config.yaml
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: build ## Execute the Concom agent with the built plugin
@../agent/dist/./concom agent --config ./.config/config.yaml
run: build ## Execute the Concom agent with the built plugin
`@test` -f ../agent/dist/concom || (echo "Error: agent not found at ../agent/dist/concom" && exit 1)
@../agent/dist/./concom agent --config ./.config/config.yaml
🧰 Tools
🪛 checkmake (0.3.2)

[warning] 36-36: Required target "all" is missing from the Makefile.

(minphony)


[warning] 36-36: Required target "clean" must be declared PHONY.

(minphony)


[warning] 36-36: Required target "test" must be declared PHONY.

(minphony)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 36 - 37, The run target currently uses a hardcoded
agent path "../agent/dist/./concom"; make this configurable by introducing a
Makefile variable (e.g., AGENT_BIN or AGENT_PATH) with a sensible default and
replace the literal path in the run recipe with that variable, and also add an
existence check for $(AGENT_BIN) before executing (print an error and exit
non‑zero if missing) so the target is portable and fails fast when the binary is
not found.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main.go (1)

177-180: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent error return pattern.

Other error paths (lines 143, 149-151, 172-174) return &proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE} alongside the error, but this path returns nil. If the caller inspects the response status before checking the error, this could cause a nil pointer dereference.

Proposed fix for consistency
 	if err := apiHelper.CreateEvidence(ctx, evidences); err != nil {
 		l.logger.Error("Error creating evidence", "error", err)
-		return nil, err
+		return &proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE}, fmt.Errorf("failed to create evidence: %w", err)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.go` around lines 177 - 180, The CreateEvidence error path currently
returns nil, err which is inconsistent with other paths; change the return to
mirror others by returning a failure EvalResponse and the error: return
&proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE}, err. Update the
block where apiHelper.CreateEvidence(ctx, evidences) is called (and the
l.logger.Error("Error creating evidence", "error", err) line) to return
&proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE}, err instead of nil,
err so callers always get a non-nil response.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@main.go`:
- Line 157: Replace the direct proto field access request.PolicyPaths with the
nil-safe getter request.GetPolicyPaths() when calling policyEvaluator.Eval;
update the call in the expression evidences, err := policyEvaluator.Eval(ctx,
data, request.PolicyPaths, l.policyData, l.config.PolicyLabels) to use
request.GetPolicyPaths() so it matches other proto accesses like req.GetConfig()
and req.GetPolicyData() and avoids potential nil dereference.

In `@README.md`:
- Around line 49-50: Update the two YAML comment strings to fix
spelling/wording: change "Policy behaviour can be defined to later filter
policies to specific bundles per execution" to use "behavior" instead of
"behaviour", and change "This is useful if your plugin proccesses more than 1
type of component" to use "processes" instead of "proccesses" (i.e., replace the
exact substrings "behaviour" -> "behavior" and "proccesses" -> "processes" in
the README comment lines).

---

Outside diff comments:
In `@main.go`:
- Around line 177-180: The CreateEvidence error path currently returns nil, err
which is inconsistent with other paths; change the return to mirror others by
returning a failure EvalResponse and the error: return
&proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE}, err. Update the
block where apiHelper.CreateEvidence(ctx, evidences) is called (and the
l.logger.Error("Error creating evidence", "error", err) line) to return
&proto.EvalResponse{Status: proto.ExecutionStatus_FAILURE}, err instead of nil,
err so callers always get a non-nil response.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 57e74caf-5b95-4124-a2b6-6815e71472af

📥 Commits

Reviewing files that changed from the base of the PR and between 3e102a6 and 8bea3e3.

📒 Files selected for processing (2)
  • README.md
  • main.go

Comment thread main.go

policyEvaluator := internal.NewPolicyEvaluator(ctx, l.logger, stepActivities)
// Simple use case for evaluating all policies against the data collected
evidences, err := policyEvaluator.Eval(ctx, data, request.PolicyPaths, l.policyData, l.config.PolicyLabels)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use proto getter for nil-safety.

Static analysis flags direct proto field access. Use request.GetPolicyPaths() to ensure nil-safe access consistent with other proto field accesses in this file (e.g., req.GetConfig(), req.GetPolicyData()).

Proposed fix
-	evidences, err := policyEvaluator.Eval(ctx, data, request.PolicyPaths, l.policyData, l.config.PolicyLabels)
+	evidences, err := policyEvaluator.Eval(ctx, data, request.GetPolicyPaths(), l.policyData, l.config.PolicyLabels)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
evidences, err := policyEvaluator.Eval(ctx, data, request.PolicyPaths, l.policyData, l.config.PolicyLabels)
evidences, err := policyEvaluator.Eval(ctx, data, request.GetPolicyPaths(), l.policyData, l.config.PolicyLabels)
🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 157-157: avoid direct access to proto field request.PolicyPaths, use request.GetPolicyPaths() instead

(protogetter)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.go` at line 157, Replace the direct proto field access
request.PolicyPaths with the nil-safe getter request.GetPolicyPaths() when
calling policyEvaluator.Eval; update the call in the expression evidences, err
:= policyEvaluator.Eval(ctx, data, request.PolicyPaths, l.policyData,
l.config.PolicyLabels) to use request.GetPolicyPaths() so it matches other proto
accesses like req.GetConfig() and req.GetPolicyData() and avoids potential nil
dereference.

Comment thread README.md
Comment on lines +49 to +50
# Policy behaviour can be defined to later filter policies to specific bundles per execution
# This is useful if your plugin proccesses more than 1 type of component
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling/wording in YAML comments.

Line 49-50 has user-facing typos/inconsistent spelling (behaviour, proccesses). Please normalize to behavior and processes for clarity and consistency with the rest of the docs/code terminology.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 49 - 50, Update the two YAML comment strings to fix
spelling/wording: change "Policy behaviour can be defined to later filter
policies to specific bundles per execution" to use "behavior" instead of
"behaviour", and change "This is useful if your plugin proccesses more than 1
type of component" to use "processes" instead of "proccesses" (i.e., replace the
exact substrings "behaviour" -> "behavior" and "proccesses" -> "processes" in
the README comment lines).

@reecebedding reecebedding merged commit 736b275 into main May 28, 2026
2 checks passed
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