ICE: active defence for Kubernetes
Not a scanner — a loop. ICE turns findings and drift into GitOps pull requests a person approves, and calls a problem fixed only when a measurement taken after the merge says so.
- Who it's for
- Teams of 5–50 engineers where one or two people own the infrastructure and there is no dedicated security team.
- What you get
- Findings that arrive as reviewable pull requests, and cases that close only when the cluster proves the fix.
- Where it stands
- In development since July 2026, to be open-sourced under Apache-2.0. Looking for design partners.
10 live63 tested3 implemented1 contractcapabilities as of 18 October 2026 · what that means
Why another security tool
You switch a scanner on, and nobody reads its reports. The channel with 400 findings is muted by day three. The CI gate is ripped out during the first hotfix. What is left is security on paper.
ICE starts from the other end — from the action. Every signal has to answer three questions before it is allowed into the system:
- What is the action?
- Who performs it?
- Why are we sure?
A detector that cannot answer all three is rejected when its signal arrives, and the reason shows up on its pack. A missing component is never reported as a broken requirement: "you don't run a service mesh" and "your mesh is configured insecurely" are different statements, and ICE keeps them apart.
The estate can be mixed: managed Kubernetes, bare-metal Kubernetes and plain servers.
The loop
- ObserveA read-only agent and your CI scans report facts out of the cluster.
- DetectPacks turn facts into findings — only if each says what to do, who does it and why it is sure.
- DecideA person approves a deterministic, digest-pinned change.
- DeliverThe operator opens a pull request in your GitOps repository.
- VerifyThe case closes only on a measurement newer than the merge.
Merged is not deployed, and deployed is not fixed. A remediation case walks through explicit states, and the last two are earned, not declared:
- openICEa requirement is unmet
- proposedICErendered change + digest
- approvedpersonin the console
- deliveredICEpull request opened
- mergedpersonyour review, your repo
- deployedmeasurementArgo CD Synced on the merge revision
- verifiedmeasurementa measurement newer than the merge
Before a change is applied, ICE renders it again. If the digest no longer matches what the person approved, the action fails instead of shipping something nobody reviewed.
What it looks like
The real ICE console, running against synthetic demo data for a fictional company, acme-corp — not a production estate.



Principles enforced by code, not by discipline
- Writes go through pull requests — because there is nothing else. Outside its own resources the operator can only
getandlist; tests check that matrix against a real kube-apiserver authorizer — no secrets, nopods/exec, no impersonation. Unknowncounts as unmet. A verdict older than its cadence drops toUnknown; a failed source reports unmeasured, never clean.- A rule whose alert cannot be delivered is not loaded — and the pack's status says why.
- One signal is not an action. A runtime response needs three different detectors to agree, only for assets you marked as crown jewels; acting on a client IP needs the "client IP is trusted" precondition measured as met.
- The model advises; it has no hands. An optional LLM explains entities; it has no tools, PII redaction cannot be turned off, and it never changes a detector's weight. The MCP interface is read-only, off by default, and marks every answer as untrusted data.
- No Black ICE. The name is cyberpunk's intrusion countermeasures electronics, popularised by William Gibson's Neuromancer — minus the counter-attack. Every response targets the estate it protects.
- The product does not know its test clusters. A CI gate keeps proving-ground names out of the product; portability is checked against a synthetic company.
The detail behind each principle →
Works with the stack you already run
ICE does not replace your detection or policy tools — it takes their output and decides what to do with it, then proves whether it worked.
| Your tool | What ICE does with it | Status |
|---|---|---|
| Falco, Tetragon | receives syscall events as runtime signals | live (Falco) |
| Trivy, Grype | scheduled image scans with a delta to the accepted baseline; CycloneDX SBOMs | live (scans) |
| GitHub | remediation pull requests opened from a console approval | live |
| GitLab | the same pull-request flow on a second forge | tested |
| Argo CD | a case is deployed only when the application is Synced on the merge revision | tested |
| Prometheus, Alertmanager | PromQL detectors as generated PrometheusRule objects — one of eleven renders today, and the generator names its reason for each refusal; alerts reach the agent | tested |
| Loki | LogQL detectors are defined but need a Loki ruler to run | not yet |
| Kyverno | reads PolicyReport objects as posture facts; proposes policies in audit mode only | tested |
| Istio, Linkerd | posture checks and authorisation-by-service-account responses | tested |
| OIDC | console sign-in and the approver role, including providers other than Keycloak | tested |
| MCP clients | read-only tools for AI assistants, off by default | live |
live means observed on a running cluster with dated evidence; tested means covered by tests but not yet seen on a cluster — the same scale as in Honest status.
Honest status
ICE has its own rule for honesty: a capability can be marked live only with dated evidence from a running cluster, and CI fails if the evidence is missing. The day after that rule arrived, five rows were downgraded from live to tested — nobody could produce the evidence.
As of 18 October 2026:
| Status | Capabilities | Meaning |
|---|---|---|
| live | 10 | observed on a real cluster, with dated evidence |
| tested | 63 | covered by tests against envtest and a real PostgreSQL |
| implemented | 3 | code exists, tests are partial |
| contract | 1 | the interface is fixed, there is no executor yet |
Live today: daily image scans with a delta to baseline and provenance; syscall detectors via Falco; console approval that opens a real GitOps pull request; the read-only MCP; a daily automated walk-through of the console.
Not there yet: the full case up to verified passes in tests but has not been watched end-to-end on a live cluster; the second proving-ground cluster is not connected; there are no tagged releases; one trust domain per installation, no multi-tenancy.
Questions
Is ICE a scanner?
No. Scans are one input. ICE runs from detection to a verified fix: findings become pull requests a person approves, and a case closes only on a measurement taken after the merge.
Does ICE change my cluster?
Not directly. The operator has no write rights outside its own resources; changes reach the cluster as pull requests to your GitOps repository, and your pipeline applies them. The one exception to human approval is a trap response, and only if you opt in — even then the change arrives as a pull request.
Does it replace Falco or Kyverno?
No — it consumes what they report and turns it into decisions, pull requests and verified outcomes.
Is ICE open source?
It will be released under Apache-2.0. Until then it is developed in private, with design partners.
Where does it run?
On any Kubernetes cluster, with a collector for plain servers. A local trial on kind takes 15–20 minutes.
Become a design partner
I'm looking for teams running Kubernetes in production that want the loop on their estate before the public release — and will tell me where it hurts. What a pilot involves →
or write to [email protected]