Skip to main content

Security Scan APIs

Four automated scan APIs built into the stack-agent. Each scan reads the Stacktic topology, discovers targets automatically, runs real tests, and returns structured JSON with scores.


Scan Overview

ScanEndpointLightFullWhat It Validates
NetworkGET /network_scanPolicy existence (~2s)nmap TCP probes (~2-5min)NetworkPolicies match architecture
OPAGET /opa_scanInventory + violations (~2-5s)Admission dry-run tests (~15-45s)OPA/Gatekeeper policies enforce correctly
KubescapeGET /kubescape_scanPer-namespace scores (~30-60s)Per-control findings (~2-4min)K8s compliance (NSA/MITRE frameworks)
NucleiGET /nuclei_scanIngress route scan (~1-3min)Tech-specific CVEs (~5-15min)Vulnerabilities, exposed panels, misconfigs

All scans accept ?mode=light or ?mode=full query parameter.


Network Scan

Validates that NetworkPolicies match the stack topology defined in Stacktic.

Data Source

Reads networkpolicy-manifest.json — pre-generated by the Stacktic pipeline. Contains every expected policy rule derived from component links.

Light Mode

What It ChecksHow
Policy existenceCompares manifest rules against kubectl get networkpolicies
Missing policiesRules in manifest but not in cluster
Extra policiesPolicies in cluster but not in manifest
Bidirectional coverageBoth ingress + egress exist for each link
Namespace breakdownMissing policies grouped by namespace

Returns: score, policies breakdown (link/exception/internet/intra-namespace/default-deny), bidirectional analysis, extra policies list, missing by namespace.

Full Mode

Everything in light, plus real TCP connectivity probes:

Test LayerWhat It Probes
Link testsEvery manifest connection (src→dst:port) via nmap
Exception testsDNS (port 53) and kube-api (port 443) from each namespace
Internet testsOutbound 80/443 from stack namespaces
Intra-namespaceService connectivity within same namespace
Negative testsUnauthorized paths verified as BLOCKED

Creates temporary nmap pods in each source namespace (10 concurrent). For failed connections, runs blocking analysis matching against actual NetworkPolicy specs.

Verdicts: PASS (connection matches expectation), FAIL (should connect but can't), SECURITY_RISK (blocked path is actually open), BLOCKED (expected block confirmed), NO_SERVICE (target service doesn't exist).


OPA Scan

Validates OPA/Gatekeeper policies are correctly deployed and actually enforcing.

Data Source

Auto-discovers Gatekeeper in any namespace (searches: gatekeeper-system, opa, gatekeeper). Reads all ConstraintTemplates and Constraints via Kubernetes API.

Light Mode

What It ReturnsDetails
Gatekeeper healthPod readiness status
Constraint templatesTotal count + names
ConstraintsPer-constraint: name, template, action, target kinds, violation count
ViolationsGrouped by constraint + by namespace
Namespace coverageWhich namespaces are scoped by policies
Score% of constraints with zero violations

Full Mode

Everything in light, plus admission dry-run tests per constraint:

Per ConstraintWhat Happens
Valid resourceResource that should be ADMITTED — satisfies all active constraints
Invalid resourceResource that should be DENIED — violates this specific constraint
Dry-runBoth submitted via kubectl apply --dry-run=server

Cross-policy aware: each valid test resource satisfies ALL active constraints simultaneously (security context, resources, probes, labels, image registries).

Verdict Reference

StatusValid TestInvalid TestMeaning
ENFORCINGAdmittedDeniedPolicy working correctly
NOT_ENFORCINGAdmittedAdmittedPolicy not blocking violations
OVER_ENFORCINGDeniedDeniedPolicy too strict, blocks legitimate resources
BROKENDeniedAdmittedMisconfigured constraint
AUDIT_ONLYConstraint requires cluster state (skipped)

Test generators: SecurityContextPolicy, ResourcePolicy, ProbesPolicy, DisallowDangerousSettings, K8sAllowedImageRequirements, ImageSigningPolicy, BlockNamespaceDeployments, BlockWideOpenNetworkPolicy, DisallowDefaultServiceAccount, DisallowWildcardRBAC, RequiredLabelsPolicy, RequireNetworkPolicy.


Kubescape Scan

Validates Kubernetes compliance against NSA/CISA and MITRE ATT&CK frameworks.

Data Source

Reads stack-metadata.yaml (Stacktic topology) to discover all stack namespaces. Runs kubescape CLI per namespace.

Light Mode

What It ReturnsDetails
Per-namespace scoresNSA + MITRE framework scores separately
Component listWhich components run in each namespace
Overall scoresAverage across all namespaces
Flagged namespacesOnly namespaces below threshold (NSA < 70%, MITRE < 60%)

Full Mode

Everything in light, plus per-control findings:

Per Failed ControlDetails
Control ID + nameNSA/MITRE control identifier
SeverityCritical, high, medium
Affected resourcesPod/deployment names that fail the control
Stacktic remediationWhich Stacktic attribute to set to fix
K8s fieldThe specific securityContext/spec field that needs fixing

Exclusion-aware: Filters out legitimate operator requirements that cannot be changed:

Exclusion TypeExamples
Operators needing elevated RBACArgoCD, cert-manager, ESO, Velero
Components requiring rootClickHouse (by design)
Components needing writable FSPrometheus (TSDB), Grafana (plugins)
CSI drivers needing privilegedStorage provisioners

Separates "known architectural limitation" from "actual security misconfiguration".


Nuclei Scan

Vulnerability scanning (DAST) with four modes. Discovers targets from APISIX topology.

Data Source

Reads stack-metadata.yaml to discover APISIX routes (externally exposed services) and internal services.

Modes

ModeTargetsTemplatesTime
lightAPISIX ingress routes onlyexposure, misconfiguration, default-login, panel~1-3min
fullRoutes + internal servicesTech-specific CVE templates per component type~5-15min
networkTCP services (databases, queues)unauth, default-login, misconfig~2-5min
sslHTTPS routes onlySSL/TLS certificate checks~30s

Full Mode — Tech-Specific Scanning

Maps component types to nuclei template tags:

Component TypeNuclei Tags
grafanagrafana CVEs
keycloakkeycloak CVEs
mongodbmongodb unauth
cnpg / postgresqlpostgres CVEs
opensearch / elasticsearchelasticsearch CVEs
rabbitmqrabbitmq CVEs
miniominio CVEs
redis / valkeyredis CVEs

Network Mode

Scans TCP-only services for:

  • Unauthenticated database access
  • Exposed management ports
  • Default credentials
  • Protocol-level vulnerabilities

SSL Mode

Checks all HTTPS ingress routes for:

  • Expired certificates
  • Weak cipher suites
  • Deprecated TLS versions
  • Self-signed certificates
  • Revoked certificates

What Makes These Scans Smart

FeatureHow It Works
Topology-awareAll scans read Stacktic metadata — know what SHOULD exist, not just what DOES exist
Link-drivenNetwork scan validates every component link has a matching policy
Cross-policy testingOPA scan tests that valid resources satisfy ALL constraints simultaneously
Exclusion-awareKubescape filters known operator requirements from findings
Tech-specificNuclei selects vulnerability templates based on component type
BidirectionalNetwork scan checks both ingress and egress for every connection
Negative testingNetwork scan verifies unauthorized paths are actually blocked
Remediation mappingKubescape maps failures to Stacktic attributes (not just K8s fields)

Access

# Via port-forward
kubectl port-forward -n {agent-namespace} svc/{agent-name} 8081:8080

# Light scan
curl -s http://localhost:8081/{scan}?mode=light | jq

# Full scan
curl -s http://localhost:8081/{scan}?mode=full | jq

Via APISIX (if ingress configured):

curl -s -H 'apikey: {api-key}' 'https://{subdomain}.{domain}/{scan}?mode=light' | jq

Replace {scan} with: network_scan, opa_scan, kubescape_scan, or nuclei_scan.


Response Structure

All scans return:

FieldDescription
scan_typelight or full
scoreOverall compliance score (0-100)
Summary sectionCounts, breakdowns, grouped results
Findings (full)Per-test results with verdicts and details