lookout state webhooks
When creates/updates hang or fail cluster-wide with “failed calling webhook”, or before relying on a policy engine: audit every admission webhook — dead backends × failurePolicy (Fail + dead backend rejects every matching admission), the namespace/rule blast radius, timeout stall risk, CA-bundle expiry. The full check; health’s webhooks category delegates here.
MCP tool: k8s_admission_webhooks
lookout state webhooks [flags]| Flag | Type | Default | Meaning |
|---|---|---|---|
--cert-warn | duration | 720h | report webhook CA bundles expiring within this window |
Common flags (every lookout command)
Section titled “Common flags (every lookout command)”| Flag | Type | Default | Meaning |
|---|---|---|---|
--namespace | string | — | limit the scan to one namespace |
-A | bool | — | scan all namespaces |
--workload | string | — | target one workload as <Kind>/<namespace>/<name>, e.g. Deployment/prod/api |
--since | duration | — | how far back to look (0 = command default) |
--format | string | logfmt | output format: logfmt|json (one record per line either way) |
--timeout | duration | 10s | abort the invocation after this long (exit 1) |
--kubeconfig | string | — | path to a kubeconfig file, instead of $KUBECONFIG / ~/.kube/config |
--context | string | — | 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 |
--exemptions | string | — | 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 |
Finding kinds
Section titled “Finding kinds”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.
| Kind | Severity | Claim |
|---|---|---|
webhook.failing_closed | critical | the webhook has no working backend and failurePolicy=Fail: every gated write is rejected cluster-wide |
webhook.dead_backend | warning | the webhook’s service backend is missing, has no ready endpoints, or does not serve the named port |
webhook.slow_risk | info | the webhook’s timeout is long enough to slow every gated write if the backend degrades |
webhook.ca_expired | critical | the webhook’s caBundle has expired: the API server cannot verify it |
webhook.ca_expiring | warning | the webhook’s caBundle expires within —cert-warn |
Output fields
Section titled “Output fields”Beyond the shared envelope fields (kind, severity, namespace, kind_of_object, name, reason, message, fingerprint, exempt_reason, exempt_expires):
| Field | Meaning |
|---|---|
webhook | admission webhook as <configuration>/<webhook name> |
service | service backend the webhook points at, as <namespace>/<name> |
backend | why the backend is dead: service missing, no ready endpoints, or port <p> not on service |
gates | namespaces the webhook gates, from namespaceSelector: all namespaces, or <matched>/<total> namespaces with up to 5 names |
rules | compact operations/resources summary of the webhook’s rules, e.g. “CREATE,UPDATE pods,deployments.apps” |
object_selector | the webhook’s objectSelector, when one is set |
timeout | webhook timeoutSeconds as <n>s (nil defaults to the API’s 10s) |
subject | CA-bundle certificate subject (CN when set); never key material |
not_after | CA-bundle certificate NotAfter, RFC 3339 |
days_left | whole days until NotAfter (negative = expired) |
Output contract
Section titled “Output contract”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=
Examples
Section titled “Examples”lookout state webhookslookout state webhooks --format=json --cert-warn=336h