[BUG] Kubescape tool reports ApplicationProfile execs/opens/containers as 0 due to metadata-only LIST (spec is not fetched)
I maintainer di solito rispondono entro 4 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 72/100
Direzione di ricerca
Inizia in pkg/kubescape/kubescape.go, nella parte relativa al List handler di ApplicationProfile, e verifica come la risposta List valorizza i contatori derivati da spec. Confronta gli oggetti elencati con i singoli risultati GET, quindi assicurati che l’handler restituisca valori reali oppure indichi chiaramente i dati non disponibili invece di restituire 0. Verifica il comportamento del listing di ApplicationProfile, incluso il path correlato vulnerabilityManifests se segue lo stesso pattern.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
🎯 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/
- Lingua principale
- Go
- Stelle
- 35
- Fork
- 28
- Merge medio
- 3g 23h
- PR unite (30g)
- 3
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di kagent-dev/tools
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
kagent-dev/tools#54 ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
kagent-dev/tools#82 ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 78/100
kagent-dev/tools#80 ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
kagent-dev/tools#68 · 1 commento ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
kagent-dev/tools#60 · 1 reazione ·
I maintainer di solito rispondono entro 4 giorni
Tutte le issue di kagent-dev/tools
Issue simili
-
self-host checker: E021 bound check reads an untyped literal at i32, not the type the call bindsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
JakeChampion/lang#11055 ·
I maintainer di solito rispondono entro 1 giorno
-
priority: low status: ready for dev
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
hyperledger-labs/fabric-smart-client#2033 ·
I maintainer di solito rispondono entro 1 giorno
-
agent-butler-finding agent-research bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 90/100
jordansmall/spindrift#4249 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
I maintainer di solito rispondono entro 1 giorno
-
acceptance-tests phase-coding schema-coverage testing triaged
Difficoltà 2/5 1-2 giorni Idoneità per principianti 84/100
elastic/terraform-provider-elasticstack#5053 ·
I maintainer di solito rispondono entro 1 giorno