π― Affected Component(s)
pkg/kubescape (kagent-tools MCP server) β kubescape_check_health
π 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.
The Kubescape tool's health check verifies the existence of Kubescape custom resources by checking for CRDs via the apiextensions client (apiExtClient).
However, the resources checked hereβApplicationProfile,
VulnerabilityManifest, and NetworkNeighborhood in the
spdx.softwarecomposition.kubescape.io/v1beta1 APIβare served by
Kubescape Storage through the Kubernetes API aggregation layer rather
than being defined by CustomResourceDefinition objects.
Because these resources do not appear in the apiextensions (CRD) API, the CRD-existence check fails and reports them as "not installed", even though the resources exist and are fully queryable through the aggregated API.
This is a self-contradicting result: within the same check_health output, the tool reports VulnerabilityManifests CRD not installed (error) while simultaneously reporting 80 vulnerability manifests found (ok) β the latter succeeds precisely because that path uses the aggregated-API client (spdxClient), not the CRD client.
Note: Kubescape Storage has long utilized the Aggregated API, and with the release of 4.0, it has reached GA.
The Aggregated API is the officially recommended architecture for these security metadata resources.
Therefore, the health check function must support this architecture rather than assuming that the resources are backed by CRDs.
π Steps To Reproduce
-
Install the Kubescape operator via Helm (v4.0.x line).
The following capabilities are relevant and enabled by default in this chart line: storage/aggregated API, vulnerabilityScan, relevancy, runtimeObservability.
# Shorten the learning period so profiles finalize quickly (default is 24h).
helm repo add kubescape https://kubescape.github.io/helm-charts/ ; helm repo update ; \
helm upgrade --install kubescape kubescape/kubescape-operator -n kubescape --create-namespace \
--set clusterName=`kubectl config current-context` \
--set nodeAgent.config.maxLearningPeriod=10m
-
Wait for scans to populate (vulnerability manifests, application profiles).
-
Invoke the kubescape_check_health tool through a kagent agent (or the MCP server directly).
π€ Expected Behavior
The health check should recognize the spdx.softwarecomposition.kubescape.io/v1beta1
resources as installed whenever they are served by the aggregated API server,
regardless of whether a CustomResourceDefinition object exists. The presence
check should therefore be based on API availability, not CRD existence.
Concretely, either of the following is appropriate:
- Perform a lightweight discovery/list against the aggregated group-version
(the data-fetching path already does this successfully via spdxClient)
- Check the
APIService v1beta1.spdx.softwarecomposition.kubescape.io and its
Available=True condition.
For reference, the official Kubescape MCP server accesses these resources through an
spdxv1beta1 client created by CreateKsObjectConnection β i.e. via the aggregated-API
client, without any CRD lookup.
π± Actual Behavior
kubescape_check_health uses apiExtClient to check for
CustomResourceDefinition objects corresponding to ApplicationProfiles,
VulnerabilityManifests, and NetworkNeighborhoods, and reports them as not installed. Representative output (trimmed):
{
"healthy": false,
"checks": {
"application_profiles_crd": {
"status": "warning",
"message": "ApplicationProfiles CRD not installed - runtime observability may not be enabled"
},
"network_neighborhoods_crd": {
"status": "warning",
"message": "NetworkNeighborhoods CRD not installed - runtime observability may not be enabled"
},
"vulnerability_crd": {
"status": "error",
"message": "VulnerabilityManifests CRD not installed - vulnerability scanning may not be enabled"
},
"vulnerability_scan_data": {
"status": "ok",
"message": "80 vulnerability manifests found"
},
"operator_pods": {
"status": "ok",
"message": "9/9 pods running"
}
},
"summary": "Kubescape has issues that need attention",
"recommendations": [
"Enable vulnerability scanning in Kubescape Helm chart: ... --set capabilities.vulnerabilityScan=enable",
"Enable runtime observability for workload behavior analysis: ... --set capabilities.runtimeObservability=enable"
]
}
Note the contradiction: vulnerability_crd = error ("not installed") vs. vulnerability_scan_data = ok ("80 vulnerability manifests found").
Manual confirmation that the resources are served via aggregated API (not CRD):
# Served by the aggregated API server (Available=True):
$ kubectl get apiservices | grep spdx.softwarecomposition.kubescape.io
v1beta1.spdx.softwarecomposition.kubescape.io kubescape/storage True
# NOT present as a CRD:
$ kubectl get crds | grep -E "applicationprofiles|vulnerabilitymanifests|networkneighborhoods"
# (no output)
# Yet fully queryable:
$ kubectl get applicationprofiles -A
(rows are returned)
$ kubectl get vulnerabilitymanifests -A
(rows are returned)
Note also that the two recommendations ("enable vulnerabilityScan", "enable runtimeObservability") point to capabilities that are enabled by default in the operator Helm chart. This is a direct consequence of the CRD-based availability check producing false negatives.
π» 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)
- Namespace: kubescape
π Additional Context
Root cause (from source): In pkg/kubescape/kubescape.go, KubescapeTool holds a dedicated apiExtClient "for verifying CRD existence", and handleCheckHealth uses it to check these resources. Since they are aggregated-API resources (not CRDs), this client is the wrong mechanism β hence the false negative described above.
Suggested fix: Replace the CRD-existence check with an API-availability check,
as described in Expected Behavior β a lightweight request through the existing
spdxClient (preferred), optionally corroborated by the APIService
Available=True condition. CRD existence should not be used as the availability
criterion for these resources.
References:
π― Affected Component(s)
pkg/kubescape(kagent-tools MCP server) βkubescape_check_healthπ Bug Description
The Kubescape tool's health check verifies the existence of Kubescape custom resources by checking for CRDs via the apiextensions client (
apiExtClient).However, the resources checked hereβ
ApplicationProfile,VulnerabilityManifest, andNetworkNeighborhoodin thespdx.softwarecomposition.kubescape.io/v1beta1APIβare served byKubescape Storage through the Kubernetes API aggregation layer rather
than being defined by
CustomResourceDefinitionobjects.Because these resources do not appear in the apiextensions (CRD) API, the CRD-existence check fails and reports them as "not installed", even though the resources exist and are fully queryable through the aggregated API.
This is a self-contradicting result: within the same
check_healthoutput, the tool reportsVulnerabilityManifests CRD not installed(error) while simultaneously reporting80 vulnerability manifests found(ok) β the latter succeeds precisely because that path uses the aggregated-API client (spdxClient), not the CRD client.Note: Kubescape Storage has long utilized the Aggregated API, and with the release of 4.0, it has reached GA.
The Aggregated API is the officially recommended architecture for these security metadata resources.
Therefore, the health check function must support this architecture rather than assuming that the resources are backed by CRDs.
π Steps To Reproduce
Install the Kubescape operator via Helm (v4.0.x line).
The following capabilities are relevant and enabled by default in this chart line: storage/aggregated API, vulnerabilityScan, relevancy, runtimeObservability.
Wait for scans to populate (vulnerability manifests, application profiles).
Invoke the
kubescape_check_healthtool through a kagent agent (or the MCP server directly).π€ Expected Behavior
The health check should recognize the
spdx.softwarecomposition.kubescape.io/v1beta1resources as installed whenever they are served by the aggregated API server,
regardless of whether a
CustomResourceDefinitionobject exists. The presencecheck should therefore be based on API availability, not CRD existence.
Concretely, either of the following is appropriate:
(the data-fetching path already does this successfully via
spdxClient)APIServicev1beta1.spdx.softwarecomposition.kubescape.ioand itsAvailable=Truecondition.For reference, the official Kubescape MCP server accesses these resources through an
spdxv1beta1client created byCreateKsObjectConnectionβ i.e. via the aggregated-APIclient, without any CRD lookup.
π± Actual Behavior
kubescape_check_healthusesapiExtClientto check forCustomResourceDefinitionobjects corresponding to ApplicationProfiles,VulnerabilityManifests, and NetworkNeighborhoods, and reports them as not installed. Representative output (trimmed):
{ "healthy": false, "checks": { "application_profiles_crd": { "status": "warning", "message": "ApplicationProfiles CRD not installed - runtime observability may not be enabled" }, "network_neighborhoods_crd": { "status": "warning", "message": "NetworkNeighborhoods CRD not installed - runtime observability may not be enabled" }, "vulnerability_crd": { "status": "error", "message": "VulnerabilityManifests CRD not installed - vulnerability scanning may not be enabled" }, "vulnerability_scan_data": { "status": "ok", "message": "80 vulnerability manifests found" }, "operator_pods": { "status": "ok", "message": "9/9 pods running" } }, "summary": "Kubescape has issues that need attention", "recommendations": [ "Enable vulnerability scanning in Kubescape Helm chart: ... --set capabilities.vulnerabilityScan=enable", "Enable runtime observability for workload behavior analysis: ... --set capabilities.runtimeObservability=enable" ] }Note the contradiction:
vulnerability_crd = error ("not installed")vs.vulnerability_scan_data = ok ("80 vulnerability manifests found").Manual confirmation that the resources are served via aggregated API (not CRD):
Note also that the two recommendations ("enable vulnerabilityScan", "enable runtimeObservability") point to capabilities that are enabled by default in the operator Helm chart. This is a direct consequence of the CRD-based availability check producing false negatives.
π» Environment
π Additional Context
Root cause (from source): In
pkg/kubescape/kubescape.go,KubescapeToolholds a dedicatedapiExtClient"for verifying CRD existence", andhandleCheckHealthuses it to check these resources. Since they are aggregated-API resources (not CRDs), this client is the wrong mechanism β hence the false negative described above.Suggested fix: Replace the CRD-existence check with an API-availability check,
as described in Expected Behavior β a lightweight request through the existing
spdxClient(preferred), optionally corroborated by theAPIServiceAvailable=Truecondition. CRD existence should not be used as the availabilitycriterion for these resources.
References: