[BUG] Kubescape tool reports ApplicationProfile execs/opens/containers as 0 due to metadata-only LIST (spec is not fetched)
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 72/100
Research direction
Start in pkg/kubescape/kubescape.go around the ApplicationProfile list handler and inspect how the List response populates spec-derived counters. Compare the listed objects with individual GET results, then ensure the handler returns real values or clearly marks unavailable data instead of zero. Verify the ApplicationProfile listing behavior, including the related vulnerabilityManifests path if it shares the same pattern.
Written by the indexing model from the issue text.
Description
🎯 Affected Component(s)
pkg/kubescape (kagent-tools MCP server) — the list-style handlers for ApplicationProfile (and likely other spdx.softwarecomposition.kubescape.io resources whose list handlers read spec-derived fields, e.g. vulnerabilityManifests).
🐛 Bug Description
Note: I think the Kubescape tool is still in an early/beta stage and not yet listed among the GA tools. I'm filing this in case the feedback is useful for hardening it before GA — please feel free to deprioritize if this tool is out of active scope.
Kubescape's Storage aggregated API server implements metadata-only LIST: a LIST request (e.g., kubectl get <custom resource> -A -o json) returns object metadata only and omits the heavy spec payload. The full spec is only returned by an individual GET on a named object (or via the documented fullSpec resourceVersion mechanism).
The Kubescape tool's list handlers appear to aggregate values from spec (e.g., spec.containers[].execs, spec.containers[].opens) using data obtained through a LIST call. Because LIST returns no spec, the aggregation counts nothing and returns 0 for all fields — even containers_count — while the objects actually contain data.
This is a documented behavior of Kubescape Storage. Per the kubescape/storage README:
a listed object comes back with its spec fields at their zero values (for example a VulnerabilityManifestSummary reports all severity counts as 0)
(the same applies to ApplicationProfile, whose spec.containers[] is likewise omitted on LIST)
🔄 Steps To Reproduce
- Install the Kubescape operator with relevancy enabled (default with node-agent/eBPF), and let the learning period complete for at least one workload.
- Invoke
kubescape_list_application_profilesthrough a kagent agent (or the MCP server directly). - Observe that all profiles report
total_execs: 0,total_opens: 0,total_syscalls: 0,containers_count: 0.
🤔 Expected Behavior
The tool should return the real spec-derived values (e.g., execs, opens, container counts) for each ApplicationProfile, or at minimum must not report 0 when the data is simply not present in a metadata-only LIST response.
Acceptable approaches:
- Fetch each object with an individual GET (which returns the full
spec) before aggregating, or - If only metadata is available, clearly distinguish "not fetched / unknown" from "0", instead of emitting
0.
Note: The storage's fullSpec resourceVersion mechanism is not applicable here — per the kubescape/storage README, fullSpec is rejected on LIST for applicationprofiles and networkneighborhoods (it is honored only for the summary resources). Individual GET is therefore the appropriate approach for these resources.
📱 Actual Behavior
All ApplicationProfiles are reported with zeroed counters (trimmed):
{
"application_profiles": [
{
"containers_count": 0,
"created_at": "2026-06-04T08:41:49Z",
"name": "replicaset-rockylinux-58468585c7",
"namespace": "kagent",
"total_capabilities": 0,
"total_endpoints": 0,
"total_execs": 0,
"total_opens": 0,
"total_syscalls": 0
},
{ "... same zeros for every profile ..." }
]
}
However, an individual GET on the same objects returns real data, and the learning is marked complete:
$ kubectl get applicationprofile replicaset-rockylinux-58468585c7 -n kagent -o json \
| jq '.spec.containers[]? | {name, execs:(.execs|length), opens:(.opens|length)}'
{
"name": "rockylinux",
"execs": 13,
"opens": 115
}
$ kubectl get applicationprofile replicaset-rockylinux-58468585c7 -n kagent -o json \
| jq '.metadata.annotations'
{
"kubescape.io/completion": "complete",
"kubescape.io/status": "completed",
...
}
So the data exists (execs: 13, opens: 115) and the profile is completed; the tool's 0 values come from LIST not returning spec, not from an actually-empty profile.
💻 Environment
- OS version: Rocky Linux 8.10 (x86_64) bastion; nodes on Amazon Linux
- Kubernetes: v1.35.6 (EKS)
- Kubernetes Provider: AWS (EKS)
- kagent-tools / MCP server version: v0.2.1
- Kubescape operator: v4.0.5 (Helm chart 1.40.2)
🔍 Additional Context
Root cause:
In pkg/kubescape/kubescape.go (v0.2.1, around L741), the list handler fetches profiles with a LIST call and then reads spec-derived fields directly from each listed item:
profiles, err := k.spdxClient.ApplicationProfiles(queryNamespace).List(ctx, metav1.ListOptions{})
// ...
for _, profile := range profiles.Items {
containersCount := len(profile.Spec.Containers)
// ...
for _, c := range profile.Spec.Containers {
totalExecs += len(c.Execs)
totalOpens += len(c.Opens)
totalSyscalls += len(c.Syscalls)
totalCapabilities += len(c.Capabilities)
totalEndpoints += len(c.Endpoints)
}
// ... written into profileMap as containers_count / total_execs / ...
}
The List call uses an empty metav1.ListOptions{}. Since Kubescape Storage serves metadata-only LIST (the payload/spec is not loaded from disk), profile.Spec comes back zero-valued: profile.Spec.Containers is empty, so containers_count and every total_* counter sum to 0. The values are read from a response that, by design, never contains spec.
Suggested fix: GET each object individually to obtain spec before aggregating, or report the counters as "unknown/not fetched" rather than 0 when spec is unavailable.
(The fullSpec LIST mechanism cannot be used here: the storage server rejects it for applicationprofiles and networkneighborhoods.)
References:
- Kubescape Storage README (documents metadata-only LIST and fullSpec): https://github.com/kubescape/storage
- Relevancy (execs/opens learning via eBPF node-agent): https://kubescape.io/docs/operator/relevancy/
- Dominant language
- Go
- Stars
- 35
- Forks
- 30
- Avg merge
- 3d 23h
- Merged PRs (30d)
- 3
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from kagent-dev/tools
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
kagent-dev/tools#54 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
kagent-dev/tools#82 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
kagent-dev/tools#80 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
kagent-dev/tools#68 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
kagent-dev/tools#60 · 1 reaction ·
All issues in kagent-dev/tools
Similar issues
-
agentic-workflows
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
agentic-workflows
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
microsoft/agent-framework-go#1179 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
[Bug]: OLLAMA_KEEP_ALIVE="5m" / "24h" crashes Ollama embedding and vision models with ValueError Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
infiniflow/ragflow#20223 · 1 reaction ·
-
bug needs triage pkg/translator/faro
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
open-telemetry/opentelemetry-collector-contrib#51484 · 1 comment ·