Skip to content

path-wildcards: anchored trailing-* + per-endpoint port + R0040 args#807

Open
entlein wants to merge 17 commits into
kubescape:mainfrom
k8sstormcenter:upstream-pr/sbob-path-wildcards
Open

path-wildcards: anchored trailing-* + per-endpoint port + R0040 args#807
entlein wants to merge 17 commits into
kubescape:mainfrom
k8sstormcenter:upstream-pr/sbob-path-wildcards

Conversation

@entlein
Copy link
Copy Markdown

@entlein entlein commented May 15, 2026

Overview

  • ap.was_path_opened_with_suffix/prefix: in pass-through mode, only
    scan Values (concrete paths). Wildcard Patterns are delegated
    to CompareDynamic rather than raw strings.HasPrefix/HasSuffix
    a wildcard pattern can't safely answer a suffix/prefix question
    without dynamic matching.
  • New R0040 rule helper ap.was_executed_with_args: returns true
    when the profile contains an entry whose Path matches AND whose
    Args vector matches (literal-equality, one-position
    wildcard, or * zero-or-more trailing tokens).

Summary by CodeRabbit

  • New Features

    • Wildcard-aware file-open matching in application profiles.
    • Per-path exec argument-vector projection and anchored arg matching.
  • Bug Fixes

    • Stricter exec-args constraint handling to reduce false positives and ensure correct back-compat behavior.
  • Tests

    • New unit tests for exec/path projections and matching; new end-to-end component test for application-profile opens (with additional deployment fixtures).
  • Chores

    • Dependency upgrades across core libraries and tooling.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Warning

Review limit reached

@entlein, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff50fa7e-be1b-4743-8b42-9b94e7c389b2

📥 Commits

Reviewing files that changed from the base of the PR and between b27f8bc and e5069fd.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (13)
  • .github/workflows/component-tests.yaml
  • go.mod
  • pkg/objectcache/containerprofilecache/projection_apply.go
  • pkg/objectcache/containerprofilecache/projection_apply_test.go
  • pkg/objectcache/projection_types.go
  • pkg/objectcache/v1/mock.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open_test.go
  • tests/component_test.go
  • tests/resources/curl-user-profile-wildcards-deployment.yaml
  • tests/resources/nginx-user-profile-deployment.yaml
📝 Walkthrough

Walkthrough

This PR extends ApplicationProfile-based CEL rule evaluation by adding per-path exec-argument projection, implementing argument-aware matching in CEL with wildcard support, refining open-path pattern handling to avoid false negatives, and validating the changes with comprehensive end-to-end component tests using new Kubernetes test workloads.

Changes

ApplicationProfile CEL Rule Evaluation Improvements

Layer / File(s) Summary
Dependency version updates
go.mod
Direct and indirect dependency versions are bumped for kubescape/storage, anchore/syft, logrus, sqlite, and containerd/docker ecosystems. A replace directive pins opencontainers/runtime-spec to v1.2.1.
Exec-by-path projection foundation
pkg/objectcache/projection_types.go, pkg/objectcache/containerprofilecache/projection_apply.go, pkg/objectcache/containerprofilecache/projection_apply_test.go
RuleProjectionSpec gains ExecsByPath field to store per-Path argv vectors; extractExecsByPath builds the mapping from cp.Spec.Execs, appending multiple argv lists for the same path, cloning slices to avoid aliasing, and representing nil Args as non-nil empty slices. Tests verify correct append semantics, cloning, and nil-vs-empty handling.
Mock projection for exec-by-path
pkg/objectcache/v1/mock.go
RuleObjectCacheMock.GetProjectedContainerProfile populates ExecsByPath alongside Execs when building projected container profiles for tests.
Exec args wildcard matching in CEL evaluation
pkg/rulemanager/cel/libraries/applicationprofile/exec.go, pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go
wasExecutedWithArgs now parses and validates runtime args from CEL, consults ExecsByPath for matching via CompareExecArgs (supporting single-position and * zero-or-more wildcards), and implements back-compat fallback for absent ExecsByPath entries. Test expectations updated to enforce anchored argv matching and new TestExecWithArgsWildcardInProfile validates wildcard semantics.
Open-path pattern matching refinement
pkg/rulemanager/cel/libraries/applicationprofile/open.go, pkg/rulemanager/cel/libraries/applicationprofile/open_test.go
wasPathOpenedWithSuffix and wasPathOpenedWithPrefix now scan only cp.Opens.Values when cp.Opens.All=true, avoiding false negatives from wildcard-shaped patterns; doc comment clarifies wasPathOpenedWithFlags parses but does not use flags for matching. New tests verify patterns are ignored in pass-through mode; flags-based tests refactored to separate path-only and flags-inclusive evaluation.
Component test for ApplicationProfile Opens matching
tests/component_test.go, tests/resources/curl-user-profile-wildcards-deployment.yaml, tests/resources/nginx-user-profile-deployment.yaml, .github/workflows/component-tests.yaml
Test_27_ApplicationProfileOpens validates R0002 rule against recorded nginx profiles (asserting absolute paths only) and user-defined curl profiles with exact/wildcard/dynamic-segment Opens patterns. Includes helpers to deploy profiles, exec cat, poll alerts, and verify alert presence/absence per test case. Two test workload deployments added and test matrix updated.

Sequence Diagram(s)

sequenceDiagram
  participant CEL as CEL Runtime
  participant wasExec as wasExecutedWithArgs
  participant Cache as Profile Cache
  participant Matcher as CompareExecArgs
  CEL->>wasExec: path, runtime args
  wasExec->>Cache: load projected container profile
  wasExec->>Cache: lookup ExecsByPath[path]
  Cache-->>wasExec: projected argv vectors or nil
  alt ExecsByPath present (constraint mode)
    wasExec->>Matcher: compare runtime args vs profile args
    Matcher-->>wasExec: match result with wildcard support
  else ExecsByPath absent (back-compat)
    wasExec-->>CEL: match any runtime args if path exists
  end
  wasExec-->>CEL: true or false
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • kubescape/node-agent#799: Both PRs extend the rule-aware projected profile pipeline by updating the same ApplicationProfile exec CEL logic and the underlying container-profile projection model—implement Rule-Aware Profile Projection #799 moves exec checks onto projected data, and this main PR further refines it by projecting ExecsByPath (derived from cp.Spec.Execs) and using it in wasExecutedWithArgs to enforce anchored/wildcard argv-vector matching.
  • kubescape/node-agent#800: Overlapping changes to how recorded exec path values are determined; affects the Exec.Path inputs consumed by the new ExecsByPath matching logic.
  • kubescape/node-agent#788: Related cache/projection changes that surface cp.Spec.Execs to rule evaluation, which this PR builds upon for deeper arg-vector matching.

Suggested reviewers

  • matthyx
  • slashben

Poem

🐰 The args hop in, by path they're sorted,
Wildcards wildly, patterns contorted—
Opens pared down to concrete lights,
CEL now matches with clearer rights.
🥕 Projection hopped and tests took flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.91% 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 'path-wildcards: anchored trailing-* + per-endpoint port + R0040 args' accurately reflects the main changes: path wildcard support, anchored trailing-* syntax, per-endpoint port handling, and new R0040 rule argument matching. It is concise and specific.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@entlein entlein marked this pull request as ready for review May 15, 2026 20:57
@entlein
Copy link
Copy Markdown
Author

entlein commented May 16, 2026

@CodeRabbit review this please together with kubescape/storage#323

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch details of the linked storage PR
gh pr view 323 --repo kubescape/storage --json title,body,files,additions,deletions,changedFiles
echo "---FILES---"
gh pr diff 323 --repo kubescape/storage

Length of output: 143814


🏁 Script executed:

#!/bin/bash
# Fetch node-agent PR `#807` diff
gh pr diff 807 --repo kubescape/node-agent
echo "---PR META---"
gh pr view 807 --repo kubescape/node-agent --json title,body,files,additions,deletions,changedFiles

Length of output: 28898


🏁 Script executed:

#!/bin/bash
# Check if CompareExecArgs exists in the storage repo
gh api repos/kubescape/storage/git/trees/main?recursive=1 | jq -r '.tree[].path' | grep -i "compareexec\|compare_exec\|execargs"
echo "---SEARCH CODE---"
# Search for CompareExecArgs in storage repo via code search
gh api "search/code?q=CompareExecArgs+repo:kubescape/storage&per_page=10" | jq -r '.items[].path'

Length of output: 18


🏁 Script executed:

#!/bin/bash
# Get the head branch of storage PR `#323`
gh pr view 323 --repo kubescape/storage --json headRefName,headRefOid
echo "---SEARCH BRANCH---"
# Search for CompareExecArgs on the PR `#323` branch
gh api "repos/kubescape/storage/contents/pkg/registry/file/dynamicpathdetector" \
  --jq '.[].name' 2>/dev/null || echo "API failed"
echo "---FILE LIST ON BRANCH---"
gh api "repos/kubescape/storage/git/refs/heads" | jq -r '.[].ref' | head -20
echo "---NODE-AGENT BRANCH---"
gh pr view 807 --repo kubescape/node-agent --json headRefName,headRefOid
echo "---SEARCH NODE-AGENT BRANCH---"
# Check if CompareExecArgs is defined locally in the node-agent repo
gh api "search/code?q=CompareExecArgs+repo:kubescape/node-agent&per_page=10" | jq -r '.items[].path'

Length of output: 1010


🏁 Script executed:

#!/bin/bash
# Fetch the contents of utils.go from the storage PR branch
gh api "repos/kubescape/storage/contents/pkg/registry/file/dynamicpathdetector/utils.go?ref=upstream-pr/sbob-path-wildcards" \
  | jq -r '.content' | base64 -d

echo "---ANALYZER TAIL (search for CompareExecArgs)---"
# Check if CompareExecArgs appears in any file on the branch
gh api "repos/kubescape/storage/git/trees/upstream-pr%2Fsbob-path-wildcards?recursive=1" \
  | jq -r '.tree[].path' | xargs -I{} sh -c \
  'content=$(gh api "repos/kubescape/storage/contents/{}?ref=upstream-pr/sbob-path-wildcards" 2>/dev/null | jq -r ".content // empty" | base64 -d 2>/dev/null); echo "$content" | grep -l "CompareExecArgs" && echo "FOUND IN: {}"' 2>/dev/null | grep "FOUND IN" || true

echo "---DIRECT GREP via search---"
gh api "search/code?q=CompareExecArgs+repo:kubescape/storage+ref:upstream-pr/sbob-path-wildcards" 2>/dev/null | jq -r '.total_count, (.items[].path)' || echo "search API does not filter by ref"

Length of output: 241


🏁 Script executed:

#!/bin/bash
# Try to get the diff more specifically for utils.go in storage PR `#323` 
gh pr diff 323 --repo kubescape/storage -- "*.go" 2>/dev/null | grep -A 30 "CompareExecArgs" || echo "Not found in storage PR diff"

echo "---CHECK UTILS GO IN STORAGE MAIN---"
gh api "repos/kubescape/storage/contents/pkg/registry/file/dynamicpathdetector/utils.go" \
  2>/dev/null | jq -r '.content' | base64 -d || echo "utils.go not in main"

echo "---CHECK EXEC ARGS IN STORAGE MAIN ALL GO FILES---"
gh api "search/code?q=ExecArgs+repo:kubescape/storage&per_page=10" | jq -r '.total_count, (.items[] | .path + " -> " + .name)'

Length of output: 422


@entlein: Reviewed PR #807 (node-agent) together with kubescape/storage#323. Both are well-structured and the test coverage is extensive. Here are my findings, ordered by severity:


🔴 Critical — Build break

CompareExecArgs is not defined in kubescape/storage

exec.go calls dynamicpathdetector.CompareExecArgs(profileArgs, runtimeArgs) but this function does not exist anywhere in kubescape/storage — confirmed via code search against both main and storage PR #323's diff. This will cause a compilation failure in node-agent.

CompareExecArgs needs to be added to storage PR #323. Based on the exec-test cases (literal equality, single-position wildcard, * zero-or-more trailing tokens), it should mirror compareSegments from the rewritten CompareDynamic, but operating on a []string argument vector rather than a /-split path:

// CompareExecArgs reports whether runtimeArgs is matched by profileArgs.
// profileArgs may contain DynamicIdentifier (⋯, matches exactly one arg)
// or WildcardIdentifier (*, matches zero-or-more trailing args).
func CompareExecArgs(profileArgs, runtimeArgs []string) bool {
    return compareSegments(profileArgs, runtimeArgs)
}

The existing compareSegments in analyzer.go already implements this logic generically over []string. Exposing a thin public wrapper would avoid duplication.

Additionally, the comment in exec_test.go references the wrong repository — it should reference kubescape/storage#323, not k8sstormcenter/storage#23:

// dynamicpathdetector.CompareExecArgs (added in
// k8sstormcenter/storage#23 — ...   ← should be kubescape/storage#323

🟡 Medium — Missing test coverage

was_path_opened_with_flags function loses all direct tests

open_test.go removes TestOpenWithFlagsInProfile, TestOpenWithFlagsNoProfile, and TestOpenWithFlagsCompilation without replacement. The wasPathOpenedWithFlags function is still present in open.go (and even gains a new doc comment in this PR), but now has zero test coverage. If the flags argument is ever wired up in a future spec revision, there will be no baseline to diff against.

Consider retaining at least the compilation test and the no-profile guard test.


🟡 Medium — Misleading PR description / silent false-negatives

Patterns are skipped entirely, not "delegated to CompareDynamic"

The PR description states:

Wildcard Patterns are delegated to CompareDynamic rather than raw strings.HasPrefix/HasSuffix

But the actual change in open.go removes the Patterns loop entirely — patterns don't contribute at all to suffix/prefix answers in pass-through mode, regardless of whether CompareDynamic would match. This is the correct conservative fix (you can't answer "ends with .log?" by running CompareDynamic without a concrete candidate), but the description should be updated to say "Patterns are excluded from suffix/prefix scanning in pass-through mode" to avoid confusion for future rule authors who wonder why a profiled path that was collapsed to doesn't surface in a suffix query.


🔵 Low — Subtle back-compat semantics in wasExecutedWithArgs

In exec.go, both the exact-path and pattern branches return true unconditionally when cp.ExecsByPath[path] is absent:

} else {
    // No ExecsByPath entry for this path — back-compat: treat as
    // "no argv constraint", match.
    return types.Bool(true)
}

This means: any profile built before ExecsByPath projection was active gets unconditional path-only matching, silently ignoring runtimeArgs. While intentional, this creates an invisible two-tier behavior: new profiles enforce arg constraints, old profiles don't. Rule authors writing R0040 expressions may be surprised when a newly-deployed workload with the same path suddenly starts enforcing args that the legacy profile never evaluated. A log-level warning ("back-compat: ExecsByPath absent for %s, matching on path only") would make the fallback observable.


🔵 Low — Storage PR #323 notes

removeEndpoint mutates the backing array in-place (append(s[:i], s[i+1:]...) in MergeDuplicateEndpoints). This is safe because the return value is immediately reassigned, but it's the kind of subtle slice mutation that trips up future readers. A short comment clarifying this intent would help.

effectiveThreshold and FindConfigForPath tiebreak parity: Both correctly use strict > (first entry wins on equal-length prefixes). The comment in effectiveThreshold rightly warns about this, but NewPathAnalyzerWithConfigs could deduplicate or log a warning on duplicate prefixes at construction time to surface misconfiguration earlier.

consolidateOpens quadratic worst-case: The outer loop is O(literals) × O(patterns), and each CompareDynamic call with mid-path * can backtrack O(segment²). This is fine for realistic filesystem profiles but worth noting in the function doc for operators tuning CollapseConfig thresholds for very wide trees.


Summary

Issue Location Severity
CompareExecArgs missing from kubescape/storage exec.go + storage PR #323 🔴 Build break
Stale comment k8sstormcenter/storage#23 exec_test.go 🔵
was_path_opened_with_flags loses all test coverage open_test.go 🟡
PR description misleads on pattern delegation open.go 🟡
Back-compat silent tier in wasExecutedWithArgs exec.go 🔵
removeEndpoint in-place mutation undocumented analyze_endpoints.go 🔵

The storage PR #323 changes are solid — the per-port endpoint isolation, CompareDynamic rewrite with proper trailing-* anchoring, consolidateOpens, bufPool, and the extensive test suite all look correct. The node-agent changes are also logically sound, contingent on resolving the missing CompareExecArgs definition.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 16, 2026
…prefix + exec-args

Two doc-only fixes for CodeRabbit cross-PR advisory:

#7 (NA kubescape#807): ap.was_path_opened_with_suffix / _prefix — explicitly
document the false-negative gap when the projection is in pass-through
mode (cp.Opens.All=true). Wildcard Patterns are skipped from the
suffix/prefix scan because their token-bearing text doesn't safely
answer suffix questions. Rule authors who need wildcard-aware coverage
should either declare an Opens-projection slice (so SuffixHits/PrefixHits
become authoritative for the literals they care about) or use
ap.was_path_opened (which runs CompareDynamic over Patterns).

#8 (NA kubescape#807): wasExecutedWithArgs — document the three states of
ExecsByPath:
  1. Path absent from Execs.Values → exec not allowed, fall through.
  2. Path in Values, ABSENT from ExecsByPath → legacy back-compat
     "no argv constraint", match.
  3. Path in Values, PRESENT with empty arg list [] → explicit
     "ran with no args" constraint, NOT a wildcard.
The distinction is load-bearing for profile authors: an entry of
{Path: ..., Args: []} is a constraint, not a free pass.

No behavioural change. Tests pass unchanged.
@entlein
Copy link
Copy Markdown
Author

entlein commented May 16, 2026

@coderabbitai review

Collective re-review request after applying your atomic-split advisory + rabbit-feedback fixes across the full SBOB upstream PR set. Each PR is now scoped to a single tier per your dependency map:

Tier 0 (opens):

Tier 2 (execs):

Tier 3 (network):

Tier 4 (tamper/sign):

Umbrellas:

Please confirm atomicity per your earlier advisory and flag any remaining cross-PR coupling we missed.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll fetch all PRs in the set to verify atomicity and cross-PR coupling.


🏁 Script executed:

#!/bin/bash
set -e

# Fetch metadata for all storage PRs
for pr in 322 323 324 325 326; do
  echo "===STORAGE PR $pr==="
  gh pr view $pr --repo kubescape/storage --json title,state,headRefName,baseRefName,additions,deletions,changedFiles 2>/dev/null || echo "NOT FOUND"
done

# Fetch metadata for all node-agent PRs
for pr in 805 806 807 808 809 810 811 812; do
  echo "===NODE-AGENT PR $pr==="
  gh pr view $pr --repo kubescape/node-agent --json title,state,headRefName,baseRefName,additions,deletions,changedFiles 2>/dev/null || echo "NOT FOUND"
done

Length of output: 2908


🏁 Script executed:

#!/bin/bash
# Fetch diffs for storage PRs
for pr in 322 323 324 325 326; do
  echo "===STORAGE DIFF $pr==="
  gh pr diff $pr --repo kubescape/storage 2>/dev/null | head -600 || echo "DIFF FAILED"
  echo "---END STORAGE $pr---"
done

Length of output: 101307


🏁 Script executed:

#!/bin/bash
# Fetch diffs for node-agent PRs (excluding `#807` which we already have)
for pr in 805 806 808 809 810 811 812; do
  echo "===NODE-AGENT DIFF $pr==="
  gh pr diff $pr --repo kubescape/node-agent 2>/dev/null | head -500 || echo "DIFF FAILED"
  echo "---END NODE-AGENT $pr---"
done

Length of output: 93396


@entlein: Good progress on the split. After inspecting all 13 diffs in detail, here is the atomicity verdict and the remaining coupling issues that need resolution before merge ordering can be safely established.


✅ Confirmed Atomic (no cross-PR coupling issues found)

PR Verdict
kubescape/storage#322 ✅ Self-contained — CompareExecArgs + tests, no overlap with other PRs
#805 ✅ Self-contained — busybox-symlink resolveExecPath + 3-arg CEL overload
#809 ✅ Self-contained — cmd/sign-object CLI, no runtime entanglement
#811 ✅ Self-contained — removes Patterns loop from wasPathOpenedWithSuffix/Prefix + doc comments

🔴 Remaining Cross-PR Coupling (must resolve before merging)

1 — storage#324 ↔ storage#325: protobuf test cannot pass without the sibling

storage#324 adds NetworkNeighbor.IPAddresses []string to the struct and a TestNetworkNeighbor_IPAddresses_ProtobufRoundtrip test that calls Marshal() / Unmarshal().

storage#325's generated.pb.go is where the encoding of that field actually lives (tag 0x4a = field 9, inside NetworkNeighbor.MarshalToSizedBuffer and the corresponding Size() / Unmarshal() paths). The roundtrip test in #324 will fail to compile and run on its own because the generated protobuf code for the field is in #325.

Fix options:

  • Option A (preferred): Move the IPAddresses protobuf encoding from generated.pb.go in storage#325 into storage#324 so the test and the encoding ship in the same PR.
  • Option B: Mark #324 as depending on #325 and merge them atomically in CI (same release train).

2 — node-agent#808 ↔ node-agent#812: extractExecsByPath is defined in both

node-agent#812 adds ExecsByPath map[string][]string to ProjectedContainerProfile (in projection_types.go) and adds extractExecsByPath to projection_apply.go.

node-agent#808 also adds an identical extractExecsByPath to projection_apply.go and calls pcp.ExecsByPath = extractExecsByPath(cp).

If #812 merges first (which it must, since #807 reads cp.ExecsByPath), #808 will hit a direct merge conflict on the same function in the same file.

Fix: Rebase #808 on top of #812 and remove its copy of extractExecsByPath. After the rebase, #808 only needs the pcp.ExecsByPath = extractExecsByPath(cp) call line — the function definition is already present from #812.


3 — node-agent#806 (Tier 3) depends on node-agent#808 (Tier 4)

node-agent#806's matchIPField routes wildcard IP entries (CIDRs, *) to field.Patterns and calls networkmatch.MatchIP(field.Patterns, observed). For field.Patterns to contain anything, extractEgressAddresses / extractIngressAddresses must append n.IPAddresses... — and that append is in node-agent#808's projection_apply.go, not in #806 itself.

Without #808 merged first, a profile entry with e.g. IPAddresses: ["10.0.0.0/8"] will never reach Patterns, so matchIPField will always fall through to a miss for CIDR-only entries. Tier 3 silently degrades without Tier 4 being present.

Fix: Promote the extractEgressAddresses / extractIngressAddresses n.IPAddresses... append into node-agent#806 (it logically belongs with the network-wildcard CEL work), and remove it from #808 after rebasing. This restores the Tier 3-before-Tier 4 ordering the map intends.


4 — go.mod downgrades exist only in the umbrella (storage#326)

storage#326 has three dependency version changes absent from all atomic tier PRs:

github.com/anchore/syft         v1.42.3 → v1.32.0
github.com/anchore/stereoscope  v0.1.22 → v0.1.9
github.com/opencontainers/runtime-spec v1.3.0 → v1.2.1

If the tier PRs (#322#325) are merged individually against main, they will carry syft v1.42.3. The umbrella then merges them all and applies the downgrades. This means the umbrella cannot be trivially assembled from its tier PRs — the umbrella is doing real independent work (the dependency pin). Either:

  • Add a thin go.mod-only PR (no code changes) that must land before #326, or
  • Move the downgrades into whichever tier PR first introduces the dependency (likely storage#323 or storage#324 if networkmatch pulls in syft transitively).

⚠️ Minor / Cosmetic

Item Location
storage#323 title still says "R0040 args" That scope moved to node-agent#807; update the title
node-agent#808 still bundles 4 concerns stampOverlayIdentity, tamper detection, IPAddresses extraction, isNetworkIPWildcard/DNS classifiers — acceptable if you want a single Tier 4 PR, but worth noting for future bisect

Revised Merge Ordering (after fixes)

graph TD
  S322["storage#322\nCompareExecArgs"] --> NA807["node-agent#807\nR0040 args"]
  S323["storage#323\npath-wildcards core"] --> NA811["node-agent#811\nwas_path_opened*"]
  S323 --> S325["storage#325\nCollapseConfig CRD"]
  S324["storage#324 + IPAddresses pb\nnetworkmatch"] --> NA806["node-agent#806\nnetwork CEL"]
  S324 --> NA808["node-agent#808\nprojection overlay + tamper"]
  S325 --> NA808
  NA812["node-agent#812\nExecsByPath surface"] --> NA807
  NA812 --> NA808
  NA805["node-agent#805\nresolveExecPath"] --> NA807
  NA808 --> NA806
  NA808 --> S326["storage#326 umbrella"]
  NA810["node-agent#810 umbrella"] --> S326
Loading

entlein added a commit to k8sstormcenter/node-agent that referenced this pull request May 16, 2026
…e#807, kubescape#808) (#44)

* fix(containerprofilecache): honor verify result before merging user overlay

CodeRabbit upstream PR kubescape#808 / containerprofilecache.go:414 (Major).
The verifyUserApplicationProfile and verifyUserNetworkNeighborhood
methods already return a boolean reflecting verification outcome —
true when the overlay is unsigned OR when verification succeeded OR
in permissive mode (EnableSignatureVerification=false); false only
in strict mode on actual tamper.

The two call sites in projection-load were discarding that return,
so tampered overlays in strict mode silently merged anyway. The
R1016 alert was emitted but the protection was advisory only.

Now: when verify returns false (strict mode + tamper detected) the
overlay is nilled out before the merge step so the cache never
projects a known-tampered profile. Permissive mode is unchanged —
verify always returns true, the overlay still merges, R1016 still
fires.

New tests:

  - TestVerifyAP_StrictMode_ReturnsFalseOnTamper — sign + tamper an
    ApplicationProfile, construct a cache with
    EnableSignatureVerification=true, and assert
    verifyUserApplicationProfile returns false (caller drops overlay).
  - TestVerifyNN_StrictMode_ReturnsFalseOnTamper — symmetric pin for
    the NetworkNeighborhood path.

The existing legacy-permissive tamper test
(TestVerifyAP_TamperedProfile_PopulatesDedupMap) continues to pass
unchanged — that path still returns true with the R1016 emitted.

* docs(applicationprofile): rule-author contracts on opens-with-suffix/prefix + exec-args

Two doc-only fixes for CodeRabbit cross-PR advisory:

#7 (NA kubescape#807): ap.was_path_opened_with_suffix / _prefix — explicitly
document the false-negative gap when the projection is in pass-through
mode (cp.Opens.All=true). Wildcard Patterns are skipped from the
suffix/prefix scan because their token-bearing text doesn't safely
answer suffix questions. Rule authors who need wildcard-aware coverage
should either declare an Opens-projection slice (so SuffixHits/PrefixHits
become authoritative for the literals they care about) or use
ap.was_path_opened (which runs CompareDynamic over Patterns).

#8 (NA kubescape#807): wasExecutedWithArgs — document the three states of
ExecsByPath:
  1. Path absent from Execs.Values → exec not allowed, fall through.
  2. Path in Values, ABSENT from ExecsByPath → legacy back-compat
     "no argv constraint", match.
  3. Path in Values, PRESENT with empty arg list [] → explicit
     "ran with no args" constraint, NOT a wildcard.
The distinction is load-bearing for profile authors: an entry of
{Path: ..., Args: []} is a constraint, not a free pass.

No behavioural change. Tests pass unchanged.

* deps: pin stereoscope v0.1.9 + runtime-spec v1.2.1 (compat with kubescape/syft fork)

Storage rc1 bumped to syft v1.42.4 (CVE-2026-33481), which transitively
requires stereoscope v0.1.22 + runtime-spec v1.3.0. Those versions use
the new moby/moby/client submodule API, which is incompatible with
inspektor-gadget's moby/moby umbrella requirement on the node-agent
side (ambiguous-import wall — see issue #45).

Node-agent stays on kubescape/syft v1.32.0-ks.2 via the existing
replace, but transitive resolution from storage's go.mod pulls the
newer stereoscope into the build, breaking the build with:

  undefined: client.New
  undefined: client.PingOptions

Adds two replace directives to force the older transitive chain that
matches kubescape/syft v1.32.0-ks.2's expectations:

  github.com/anchore/stereoscope     => v0.1.9-0.20250826202322-...
  github.com/opencontainers/runtime-spec => v1.2.1

This is the minimum set needed for node-agent to build cleanly against
storage rc1 (with syft v1.42.4) while still using kubescape/syft on
its own side. Storage's CVE fix remains in effect at the storage
binary; node-agent's syft surface is unchanged.

Verified locally:
  go build ./...          ok
  go test ./pkg/objectcache/... ./pkg/rulemanager/... -count=1
                          → 30+ packages ok

---------

Co-authored-by: Entlein <eineintlein@gmail.com>
@matthyx matthyx moved this to WIP in KS PRs tracking May 26, 2026
@matthyx
Copy link
Copy Markdown
Contributor

matthyx commented May 27, 2026

Blocking: this branch still does not build against current main. Running go test ./pkg/rulemanager/cel/libraries/applicationprofile/... fails in pkg/rulemanager/cel/libraries/applicationprofile/exec.go because the new wasExecutedWithArgs path references cp.ExecsByPath and dynamicpathdetector.CompareExecArgs, but neither symbol exists in this branch's current dependency state (ProjectedContainerProfile has no ExecsByPath, and storage v0.0.258 has no CompareExecArgs). As-is this PR is not mergeable on its own; it needs to be explicitly rebased onto the stacked changes that introduce those symbols, or the new calls need to be gated/removed here.

entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 27, 2026
This PR (R0040 args consumer) references dynamicpathdetector.CompareExecArgs,
which ships in k8sstormcenter/storage's upstream-pr/sbob-execs branch (the
storage sibling of kubescape/storage#322), not in any released
kubescape/storage tag. The PR's existing go.mod pin (v0.0.258) does not
contain it.

Adds a replace directive to the sister branch's current tip (5e39d001 —
feat(apis): add ExecCalls.ArgsRequired + MatchExecArgs to express 'no args').
Removed when the sister storage PR kubescape/storage#322 merges and a
release ships CompareExecArgs.

Companion to the stacking-on-NA-kubescape#812 cherry-pick (provides cp.ExecsByPath)
in the previous commits on this branch.

Resolves the matthyx 'does not build' blocker on PR kubescape#807 (2026-05-27).
@entlein entlein force-pushed the upstream-pr/sbob-path-wildcards branch from 70a9d9b to ce0d6a4 Compare May 27, 2026 18:37
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

🧹 Nitpick comments (3)
pkg/rulemanager/cel/libraries/applicationprofile/open_test.go (1)

117-122: ⚡ Quick win

Keep direct coverage for ap.was_path_opened_with_flags.

These edits convert the old flag-focused cases into ap.was_path_opened(...), so wasPathOpenedWithFlags no longer has a test for its remaining contract: CEL list parsing and malformed-flags rejection. Please keep at least one happy-path case and one invalid-flags case here.

Also applies to: 186-205, 210-241

🤖 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 `@pkg/rulemanager/cel/libraries/applicationprofile/open_test.go` around lines
117 - 122, Restore direct coverage for ap.was_path_opened_with_flags in
TestOpenInProfile by adding at least two cases: one happy-path where the CEL
list of flags parses correctly and the function returns true (e.g., supply a
valid flags list and expected open event), and one invalid-flags case where a
malformed flags CEL list causes the function to reject the input (assert an
error or false per contract). Locate the test table or assertions around
TestOpenInProfile and reintroduce cases that call ap.was_path_opened_with_flags
(not ap.was_path_opened) so you exercise CEL list parsing and malformed-`flags`
rejection behavior; keep the existing ap.was_path_opened cases as well.
go.mod (1)

474-474: Supply chain and merge coordination risk.

Using a fork (k8sstormcenter/storage) instead of the canonical kubescape/storage introduces supply chain concerns and requires careful coordination:

  • Provenance: Verify that the fork maintainer is trustworthy and the fork accurately cherry-picks only the needed CompareExecArgs changes
  • Atomicity: Ensure this replace directive is removed in the same release cycle that upgrades to the official storage version containing the fix
  • Drift risk: The fork may diverge from upstream, introducing subtle behavioral differences

Consider these alternatives to reduce risk:

  1. Feature gating: Guard the new ExecsByPath / CompareExecArgs calls behind a feature flag until storage PR #323 ships
  2. Atomic merge: Coordinate merging this PR simultaneously with storage PR #323 to avoid the fork entirely
  3. Tracking issue: Create a GitHub issue to track removal of this replace directive, linked to storage PR #323 closure
🤖 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 474, The go.mod replace directive pointing at
github.com/k8sstormcenter/storage (replacing github.com/kubescape/storage)
creates supply-chain and merge coordination risk; either remove this replace and
coordinate merging with the upstream storage PR `#323` so the official module
contains CompareExecArgs/ExecsByPath, or gate uses of the new APIs
(ExecsByPath/CompareExecArgs) behind a feature flag until upstream lands, and
add a tracking GitHub issue to remove the go.mod replace as soon as storage PR
`#323` is merged; ensure the replace removal is done atomically with the upgrade
to the official release to avoid drift.
pkg/rulemanager/cel/libraries/applicationprofile/exec.go (1)

127-130: ⚡ Quick win

Add visibility when legacy profiles bypass argv constraints.

Line 127 and Line 140 return true when ExecsByPath lacks a key for a matched path. Add a warn/metric (ideally once per container/profile hash) so silent back-compat matches are observable.

Also applies to: 140-142

🤖 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 `@pkg/rulemanager/cel/libraries/applicationprofile/exec.go` around lines 127 -
130, The branch that returns types.Bool(true) when ExecsByPath lacks a key for a
matched path (the legacy "no argv constraint" back-compat in the ExecsByPath
handling) should emit an observable signal so these silent matches are visible;
update the code paths that currently return types.Bool(true) (the branches
referencing ExecsByPath) to log or increment a metric including the
container/profile hash and ensure the signal is emitted at most once per
container/profile by deduplicating with a short-lived in-memory cache or an
"emit-once" set keyed by containerID+profileHash; apply the same change to both
places where types.Bool(true) is returned so legacy bypasses are recorded.
🤖 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 `@go.mod`:
- Line 474: Add a clear TODO comment immediately above the replace directive
"replace github.com/kubescape/storage => github.com/k8sstormcenter/storage
v0.0.240-0.20260527160734-5e39d0018391" explaining this is a temporary override,
referencing the upstream storage PR (`#323`), the criteria for removal (e.g., when
that PR is merged and a released version is available), and include the
author/date or ticket that added the workaround so it can be tracked and removed
later.

In `@pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go`:
- Around line 317-318: Update the test comment in exec_test.go that references
the old storage repo; replace the text "k8sstormcenter/storage#23" with the
correct "kubescape/storage#23" (locate the comment block in
pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go where the matcher
note appears) so the PR link points to the correct repository.

---

Nitpick comments:
In `@go.mod`:
- Line 474: The go.mod replace directive pointing at
github.com/k8sstormcenter/storage (replacing github.com/kubescape/storage)
creates supply-chain and merge coordination risk; either remove this replace and
coordinate merging with the upstream storage PR `#323` so the official module
contains CompareExecArgs/ExecsByPath, or gate uses of the new APIs
(ExecsByPath/CompareExecArgs) behind a feature flag until upstream lands, and
add a tracking GitHub issue to remove the go.mod replace as soon as storage PR
`#323` is merged; ensure the replace removal is done atomically with the upgrade
to the official release to avoid drift.

In `@pkg/rulemanager/cel/libraries/applicationprofile/exec.go`:
- Around line 127-130: The branch that returns types.Bool(true) when ExecsByPath
lacks a key for a matched path (the legacy "no argv constraint" back-compat in
the ExecsByPath handling) should emit an observable signal so these silent
matches are visible; update the code paths that currently return
types.Bool(true) (the branches referencing ExecsByPath) to log or increment a
metric including the container/profile hash and ensure the signal is emitted at
most once per container/profile by deduplicating with a short-lived in-memory
cache or an "emit-once" set keyed by containerID+profileHash; apply the same
change to both places where types.Bool(true) is returned so legacy bypasses are
recorded.

In `@pkg/rulemanager/cel/libraries/applicationprofile/open_test.go`:
- Around line 117-122: Restore direct coverage for ap.was_path_opened_with_flags
in TestOpenInProfile by adding at least two cases: one happy-path where the CEL
list of flags parses correctly and the function returns true (e.g., supply a
valid flags list and expected open event), and one invalid-flags case where a
malformed flags CEL list causes the function to reject the input (assert an
error or false per contract). Locate the test table or assertions around
TestOpenInProfile and reintroduce cases that call ap.was_path_opened_with_flags
(not ap.was_path_opened) so you exercise CEL list parsing and malformed-`flags`
rejection behavior; keep the existing ap.was_path_opened cases as well.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 13925bf1-e737-4b6b-a4c1-a13450f2d4a9

📥 Commits

Reviewing files that changed from the base of the PR and between a9bde81 and ce0d6a4.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • go.mod
  • pkg/objectcache/containerprofilecache/projection_apply.go
  • pkg/objectcache/containerprofilecache/projection_apply_test.go
  • pkg/objectcache/projection_types.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open_test.go

Comment thread go.mod Outdated
Comment thread pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go
entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 27, 2026
This PR (R0040 args consumer) references dynamicpathdetector.CompareExecArgs,
which ships in k8sstormcenter/storage's upstream-pr/sbob-execs branch (the
storage sibling of kubescape/storage#322), not in any released
kubescape/storage tag. The PR's existing go.mod pin (v0.0.258) does not
contain it.

Adds a replace directive to the sister branch's current tip (5e39d001 —
feat(apis): add ExecCalls.ArgsRequired + MatchExecArgs to express 'no args').
Removed when the sister storage PR kubescape/storage#322 merges and a
release ships CompareExecArgs.

Companion to the stacking-on-NA-kubescape#812 cherry-pick (provides cp.ExecsByPath)
in the previous commits on this branch.

Resolves the matthyx 'does not build' blocker on PR kubescape#807 (2026-05-27).

Signed-off-by: entlein <einentlein@gmail.com>
@entlein entlein force-pushed the upstream-pr/sbob-path-wildcards branch from ce0d6a4 to d3cd5cc Compare May 27, 2026 18:51
Copy link
Copy Markdown
Contributor

@matthyx matthyx left a comment

Choose a reason for hiding this comment

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

Re-checked this at the current HEAD (9c89feb). The old missing-symbol blocker is fixed, but I still see three blocker-level issues:

  1. tests/component_test.go now contains a second //go:build component, a second package tests, a second import block, and a duplicated Test_32_UnexpectedProcessArguments body. gofmt -e tests/component_test.go fails with parse errors at 1574, 1576, 4978, and 5206, so the component test file does not parse.
  2. The new storage replace in go.mod is not readonly-clean. go test -mod=readonly ./pkg/objectcache/containerprofilecache fails immediately with go: updates to go.mod needed; to update it: go mod tidy, so clean/reproducible CI runs fail before tests even start.
  3. pkg/objectcache/containerprofilecache/projection_apply.go / pkg/rulemanager/cel/libraries/applicationprofile/exec.go: ExecsByPath is keyed only by path, so duplicate ExecCalls collapse to the last argv shape. That breaks merged profiles that legitimately append multiple allowed argv variants for the same executable path (mergeApplicationProfile appends matched.Execs), and ap.was_executed_with_args(...) will reject valid executions unless they match the final entry.

@entlein
Copy link
Copy Markdown
Author

entlein commented May 29, 2026

Fresh harness run on tip `90465661` ("adding strings in import"): 21/21 GREEN ✓ (run 26626548803). Tag `regress-v0.0.278-20260529-081531`.

Includes `Test_27_ApplicationProfileOpens` (the test exercising this PR's path-wildcards surface) AND `Test_02_AllAlertsFromMaliciousApp` (same test that fails on #805's run in parallel). The Test_02 result is interesting comparative signal: both PRs ran against the same storage image and the same monitoring stack, so the per-PR difference in Test_02's outcome reflects how each PR's matchers interact with R0003 traffic from the monitoring stack — this PR tolerates it, #805 doesn't.

Full pass list: Test_01, 02, 06–08, 10–24 (minus 25/26 which aren't in source's matrix), and Test_27.

Caveat (the static-review lesson saved this morning): "21 green" is a real signal from runtime behaviour; it isn't a "merge ready" verdict, just an absence of regressions in this matrix on this tip. The earlier blocker about build-against-`main` symbol resolution is resolved AND the runtime tests now pass; both checks aligned.

Storage at `ghcr.io/k8sstormcenter/storage:regress-v0.0.278-20260529-081531` (= upstream's `v0.0.278` content); NA compiled with STORAGE_REF=45e3bfc9 so compile and deployed image are bit-identical.

Copy link
Copy Markdown
Contributor

@matthyx matthyx left a comment

Choose a reason for hiding this comment

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

Re-checked at the current HEAD (90465661). The earlier missing-strings blocker is fixed, and the focused checks that were failing before now pass.

I'm still requesting changes because this head is not mergeable with main:

  • GitHub currently reports mergeable: CONFLICTING / mergeStateStatus: DIRTY for this PR.
  • A local merge of origin/main into 90465661 reproduces conflicts in go.mod and go.sum.

Please rebase or merge main and regenerate the module files so the PR is mergeable again.

entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 29, 2026
This PR (R0040 args consumer) references dynamicpathdetector.CompareExecArgs,
which ships in k8sstormcenter/storage's upstream-pr/sbob-execs branch (the
storage sibling of kubescape/storage#322), not in any released
kubescape/storage tag. The PR's existing go.mod pin (v0.0.258) does not
contain it.

Adds a replace directive to the sister branch's current tip (5e39d001 —
feat(apis): add ExecCalls.ArgsRequired + MatchExecArgs to express 'no args').
Removed when the sister storage PR kubescape/storage#322 merges and a
release ships CompareExecArgs.

Companion to the stacking-on-NA-kubescape#812 cherry-pick (provides cp.ExecsByPath)
in the previous commits on this branch.

Resolves the matthyx 'does not build' blocker on PR kubescape#807 (2026-05-27).

Signed-off-by: entlein <einentlein@gmail.com>
entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 29, 2026
Previous Test_32 add appended the full umbrella component_test.go on top
of the legitimate one, producing two //go:build directives, two package
clauses, two import blocks and a triplicated Test_32 body. gofmt -e
rejected the file at lines 1574, 1576, 4978, 5206.

Truncates to the last legitimate line and re-appends only the Test_32
function from the umbrella branch. File parses clean, single instance
of each top-level element.

Resolves matthyx blocker (1) on PR kubescape#807 (2026-05-28).

Signed-off-by: entlein <einentlein@gmail.com>
entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 29, 2026
Storage v0.0.278 bump pulled in a transitive dep set that drove
runtime-spec up to v1.3.0, which is incompatible with containerd
v1.7.32's spec_opts.go (cannot use int64 as *int64). Upstream NA main
runs on runtime-spec v1.2.1; pin it the same way here via replace so
'go test -mod=readonly' is clean (matthyx blocker 2 on PR kubescape#807, 2026-05-28).

Also runs full mod tidy now that v0.0.278 has shipped — populates the
transitive go.sum entries that were missing under the previous
sister-branch replace, so CI's -mod=readonly accepts the module graph.

Signed-off-by: entlein <einentlein@gmail.com>
@entlein entlein force-pushed the upstream-pr/sbob-path-wildcards branch from 9046566 to b27f8bc Compare May 29, 2026 09:04
entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 29, 2026
Previous shape (map[string][]string) collapsed duplicate Path entries
to the last seen, breaking merged profiles where
mergeApplicationProfile legitimately appends multiple ExecCalls per
path with distinct argv shapes. ap.was_executed_with_args silently
rejected valid executions that matched any but the final entry
(matthyx blocker 3 on PR kubescape#807, 2026-05-28).

extractExecsByPath now appends each Args slice to a per-path list.
wasExecutedWithArgs iterates the list and returns true when any
vector matches via CompareExecArgs. The 'absent key means no argv
constraint' back-compat semantic is unchanged. Cloned-slice
invariant preserved.

Updates TestApply_ExecsByPath_PopulatesFromSpec to assert the
appended-list shape and the second-entry mutation invariant.

Signed-off-by: entlein <einentlein@gmail.com>
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: 1

🤖 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 `@go.mod`:
- Around line 481-483: Add TODO comments above the two go.mod replace directives
to document that these downgrades are temporary workarounds: reference the exact
directives 'replace github.com/anchore/stereoscope =>
github.com/anchore/stereoscope v0.1.9' and 'replace
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec
v1.2.1', state the reason (build compatibility with current toolchain), record
the criteria for removal (upstream releases restoring compatibility, CI green
when removing), and include a ticket/issue ID or owner and a target review date
to ensure the replacements are revisited.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a08c592-4bce-40c2-ac99-65ca5d5230aa

📥 Commits

Reviewing files that changed from the base of the PR and between 1fdaa89 and b27f8bc.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (13)
  • .github/workflows/component-tests.yaml
  • go.mod
  • pkg/objectcache/containerprofilecache/projection_apply.go
  • pkg/objectcache/containerprofilecache/projection_apply_test.go
  • pkg/objectcache/projection_types.go
  • pkg/objectcache/v1/mock.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec_test.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open_test.go
  • tests/component_test.go
  • tests/resources/curl-user-profile-wildcards-deployment.yaml
  • tests/resources/nginx-user-profile-deployment.yaml
🚧 Files skipped from review as they are similar to previous changes (11)
  • tests/resources/curl-user-profile-wildcards-deployment.yaml
  • tests/resources/nginx-user-profile-deployment.yaml
  • pkg/objectcache/projection_types.go
  • .github/workflows/component-tests.yaml
  • pkg/rulemanager/cel/libraries/applicationprofile/open.go
  • pkg/rulemanager/cel/libraries/applicationprofile/exec.go
  • pkg/objectcache/containerprofilecache/projection_apply_test.go
  • pkg/objectcache/v1/mock.go
  • pkg/objectcache/containerprofilecache/projection_apply.go
  • tests/component_test.go
  • pkg/rulemanager/cel/libraries/applicationprofile/open_test.go

Comment thread go.mod
Comment on lines +481 to +483
replace github.com/anchore/stereoscope => github.com/anchore/stereoscope v0.1.9

replace github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.2.1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add TODO comments documenting the temporary nature and removal criteria of these replace directives.

These replace directives downgrade transitive dependencies (stereoscope from v0.1.22→v0.1.9 and runtime-spec from v1.3.0→v1.2.1) to fix build compatibility issues. Without inline documentation explaining why these downgrades are necessary and when they can be removed, this workaround may persist indefinitely after upstream compatibility is restored.

📝 Proposed fix to add removal tracking
+// TODO: Remove after syft upstream resolves stereoscope compatibility.
+// Temporary pin to v0.1.9 to fix build issues with syft v1.42.3.
 replace github.com/anchore/stereoscope => github.com/anchore/stereoscope v0.1.9
 
+// TODO: Remove after upstream dependencies support runtime-spec v1.3.0.
+// Temporary downgrade to v1.2.1 to fix compatibility with current dependency graph.
 replace github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.2.1
📝 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
replace github.com/anchore/stereoscope => github.com/anchore/stereoscope v0.1.9
replace github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.2.1
// TODO: Remove after syft upstream resolves stereoscope compatibility.
// Temporary pin to v0.1.9 to fix build issues with syft v1.42.3.
replace github.com/anchore/stereoscope => github.com/anchore/stereoscope v0.1.9
// TODO: Remove after upstream dependencies support runtime-spec v1.3.0.
// Temporary downgrade to v1.2.1 to fix compatibility with current dependency graph.
replace github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.2.1
🤖 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` around lines 481 - 483, Add TODO comments above the two go.mod
replace directives to document that these downgrades are temporary workarounds:
reference the exact directives 'replace github.com/anchore/stereoscope =>
github.com/anchore/stereoscope v0.1.9' and 'replace
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec
v1.2.1', state the reason (build compatibility with current toolchain), record
the criteria for removal (upstream releases restoring compatibility, CI green
when removing), and include a ticket/issue ID or owner and a target review date
to ensure the replacements are revisited.

entlein and others added 17 commits May 29, 2026 11:27
…ontainerProfile

Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
This PR (R0040 args consumer) references dynamicpathdetector.CompareExecArgs,
which ships in k8sstormcenter/storage's upstream-pr/sbob-execs branch (the
storage sibling of kubescape/storage#322), not in any released
kubescape/storage tag. The PR's existing go.mod pin (v0.0.258) does not
contain it.

Adds a replace directive to the sister branch's current tip (5e39d001 —
feat(apis): add ExecCalls.ArgsRequired + MatchExecArgs to express 'no args').
Removed when the sister storage PR kubescape/storage#322 merges and a
release ships CompareExecArgs.

Companion to the stacking-on-NA-kubescape#812 cherry-pick (provides cp.ExecsByPath)
in the previous commits on this branch.

Resolves the matthyx 'does not build' blocker on PR kubescape#807 (2026-05-27).

Signed-off-by: entlein <einentlein@gmail.com>
   fixtures

Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
….278

Storage PR kubescape/storage#322 (CompareExecArgs + MatchExecArgs +
ExecCalls.ArgsRequired) merged to kubescape/storage main and a release
was cut (v0.0.278, 2026-05-28). The k8sstormcenter sister-branch
replace is no longer needed — pinning the real tag.

Signed-off-by: entlein <einentlein@gmail.com>
Previous Test_32 add appended the full umbrella component_test.go on top
of the legitimate one, producing two //go:build directives, two package
clauses, two import blocks and a triplicated Test_32 body. gofmt -e
rejected the file at lines 1574, 1576, 4978, 5206.

Truncates to the last legitimate line and re-appends only the Test_32
function from the umbrella branch. File parses clean, single instance
of each top-level element.

Resolves matthyx blocker (1) on PR kubescape#807 (2026-05-28).

Signed-off-by: entlein <einentlein@gmail.com>
Storage v0.0.278 bump pulled in a transitive dep set that drove
runtime-spec up to v1.3.0, which is incompatible with containerd
v1.7.32's spec_opts.go (cannot use int64 as *int64). Upstream NA main
runs on runtime-spec v1.2.1; pin it the same way here via replace so
'go test -mod=readonly' is clean (matthyx blocker 2 on PR kubescape#807, 2026-05-28).

Also runs full mod tidy now that v0.0.278 has shipped — populates the
transitive go.sum entries that were missing under the previous
sister-branch replace, so CI's -mod=readonly accepts the module graph.

Signed-off-by: entlein <einentlein@gmail.com>
Previous shape (map[string][]string) collapsed duplicate Path entries
to the last seen, breaking merged profiles where
mergeApplicationProfile legitimately appends multiple ExecCalls per
path with distinct argv shapes. ap.was_executed_with_args silently
rejected valid executions that matched any but the final entry
(matthyx blocker 3 on PR kubescape#807, 2026-05-28).

extractExecsByPath now appends each Args slice to a per-path list.
wasExecutedWithArgs iterates the list and returns true when any
vector matches via CompareExecArgs. The 'absent key means no argv
constraint' back-compat semantic is unchanged. Cloned-slice
invariant preserved.

Updates TestApply_ExecsByPath_PopulatesFromSpec to assert the
appended-list shape and the second-entry mutation invariant.

Signed-off-by: entlein <einentlein@gmail.com>
Mirrors containerprofilecache.Apply's extractExecsByPath shape so
exec-args unit tests exercise the real wildcard matcher instead of
hitting the absent-key 'no argv constraint' back-compat fallback.
Same per-Path append + nil→empty-slice rules.

Fixes the four TestExecWithArgsWildcardInProfile cases that were
silently returning true (back-compat) and getting marked as failing
expected:false (sh -x wrong flag, ls -l no directory, echo goodbye
world wrong literal anchor, curl --pass alice wrong literal).

Signed-off-by: entlein <einentlein@gmail.com>
…o go mod sync with main

Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
Signed-off-by: entlein <einentlein@gmail.com>
@entlein entlein force-pushed the upstream-pr/sbob-path-wildcards branch from b27f8bc to e5069fd Compare May 29, 2026 09:28
@entlein
Copy link
Copy Markdown
Author

entlein commented May 29, 2026

@claude test this again please using the same upstream-mirror image, please

entlein pushed a commit to k8sstormcenter/node-agent that referenced this pull request May 29, 2026
regress-upstream-pr-mirror: upstream-pr=kubescape#807 source=upstream-pr/sbob-path-wildcards
@entlein
Copy link
Copy Markdown
Author

entlein commented May 29, 2026

Re-running on current HEAD `e5069fd6` (the rebase tip — 10 new commits since this morning's run on `90465661`), reusing the same storage image `ghcr.io/k8sstormcenter/storage:regress-v0.0.278-20260529-081531` per your ask. NA build: https://github.com/k8sstormcenter/node-agent/actions/runs/26629665648.

CT will auto-chain after build completes (same shared tag on both images, so the deploy sees a coherent pair). Will report the matrix outcome.

@entlein
Copy link
Copy Markdown
Author

entlein commented May 29, 2026

Retry result on rebased tip `e5069fd6` (reused storage `regress-v0.0.278-20260529-081531`): 21/21 GREEN ✓ (run 26629884873).

Same result as this morning's pre-rebase run — the rebase didn't introduce regressions. Full pass list unchanged (Test_01, 02, 06–08, 10–24, 27).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: WIP

Development

Successfully merging this pull request may close these issues.

2 participants