httphandler/README.md
The HTTP Handler provides a REST API for running Kubescape scans programmatically. This enables integration with CI/CD pipelines, custom dashboards, and automation workflows.
When running Kubescape as a service, it starts a web server on port 8080 that exposes REST APIs for:
Endpoint: POST /v1/scan
Triggers a Kubescape scan. By default, scans run asynchronously and return a scan ID immediately.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
wait | bool | false | Wait for scan to complete (synchronous mode) |
keep | bool | false | Keep results in cache after returning |
Request Body: See Trigger Scan Object
Response (async):
{
"id": "scan-12345",
"type": "busy",
"response": "scanning in progress"
}
Response (sync with wait=true): Same as Get Results response.
The service accepts a bounded number of pending scans. If the queue is full,
the endpoint returns 429 Too Many Requests with a Retry-After header. A
request body larger than the configured limit returns 413 Request Entity Too Large before the scan is admitted.
Endpoint: GET /v1/results
Retrieve scan results.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
id | string | - | Scan ID. If empty, returns latest results |
keep | bool | false | Keep results in cache after returning |
Response (success):
{
"id": "scan-12345",
"type": "v1results",
"response": { /* scan results object */ }
}
Response (error):
{
"id": "scan-12345",
"type": "error",
"response": "error message"
}
Response (in progress):
{
"id": "scan-12345",
"type": "busy",
"response": "scanning in progress"
}
Endpoint: GET /v1/status
Check if a scan is still in progress. Useful for polling without retrieving full results.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
id | string | - | Scan ID. If empty, checks if any scan is in progress |
Response (in progress):
{
"id": "scan-12345",
"type": "busy",
"response": "scanning in progress"
}
Response (complete):
{
"id": "scan-12345",
"type": "notBusy",
"response": "scanning completed"
}
Endpoint: DELETE /v1/results
Delete cached scan results.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
id | string | - | Scan ID to delete. If empty, deletes latest |
all | bool | false | Delete all cached results |
{
"format": "json",
"excludedNamespaces": ["kube-system", "kube-public"],
"includeNamespaces": ["production", "staging"],
"useCachedArtifacts": false,
"keepLocal": true,
"account": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"accessKey": "your-access-key",
"targetType": "framework",
"targetNames": ["nsa", "mitre"]
}
| Field | Type | Description |
|---|---|---|
format | string | Output format (default: json) |
excludedNamespaces | []string | Namespaces to exclude from scan |
includeNamespaces | []string | Namespaces to include in scan |
useCachedArtifacts | bool | Use cached artifacts (offline mode) |
keepLocal | bool | Don't submit results to backend |
account | string | Kubescape SaaS account ID |
accessKey | string | Kubescape SaaS access key |
targetType | string | "framework" or "control" |
targetNames | []string | Frameworks/controls to scan |
{
"id": "scan-12345",
"type": "v1results",
"response": { /* payload */ }
}
| Field | Type | Description |
|---|---|---|
id | string | Scan identifier |
type | string | Response type (see below) |
response | any | Response payload |
Response Types:
| Type | Description |
|---|---|
v1results | Scan results object |
busy | Scan in progress |
notBusy | No scan in progress |
ready | Scan complete, results ready |
error | Error occurred |
# 1. Trigger scan
curl -X POST http://127.0.0.1:8080/v1/scan \
-H "Content-Type: application/json" \
-d '{"targetType": "framework", "targetNames": ["nsa"]}'
# 2. Check status
curl http://127.0.0.1:8080/v1/status
# 3. Get results
curl http://127.0.0.1:8080/v1/results -o results.json
curl -X POST "http://127.0.0.1:8080/v1/scan?wait=true" \
-H "Content-Type: application/json" \
-d '{"targetType": "framework", "targetNames": ["nsa"]}' \
-o results.json
curl -X POST http://127.0.0.1:8080/v1/scan \
-H "Content-Type: application/json" \
-d '{
"includeNamespaces": ["production"],
"targetType": "framework",
"targetNames": ["nsa", "mitre"]
}'
curl -X POST http://127.0.0.1:8080/v1/scan \
-H "Content-Type: application/json" \
-d '{
"account": "YOUR-ACCOUNT-ID",
"accessKey": "YOUR-ACCESS-KEY",
"targetType": "framework",
"targetNames": ["nsa"]
}'
curl -X DELETE "http://127.0.0.1:8080/v1/results?all=true"
Configure the HTTP handler using environment variables:
| Variable | Description | Example |
|---|---|---|
KS_ACCOUNT | Default account ID | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
KS_EXCLUDE_NAMESPACES | Default namespaces to exclude | kube-system,kube-public |
KS_INCLUDE_NAMESPACES | Default namespaces to include | production,staging |
KS_FORMAT | Default output format | json |
KS_LOGGER_NAME | Logger name | kubescape |
KS_LOGGER_LEVEL | Log level | info, debug, warning, error |
KS_DOWNLOAD_ARTIFACTS | Download artifacts on each scan | true, false |
KS_SCAN_QUEUE_CAPACITY | Maximum number of scans waiting behind the active scan | 10 |
KS_SCAN_REQUEST_MAX_BYTES | Maximum size in bytes of a POST /v1/scan request body | 1048576 |
KS_PPROF_ENABLED | Enable the pprof debug server (off by default; binds to loopback only) | true, false |
KS_PPROF_ADDR | Address the pprof debug server binds to when enabled | 127.0.0.1:6060 |
Deploy Kubescape as a microservice in your cluster for API-driven scanning.
š Microservice Deployment Guide ā
Expose Kubescape metrics for Prometheus scraping.
š Prometheus Integration Guide ā
Set the log level to debug for more verbose output:
export KS_LOGGER_LEVEL=debug
The pprof debug server is off by default and binds to 127.0.0.1 only, so it's
reachable from inside the pod's network namespace but not from the network. Enable it
and reach it via kubectl port-forward:
export KS_PPROF_ENABLED=true
# then, e.g.: kubectl port-forward <pod> 6060:6060
# Heap profile
go tool pprof http://127.0.0.1:6060/debug/pprof/heap
# CPU profile
go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=30
# Goroutine profile
go tool pprof http://127.0.0.1:6060/debug/pprof/goroutine
Set KS_PPROF_ADDR to change the bind address (e.g. if 6060 collides with a sidecar
in the pod). Binding to anything other than loopback is a deliberate, explicit choice ā
do so only on a trusted network.
For more information on pprof, see the pprof documentation.