Skip to content

feat!: implement RunnerV2 with per-resource subjects and main/context input#5

Merged
gusfcarvalho merged 11 commits into
mainfrom
claude/silly-meitner-e8a328
Apr 23, 2026
Merged

feat!: implement RunnerV2 with per-resource subjects and main/context input#5
gusfcarvalho merged 11 commits into
mainfrom
claude/silly-meitner-e8a328

Conversation

@gusfcarvalho

@gusfcarvalho gusfcarvalho commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Migrate the plugin to RunnerV2 (adds Init, switches to RunnerV2GRPCPlugin, bumps compliance-framework/agent to v0.4.0).
  • Per-resource subjects and evidence: every Kubernetes resource instance configured under main_resources becomes its own subject with its own evidence, keyed by cluster_name/namespace/app_name/name. Policies are evaluated once per (resource instance, policy path); evidence is batched per cluster.
  • New Rego input schema (v2, breaking): input.main is the single resource under evaluation; input.context is {cluster, resources} — the full collected cluster snapshot. Replaces the old input.clusters[...] shape.
  • Config restructuring:
    • main_resources — optional subset of resources that produces subjects+evidence. Types only in resources are collected as policy context. Defaults to all of resources.
    • identity_labels — map of identity key → priority list of metadata.labels keys to try. Defaults to {"app_name": ["app.kubernetes.io/name", "app"]}. Falls back to metadata.name when no candidate matches, so app_name is never empty.
    • Reserved policy_input keys are now schema_version, source, main, context, subject, fleet.

Reference implementation: mirrors the RunnerV2 pattern used in plugin-dependabot (Granular mode — one evidence per subject, context assembled alongside).

Why

The previous implementation produced one evidence stream per cluster: all collected resources were flattened into a single Rego input document and the same cluster-level subjects were attached to every evidence. A compliance failure on one pod tainted the whole cluster subject, history tracking could not follow individual workloads, and it did not match the SubjectTemplate-based model the agent uses in v2. This PR aligns the plugin with that model so each workload is tracked as an individual compliance subject.

Breaking change — downstream action required

Existing Rego policies in plugin-k8s-policies and plugin-k8s-opres-policies read input.clusters[_].resources.pods[_] and will not evaluate against the new shape. Those repos must be updated to read input.main / input.context.resources.<type> in a coordinated follow-up PR.

The README contains a full v2 schema description and an updated Rego example that demonstrates cross-referencing input.main against input.context.resources.

Test plan

  • go build ./...
  • go test ./... (unit tests cover: per-resource evaluation call shape, identity-label resolution with candidate priority + metadata.name fallback, cluster-scoped resources omitting namespace, per-cluster evidence batching, Init upserting the expected subject-template set, main_resources validation, updated reserved-keys set)
  • go vet ./...
  • Manual end-to-end against a kind cluster: deploy a labeled workload, run the plugin with resources=["nodes","pods"], main_resources=["pods"], and a simple policy reading input.main.metadata.namespace and input.context.resources.nodes; verify one subject per pod with its own evidence.
  • Manual run against a multi-cluster config (EKS + kubeconfig) to confirm subjects include cluster_name and do not collide across clusters.
  • Follow-up PRs in plugin-k8s-policies / plugin-k8s-opres-policies to update to the v2 input schema.

🤖 Generated with Claude Code

… input

BREAKING CHANGE: The plugin now evaluates policies per individual Kubernetes
resource instead of per cluster. The Rego input schema moved from v1
(input.clusters[...]) to v2 (input.main + input.context). Policies that read
input.clusters[...] must be rewritten against the new shape.

- Bump compliance-framework/agent v0.2.3 -> v0.3.2
- Implement RunnerV2: add Init that registers one SubjectTemplate per
  main_resources entry (identity keys cluster_name/namespace/app_name/name)
  via runner.InitWithSubjectsAndRisksFromPolicies
- Switch plugin registration to runner.RunnerV2GRPCPlugin
- Eval now iterates per main resource instance: each becomes its own subject
  with its own evidence; policies run once per (instance, policy_path) and
  evidence is batched per cluster via CreateEvidence
- New config fields:
  - main_resources: subset of resources that produces subjects+evidence
    (defaults to all of resources); other types are collected as context only
  - identity_labels: map of identity key -> priority list of metadata.labels
    keys to try (default {"app_name": ["app.kubernetes.io/name", "app"]});
    falls back to metadata.name when no candidate matches
- Reserved policy_input keys updated to {schema_version, source, main, context}
- README rewritten for v2 schema, new config fields, and subject model

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 22, 2026 09:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the Kubernetes plugin to the agent’s RunnerV2 interface and changes evaluation semantics from cluster-level to per-resource-instance subjects/evidence, along with a breaking v2 Rego input schema (input.main + input.context).

Changes:

  • Implement Init + switch to RunnerV2GRPCPlugin, and batch CreateEvidence per cluster while evaluating policies per (resource instance, policy path).
  • Add config support for main_resources and identity_labels, and update reserved policy_input keys to the v2 schema.
  • Update tests and README to reflect per-resource subjects and the new input schema.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
main.go Implements RunnerV2 Init, rewrites eval loop for per-resource evaluation, adds subject/template/label helpers, updates Rego input builder, switches plugin to RunnerV2 GRPC plugin.
config.go Adds parsing/validation for main_resources and identity_labels, updates reserved policy_input keys for v2 schema.
main_test.go Expands tests to validate per-resource evaluation call shape, identity label resolution, cluster-scoped namespace handling, evidence batching, and Init behavior.
config_test.go Adds coverage for main_resources defaults/subsets and identity_labels parsing/validation; updates reserved-key tests.
README.md Documents breaking schema change, new config fields, per-resource subject/evidence model, and v2 policy input examples.
go.mod / go.sum Bumps compliance-framework/agent and related transitive deps to support RunnerV2.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
Comment thread config.go
Comment thread main.go Outdated
Comment thread main.go Outdated
Comment thread README.md Outdated
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread go.mod
Comment thread main.go
Comment thread main.go Outdated
Comment thread main.go Outdated
Comment thread config.go
Comment thread README.md Outdated
Comment thread README.md
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread config.go
Comment thread config.go Outdated
Comment thread main.go
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go
Comment thread main.go Outdated
Comment thread main.go
Comment thread config.go
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
Comment thread config.go
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
Comment thread main.go Outdated
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
@gusfcarvalho gusfcarvalho merged commit 5259cdd into main Apr 23, 2026
1 check 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