Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
20d5470
feat(migrate): converter + differential oracle for user-defined AP/NN…
Jul 23, 2026
3f9299b
feat(migrate): node-agent reads a user-defined ContainerProfile as th…
Jul 24, 2026
1be5ede
test(migrate): port Test_28 to a single user-defined ContainerProfile
Jul 24, 2026
d9108c1
test(migrate): benchmark user-defined CP projection vs legacy AP+NN o…
Jul 24, 2026
a251069
test(migrate): port Test_27/32/33 to user-defined ContainerProfiles
Jul 24, 2026
903443d
fix(projection): classify '*' path entries as Patterns, not Values
Jul 2, 2026
8c82261
test(migrate): Test_33 must enable R0002 file-access monitoring
Jul 24, 2026
f2f730f
feat(migrate): user-managed ContainerProfiles carry no lifecycle anno…
Jul 24, 2026
d1bab20
test(migrate): clean user-defined CPs + restore an authoring yaml exa…
Jul 24, 2026
856dc36
docs(migrate): ContainerProfile authoring examples for network endpoints
Jul 24, 2026
aacf398
test(migrate): migrate legacy AP/NN CT fixtures to ContainerProfile
Jul 24, 2026
8231702
remove migration tooling
entlein Jul 25, 2026
83bc9fb
remove useless readme
entlein Jul 25, 2026
fd5ed04
couldnt find any active consumers of user-defined AP/NN, so opting to…
entlein Jul 27, 2026
b5bdc01
next step of many, also opened PRs in charts, backend, synchronizer, …
entlein Jul 28, 2026
c1242c4
next step :now removing the previous crds completely, trying out mutl…
entlein Jul 28, 2026
0bf5924
merge main
entlein Jul 28, 2026
f08681a
Apply suggestions from code review
entlein Jul 28, 2026
a5b538e
more decommissioning
entlein Jul 28, 2026
5e1d37d
test: add projection Apply golden-corpus oracle
Jul 29, 2026
06180a6
test: author projection corpus with ContainerProfile-native fields
Jul 29, 2026
976f850
refactor: rename AP/NN CEL libraries to ContainerProfile (cp.* namesp…
Jul 29, 2026
e0922f4
test: consolidate network-wildcard fixtures into network-wildcards
Jul 29, 2026
243bb34
IMPORANT: add Test_08_ApplicationProfilePatching to component-tes…
entlein Jul 29, 2026
be4643b
Update component-tests.yaml
entlein Jul 29, 2026
d907c49
Merge up/main into migrate/sbob
Jul 30, 2026
371cbeb
test: close ContainerProfile CEL + rule-engine coverage gaps
Jul 30, 2026
6eb22ef
test(component): make Test_20/21 deterministic (authored profile, not…
Jul 30, 2026
e21c2f3
test(component): gate Test_16 on real profile completion, not a fixed…
Jul 30, 2026
5bc3259
last fixes, only concerning test utils that coderabbit complained about
entlein Jul 31, 2026
f91d4a5
merge in main
entlein Jul 31, 2026
eab532e
merge in main fix dupes
entlein Jul 31, 2026
0212cdc
this test doesnt really catch the scrambled paths, its more to remind…
entlein Aug 4, 2026
6365bdb
Merge remote-tracking branch 'origin/migrate/sbob' into mirrormain
ConstanzeTU Aug 6, 2026
2002fc5
testing a fix (#60)
entlein Aug 6, 2026
a7345fe
Feat/celnetwork (#62)
entlein Aug 6, 2026
8e44c66
ci: add dispatchable build workflow for the storage-triggered rebuild…
ConstanzeTU Aug 7, 2026
076bd14
Signed-off-by: entlein <einentlein@gmail.com>
ConstanzeTU Aug 14, 2026
770b820
all of Matthias Aug14 review , plus a new bug (#82)
entlein Aug 15, 2026
6351b2e
Review follow-ups: container subtype recovery, adoption visibility, d…
ConstanzeTU Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: build-image

on:
workflow_dispatch:
inputs:
SOURCE_REF:
required: false
type: string
default: ""
description: "Branch/tag/SHA of node-agent to build (defaults to the dispatched ref). Use this to build upstream-pr/** or any clean branch without giving it fork-specific workflow files."
IMAGE_TAG:
required: true
type: string
description: "Image tag for the node-agent image"
STORAGE_REF:
required: false
type: string
default: ""
description: "Branch/tag/commit of k8sstormcenter/storage to use (leave empty to keep go.mod default)"
PLATFORMS:
type: boolean
required: false
default: false
description: "Build for both amd64 and arm64"

# Default to read-only at the workflow level (least privilege per Scorecard).
# Jobs that need elevated scopes override below.
permissions: read-all

jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
packages: write
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# On dispatch, SOURCE_REF may point at a clean upstream-pr/** branch
# (or an upstream SHA) that carries no fork workflow files; the
# workflow itself is resolved from the dispatched --ref (fork-ci),
# then the tree is switched to SOURCE_REF here. Empty on push.
ref: ${{ inputs.SOURCE_REF || github.ref }}
submodules: recursive

- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: "1.25"

- name: Update storage dependency
if: ${{ inputs.STORAGE_REF != '' }}
env:
STORAGE_REF: ${{ inputs.STORAGE_REF }}
GONOSUMCHECK: "*"
GOFLAGS: ""
run: |
echo "Replacing github.com/kubescape/storage with github.com/k8sstormcenter/storage@${STORAGE_REF}"
go mod edit -replace "github.com/kubescape/storage=github.com/k8sstormcenter/storage@${STORAGE_REF}"
go mod tidy
echo "Resolved storage version:"
grep "k8sstormcenter/storage" go.sum | head -1

- name: Ensure ig is installed
run: |
curl -L https://github.com/inspektor-gadget/inspektor-gadget/releases/download/v0.45.0/ig_0.45.0_amd64.deb -O
sudo dpkg -i ig_0.45.0_amd64.deb

- name: Build gadgets
run: make gadgets

- name: Set up QEMU
if: ${{ inputs.PLATFORMS }}
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: build/Dockerfile
tags: ghcr.io/${{ github.repository_owner }}/node-agent:${{ inputs.IMAGE_TAG }}
build-args: image_version=${{ inputs.IMAGE_TAG }}
platforms: ${{ inputs.PLATFORMS && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
push: true


trigger-component-tests:
needs: build
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- name: Trigger component tests
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
STORAGE_TAG="${{ inputs.IMAGE_TAG }}"
NODE_AGENT_TAG="${{ inputs.IMAGE_TAG }}"
STORAGE_REF="${{ inputs.STORAGE_REF }}"
echo "Triggering component tests with STORAGE_TAG=${STORAGE_TAG} NODE_AGENT_TAG=${NODE_AGENT_TAG} STORAGE_REF=${STORAGE_REF}"
gh workflow run component-tests.yaml \
--repo "${{ github.repository }}" \
--ref "${{ github.ref_name }}" \
-f STORAGE_TAG="${STORAGE_TAG}" \
-f NODE_AGENT_TAG="${NODE_AGENT_TAG}" \
-f STORAGE_REF="${STORAGE_REF}"
6 changes: 4 additions & 2 deletions .github/workflows/component-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
# Test_05_MemoryLeak_10K_Alerts,
Test_06_KillProcessInTheMiddle,
Test_07_RuleBindingApplyTest,
Test_08_ApplicationProfilePatching,
Test_08_ContainerProfilePatching,
Test_10_MalwareDetectionTest,
Test_11_EndpointTest,
Test_12_MergingProfilesTest,
Expand All @@ -74,7 +74,9 @@ jobs:
Test_24_ProcessTreeDepthTest,
Test_27_ApplicationProfileOpens,
Test_32_UnexpectedProcessArguments,
Test_34_NetworkNeighborsCIDRCollapse
Test_34_NetworkNeighborsCIDRCollapse,
Test_36_MultiContainerPerContainerBinding,
Test_48_MultiSubtypeGroupedProfileDocument
]
steps:
- name: Checkout code
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ DOCKERFILE_PATH=./build/Dockerfile
BINARY_NAME=node-agent

IMAGE?=quay.io/kubescape/$(BINARY_NAME)
GADGETS=advise_seccomp trace_capabilities trace_dns trace_exec trace_open
# GADGETS are pulled unmodified from upstream IG. trace_open is intentionally NOT
# here: it is vendored and built from source (see BUILT_GADGETS) so the fpath
# resolver can resolve relative opens against their dirfd/cwd.
GADGETS=advise_seccomp trace_capabilities trace_dns trace_exec
VERSION=v0.48.1
KUBESCAPE_GADGETS=bpf exit fork hardlink http iouring_new iouring_old kmod network ptrace randomx ssh symlink unshare
# BUILT_GADGETS are vendored under pkg/ebpf/gadgets and built under their full
# upstream image name+tag so node-agent's pinned openImageName keeps resolving.
BUILT_GADGETS=trace_open
TAG?=test
# TAG?=v0.0.1

Expand All @@ -26,5 +32,6 @@ docker-push: docker-build

gadgets:
$(foreach img,$(KUBESCAPE_GADGETS),$(MAKE) -C ./pkg/ebpf/gadgets/$(img) build IMAGE=$(img) TAG=latest;)
$(foreach img,$(BUILT_GADGETS),$(MAKE) -C ./pkg/ebpf/gadgets/$(img) build IMAGE=ghcr.io/inspektor-gadget/gadget/$(img) TAG=$(VERSION);)
$(foreach img,$(GADGETS),sudo ig image pull ghcr.io/inspektor-gadget/gadget/$(img):$(VERSION);)
sudo ig image export $(foreach img,$(GADGETS),ghcr.io/inspektor-gadget/gadget/$(img):$(VERSION)) $(foreach img,$(KUBESCAPE_GADGETS),$(img):latest) tracers.tar
sudo ig image export $(foreach img,$(GADGETS) $(BUILT_GADGETS),ghcr.io/inspektor-gadget/gadget/$(img):$(VERSION)) $(foreach img,$(KUBESCAPE_GADGETS),$(img):latest) tracers.tar
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,5 @@ replace github.com/anchore/syft => github.com/kubescape/syft v1.32.0-ks.2
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

replace github.com/kubescape/storage => github.com/k8sstormcenter/storage v0.0.0-20260814205251-829145296d11
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k8sstormcenter/storage v0.0.0-20260814205251-829145296d11 h1:8Qv7BSrWmcBwtd9uVzutZELQnhVl5bZpAjs7m4TP9G4=
github.com/k8sstormcenter/storage v0.0.0-20260814205251-829145296d11/go.mod h1:d/1hqWPda2clsjx2wmQgysnB5dThIo3rDKP7RWx+v+M=
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 h1:WdAeg/imY2JFPc/9CST4bZ80nNJbiBFCAdSZCSgrS5Y=
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953/go.mod h1:6o+UrvuZWc4UTyBhQf0LGjW9Ld7qJxLz/OqvSOWWlEc=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
Expand Down Expand Up @@ -885,8 +887,6 @@ github.com/kubescape/go-logger v0.0.32 h1:4mI+XJOV8VFCMewrEE9VIFEIOhzXokYT3nFpNf
github.com/kubescape/go-logger v0.0.32/go.mod h1:Alj7JBQ8/WCxbXe8Ura6ZheSRK45E0p21M3xeqedX90=
github.com/kubescape/k8s-interface v0.0.214 h1:j7KP0/5VvYOoQdBGV2+gRM3qnR8PWLAGF8RM/k/DmJ0=
github.com/kubescape/k8s-interface v0.0.214/go.mod h1:WNYUG93aZ5kDmuaRKFLtVhp18Yc6EfaHdD1gLYtVTN4=
github.com/kubescape/storage v0.0.290 h1:oIXxz31vrbQiUjBE9I6t/sBmhrwlNTAN4Vs70FxFMA4=
github.com/kubescape/storage v0.0.290/go.mod h1:ARiTDaeDWLqEcOIbH+zz4dwdMEVxubfu5X5ehdDOqPc=
github.com/kubescape/syft v1.32.0-ks.2 h1:xdUksUmKEyyVKsTfJDYW8Z5HawVJtelsUolPOsWtDx0=
github.com/kubescape/syft v1.32.0-ks.2/go.mod h1:E6Kd4iBM2ljUOUQvSt7hVK6vBwaHkMXwcvBZmGMSY5o=
github.com/kubescape/workerpool v0.0.0-20250526074519-0e4a4e7f44cf h1:hI0jVwrB6fT4GJWvuUjzObfci1CUknrZdRHfnRVtKM0=
Expand Down
45 changes: 6 additions & 39 deletions mocks/readfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"path"
"runtime"

"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
corev1 "k8s.io/api/core/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"

Expand All @@ -20,8 +19,6 @@ const (
TestKindPod TestKinds = "Pod"
TestKindRS TestKinds = "ReplicaSet"
TestKindDeploy TestKinds = "Deployment"
TestKindAP TestKinds = "ApplicationProfile"
TestKindNN TestKinds = "NetworkNeighborhood"
)

const (
Expand All @@ -30,20 +27,14 @@ const (
)

const (
nginxPodBytes = "testdata/nginx_pod.json"
nginxRSBytes = "testdata/nginx_rs.json"
nginxDeploymentBytes = "testdata/nginx_deploy.json"
nginxApplicationProfileBytes = "testdata/nginx_applicationprofiles.json"
nginxApplicationActivityBytes = "testdata/nginx_applicationactivities.json"
nginxNetworkNeighborhoodBytes = "testdata/nginx_networkneighborhood.json"
nginxPodBytes = "testdata/nginx_pod.json"
nginxRSBytes = "testdata/nginx_rs.json"
nginxDeploymentBytes = "testdata/nginx_deploy.json"
)
const (
collectionPodBytes = "testdata/collection_pod.json"
collectionRSBytes = "testdata/collection_rs.json"
collectionDeploymentBytes = "testdata/collection_deploy.json"
collectionApplicationProfileBytes = "testdata/collection_applicationprofiles.json"
collectionApplicationActivityBytes = "testdata/collection_applicationactivities.json"
collectionNetworkNeighborhoodBytes = "testdata/collection_networkneighborhood.json"
collectionPodBytes = "testdata/collection_pod.json"
collectionRSBytes = "testdata/collection_rs.json"
collectionDeploymentBytes = "testdata/collection_deploy.json"
)

var NAMESPACE = ""
Expand Down Expand Up @@ -86,16 +77,6 @@ func UnstructuredToRuntime(u *unstructured.Unstructured) k8sruntime.Object {
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(u.Object, deploy); err == nil {
return deploy
}
case TestKindAP:
ap := &v1beta1.ApplicationProfile{}
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(u.Object, ap); err == nil {
return ap
}
case TestKindNN:
nn := &v1beta1.NetworkNeighborhood{}
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(u.Object, nn); err == nil {
return nn
}
}
return nil
}
Expand Down Expand Up @@ -143,20 +124,6 @@ func GetBytes(kind TestKinds, name TestName) []byte {
case TestCollection:
return readFile(collectionDeploymentBytes)
}
case TestKindAP:
switch name {
case TestNginx:
return readFile(nginxApplicationProfileBytes)
case TestCollection:
return readFile(collectionApplicationProfileBytes)
}
case TestKindNN:
switch name {
case TestNginx:
return readFile(nginxNetworkNeighborhoodBytes)
case TestCollection:
return readFile(collectionNetworkNeighborhoodBytes)
}
}
return []byte{}
}
16 changes: 0 additions & 16 deletions mocks/readfiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ func TestUnstructuredToPod(t *testing.T) {
name: TestNginx,
kind: TestKindDeploy,
},
{
name: TestNginx,
kind: TestKindAP,
},
{
name: TestNginx,
kind: TestKindNN,
},
{
name: TestCollection,
kind: TestKindPod,
Expand All @@ -45,14 +37,6 @@ func TestUnstructuredToPod(t *testing.T) {
name: TestCollection,
kind: TestKindDeploy,
},
{
name: TestCollection,
kind: TestKindAP,
},
{
name: TestCollection,
kind: TestKindNN,
},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%s/%s", tt.name, tt.kind), func(t *testing.T) {
Expand Down
Loading
Loading