Skip to content

lookout state edges

Verify every dependency edge of one workload — ConfigMap/Secret keys, imagePullSecrets, Service selectors and endpoints, Ingress backends and class, StatefulSet governing Service and volume classes, ServiceAccount/RBAC references, TLS expiry — reporting only the broken ones. —workload also accepts Service/<namespace>/<name> to enter from the service side, which is the direction the evidence arrives from when a service has no endpoints: it reports that service’s selector, endpoints, ingresses and certificates, and names the workload the selector was probably meant for.

MCP tool: k8s_state_edges (MCP profile: triage)

Terminal window
lookout state edges [flags]
FlagTypeDefaultMeaning
--cert-warnduration720hreport TLS certificates expiring within this window
FlagTypeDefaultMeaning
--namespacestring—limit the scan to one namespace
-Abool—scan all namespaces
--workloadstring—target one workload as <Kind>/<namespace>/<name>, e.g. Deployment/prod/api
--sinceduration—how far back to look (0 = command default)
--formatstringlogfmtoutput format: logfmt|json (one record per line either way)
--timeoutduration10sabort the invocation after this long (exit 1)
--kubeconfigstring—path to a kubeconfig file, instead of $KUBECONFIG / ~/.kube/config
--contextstring—kubeconfig context to read, instead of its current-context. Selects a cluster for THIS invocation only — nothing is written back — so concurrent invocations can target different clusters. Reported as context=<name> in the summary line
--exemptionsstring—path to a git-reviewed exemption file (YAML); covered findings are ANNOTATED with their reason and expiry and counted as exempt=<n> in the summary, never dropped

Every kind= this command can emit, and the severities it carries them at. Nothing else appears in its output; a kind absent from a run means the check looked and found nothing. See the finding-kind glossary for the whole vocabulary.

KindSeverityClaim
edge.missing_refcriticala referenced ConfigMap, Secret, ServiceAccount, TLS secret, IngressClass, StorageClass, or governing Service does not exist
edge.missing_keycriticalthe referenced key is absent from an existing ConfigMap/Secret
edge.invalid_refwarningthe referenced object exists but is the wrong type to serve the reference
edge.unclassedwarningthe Ingress names no class and no IngressClass declares itself the cluster default — no controller will claim it
edge.selector_emptycriticala Service selector selects zero pods, so the service routes nowhere
edge.selector_unreadycritical, warningthe Service selects pods but some are not Ready; critical when none are
edge.endpoints_missingcriticala selecting Service has no EndpointSlices at all
edge.endpoints_orphanedwarningan endpoint targetRef names a pod that no longer exists
edge.endpoints_unreadycritical, warningthe endpoint ready-count disagrees with the selected pods (stale or lagging slices); critical at zero ready
edge.backend_missingcriticalan Ingress backend service, or the port it names, does not exist
edge.cert_expiredcriticala TLS certificate’s NotAfter is in the past
edge.cert_expiringwarninga TLS certificate expires within —cert-warn
edge.cert_invalidwarningtls.crt is missing or unparseable, or the secret is not kubernetes.io/tls
edge.rbac_danglingwarninga (Cluster)RoleBinding for the workload’s ServiceAccount points at a missing (Cluster)Role

Beyond the shared envelope fields (kind, severity, namespace, kind_of_object, name, reason, message, fingerprint, exempt_reason, exempt_expires):

FieldMeaning
workloadthe target the edges were traced from as <Kind>/<namespace>/<name>, stamped on every finding — a workload, or the Service itself when entered from the service side
likely_workloadon a Service-entry edge.selector_empty: the workload in that namespace whose pod labels best fit the broken selector, i.e. the one it was probably meant to select. Absent when two workloads fit equally well, because then naming one would be a guess
podshow many of the workload’s pods carry the broken reference
containercontainer declaring the broken env/envFrom reference
envenvironment variable whose valueFrom reference is broken
volumepod volume, or StatefulSet volumeClaimTemplate, whose reference is broken
keythe referenced key that is missing from the ConfigMap/Secret
selectorthe Service label selector under scrutiny
selectedpods the Service selector currently selects
readyready count (selected pods or serving endpoints, per finding kind)
endpointstotal endpoints across the Service’s EndpointSlices
sliceshow many EndpointSlices back the Service
servicethe Service a slice, Ingress backend, or StatefulSet serviceName refers to
podpod named by an orphaned endpoint targetRef
subjectTLS certificate subject (CN when set); never key material
not_afterTLS certificate NotAfter, RFC 3339
days_leftwhole days until NotAfter (negative = expired)
viahow the broken reference is reached from the workload: mount, ingress, or imagePullSecret
ingressIngress referencing the TLS secret, or the unserved Ingress itself
hostIngress rule host of the broken backend (empty for the default backend)
pathIngress rule path of the broken backend
portService port (name or number) the Ingress backend asks for
service_accountServiceAccount the RBAC finding is about, or the one contributing an imagePullSecret
role_refdangling roleRef as <Kind>/<name>

Output: one finding per line (logfmt; —format=json for one JSON object per line), keys in fixed order; healthy resources emit nothing. The final line is always the summary: scanned= findings= elapsed= — findings=0 with a summary present means “scanned and healthy”; a stream without a summary line is void. Exit 0 data, 1 runtime error (diagnostics on stderr only), 2 usage.

Terminal window
lookout state edges --workload=Deployment/prod/api
lookout state edges --workload=Pod/prod/api-6d5f8c-x2v9k --format=json
lookout state edges --workload=StatefulSet/db/postgres --cert-warn=336h
lookout state edges --workload=Service/prod/api