"You can lie to me about the tank level. You cannot lie to me about the tank, the pump, and the level all at once and still balance the books."
An Unbribable AI Agent
Prerequisites
This section assumes the measurement-model view of a sensor from Chapter 2 (a reading is a physical quantity plus a transfer function plus noise, not ground truth), the SCADA, PLC, and historian architecture of Chapter 35 (sensors and actuators wired to programmable controllers, logged at a fixed cadence), and the residual-and-threshold vocabulary of Chapter 12. Elementary probability from Chapter 4 is used to set thresholds but not re-derived. No control-theory or chemical-engineering background is required; the physical relations we exploit (mass balance, actuator-to-flow coupling) are stated from first principles as we need them. We deliberately leave two neighbouring questions for later: telling a malicious invariant violation from an innocent fault is the whole subject of Section 38.2, and learned reconstruction or forecasting residuals, the data-hungry cousins of hand-derived invariants, arrive in Section 38.3.
The Big Picture
An industrial control system is not a pile of independent sensors; it is a physical process wired to controllers, and physics stitches its signals together. A pump that is running must move water. A closed valve must stop flow. The water entering a tank minus the water leaving it must equal the rate at which the tank fills. These are not statistical tendencies learned from data; they are constraints the plant obeys every second it is not on fire. A physical process invariant is one such constraint written as a checkable predicate over sensor and actuator variables. Its power for security is blunt and beautiful: an attacker who spoofs a single sensor to hide their tampering breaks the arithmetic that ties that sensor to the rest of the plant, and the broken arithmetic is far harder to forge than any one number. This section builds the vocabulary of invariants, shows how to derive and mine them, and marks exactly where their edges are.
What an invariant is, precisely
Let the plant expose a vector of process variables \(z_t = (s_t, a_t)\) at time \(t\), where \(s_t\) collects sensor readings (levels, flows, pressures, temperatures) and \(a_t\) collects actuator states (pump on/off, valve position, motor speed). A process invariant is a predicate \(\phi(z_t, z_{t-1}, \ldots)\) that evaluates to true for every physically consistent trajectory of the plant. Two flavours matter. A stateless invariant constrains a single snapshot, for example "if pump P101 is ON then flow FIT101 exceeds \(0.5\) m\(^3\)/h." A stateful invariant constrains change over time and usually encodes a conservation law, for example the mass balance of a tank,
$$ A \,\frac{dL}{dt} \;=\; Q_{\text{in}} - Q_{\text{out}}, $$where \(L\) is level, \(A\) the tank cross-section, and \(Q_{\text{in}}, Q_{\text{out}}\) the metered flows. Discretised, this says the measured level change over one step should equal the net flow times \(\Delta t / A\); any persistent gap is an invariant residual \(r_t = |\Delta L_t^{\text{meas}} - (Q_{\text{in}} - Q_{\text{out}})\,\Delta t / A|\) that a healthy plant keeps near sensor-noise size and an attack drags away from zero.
The security value comes from redundancy across variables. A single reading has no internal consistency to check; it is whatever the wire says. But a mass balance couples three meters, and an actuator-flow rule couples a command to its effect. To defeat the invariant, an attacker must corrupt every variable in the predicate in a mutually consistent way, in real time, without access to the true physical state. That is a qualitatively harder attack than flipping one number, which is exactly why invariants are a security primitive and not merely a plausibility filter.
Key Insight
A single sensor is trivial to spoof because nothing contradicts it. An invariant is hard to spoof because it forces contradiction: it is a small conservation-of-truth budget that the attacker must keep balanced across several signals at once. The number of variables an invariant binds together is, roughly, its spoofing cost. This is the cyber-physical analogue of double-entry bookkeeping, and it is why a physics floor complements the learned detectors of Section 38.3 rather than duplicating them: the invariant catches exactly the stealthy, single-sensor manipulations that a reconstruction model, trained to match whatever it is shown, can be coaxed to accept.
A taxonomy: physical, control, and data-driven invariants
Invariants come from three sources, and knowing which you are holding tells you how much to trust it. First-principles physical invariants follow from conservation of mass, energy, and momentum, or from device physics: a mass balance, an energy balance, a pump curve relating speed to head and flow. These are the strongest because they hold by law, independent of the historian data, so no amount of clever training data can erase them. Control and design invariants follow from how the plant was engineered and programmed: the piping-and-instrumentation diagram (P&ID) says valve MV201 gates the line feeding tank T2, and the PLC logic says P101 turns on only when level LIT101 is below its low setpoint. These encode the intended cause-effect wiring of actuators and sensors. Data-driven invariants are relationships mined from historian logs of normal operation: a strong correlation, a linear relation among pressures, a discretised association rule that always held across a year of clean data. They are the easiest to obtain at scale and the weakest to trust, because a relation that merely held in the training window may be a coincidence of operating conditions rather than a law, a subtlety that the physics-informed modelling of Chapter 55 takes up in depth.
Two properties cut across the taxonomy. An invariant can be state-dependent: the flow-versus-pump rule only applies while the pump is commanded ON, so the predicate must be guarded by the actuator state rather than asserted unconditionally. And an invariant has a tolerance: no real plant satisfies \(r_t = 0\) exactly, because sensors are noisy and models are approximate, so every invariant ships with a band \(r_t \le \tau\) whose width you set from clean data to trade false alarms against missed attacks, precisely the threshold-selection problem of Chapter 12.
In Practice: the Secure Water Treatment testbed and a frozen level sensor
The SWaT testbed at the Singapore University of Technology and Design is a six-stage water-treatment plant instrumented exactly like a municipal one: raw-water tanks, chemical dosing, ultrafiltration, reverse osmosis, each stage with its own level, flow, and pressure sensors driving PLCs. It has become the reference ground for ICS-security research because researchers can launch real attacks on real hardware. Consider a classic stealthy attack: the adversary compromises the network and freezes the raw-water tank level sensor LIT101 at a comfortable mid-range value, then commands the inlet valve to stay open. To the operator's screen, everything looks calm; the level "holds steady." But the physics does not hold steady. Water keeps flowing in while the reported level refuses to rise, so the mass-balance residual, the gap between what the flow meters imply and what the level sensor claims, climbs off zero within seconds and stays there. An invariant monitor watching \(A\,\Delta L\) against \(Q_{\text{in}} - Q_{\text{out}}\) flags the manipulation long before the tank overflows, and it does so without ever having seen this attack in training, because it is checking a law, not recognising a pattern.
Deriving and mining invariants
There are two routes to a rulebook, and mature deployments use both. The design-led route reads the P&ID, the control narrative, and the PLC ladder logic, and transcribes the physics and the intended interlocks into predicates by hand. It yields few rules but strong ones, each auditable by an engineer and each grounded in law or specification. The data-led route runs an automated miner over a clean historian dump: discretise continuous signals into a few levels, then search for relations that hold on (almost) every logged row, whether linear equalities among analog variables or association rules among the discretised states. This yields many candidate rules cheaply, at the cost of a validation burden, because the miner cannot tell a physical law from a habit of the operating schedule.
The listing below makes the stateful case concrete. It simulates a tank under a mass balance, injects a sensor-freeze attack, and shows that a single physics invariant, thresholded from clean early data, separates the attack from normal operation cleanly. The residual is referenced in the discussion that follows.
import numpy as np
rng = np.random.default_rng(0)
T, A, dt = 2000, 1.5, 1.0 # steps, tank area (m^2), step (s)
t = np.arange(T)
Qin = 0.020 + 0.005*np.sin(t/50) # metered inflow (m^3/s)
Qout = 0.020 + 0.005*np.cos(t/60) # metered outflow (m^3/s)
# True level integrates the mass balance; the sensor adds small noise.
level = 1.0 + np.cumsum((Qin - Qout)*dt)/A
meas = level + rng.normal(0, 1e-3, T)
# ATTACK: from t=1200, freeze the level sensor while the tank keeps filling.
meas_att = meas.copy()
meas_att[1200:] = meas[1200]
# INVARIANT residual: measured level change vs. what the flow balance predicts.
pred_dL = (Qin - Qout)*dt / A
resid = np.abs(np.diff(meas_att) - pred_dL[1:])
tau = 6 * resid[:1000].std() # threshold from clean early window
alarm = resid > tau
print(f"threshold tau : {tau:.2e} m")
print(f"false-alarm rate t<1200: {alarm[:1199].mean():.3f}")
print(f"detection rate t>=1200: {alarm[1199:].mean():.3f}")
As Listing 38.1 shows, the invariant needs no library of past attacks, only a clean baseline to size its tolerance \(\tau\). That is the structural gift of physics-based detection: it defends against manipulations it has never observed, because it defends the law rather than a memorised signature. The data-led route trades some of that certainty for coverage, mining the analog and discrete relations that no one thought to transcribe by hand.
The Right Tool
Mining stateless invariants by hand, enumerating candidate antecedents, counting support and confidence across millions of historian rows, pruning by a minimum-support lattice, is a few hundred lines of careful combinatorics. After discretising each signal into a handful of levels, mlxtend's frequent-itemset and association-rule engine does the search for you and returns rules like "P101=ON ⇒ FIT101=high" with support and confidence attached:
from mlxtend.frequent_patterns import apriori, association_rules
# df_onehot: historian rows one-hot encoded as "SENSOR=level" boolean columns
freq = apriori(df_onehot, min_support=0.02, use_colnames=True)
rules = association_rules(freq, metric="confidence", min_threshold=0.999)
# keep near-certain rules as candidate invariants, then validate against physics
mlxtend collapses roughly 250 lines of itemset-mining plumbing into two calls, turning a year of clean logs into ranked candidate invariants. It finds the correlations; deciding which are physical laws and which are schedule artefacts, and setting each rule's guard state, remains an engineer's judgement, not the library's.
Strengths, limits, and where invariants sit in the stack
Invariants are the interpretable, low-false-alarm, attack-agnostic floor of a cyber-physical detector. Their strengths are exactly what learned models lack: an alarm names a specific violated law ("tank mass balance breached at T2"), which hands the operator a head start on root cause (Section 38.5); a first-principles invariant cannot be trained away by a poisoned dataset; and a well-chosen invariant flags novel, zero-day manipulations because it never enumerated the attacks. Their limits are equally real. Hand-derived invariants demand process expertise and a correct P&ID, and they are laborious to enumerate. Data-mined invariants risk being coincidences of the training regime, firing false alarms the first time the plant runs a legitimate but under-sampled mode. A tolerance \(\tau\) set too tight drowns operators in noise-driven alerts; set too loose, it opens a band inside which a patient attacker can drift a variable slowly enough to stay under the threshold. And an invariant only covers the variables it binds; a manipulation confined to a signal no invariant touches is simply invisible to this layer.
The practical posture is layered defence. Invariants handle the physically checkable violations with crisp, explainable alarms and near-zero false-positive cost; learned reconstruction and forecasting residuals (Section 38.3) cover the subtler, multivariate patterns no closed-form law captures; and graph-structured models (Section 38.4) learn the plant's coupling structure when the P&ID is incomplete. Invariants are the layer you can hand to a safety auditor, so they anchor the stack even when the fancier detectors do the heavy lifting.
Research Frontier
The reference line of work is Adepu and Mathur's invariant-based detection on SWaT and its larger sibling WADI, which systematically derive Distributed Invariants (also called the DIP, Distributed Attack Detection) coupling sensors and actuators across process stages, and evaluate them against a documented attack catalogue. Complementary threads automate the derivation: mining invariants directly from operational logs, and learning them with support-vector or association-rule techniques so a rulebook can be regenerated as a plant changes. The current frontier blends the two, using physics-informed and graph-neural models (Chapter 55) to learn soft invariants where first principles are unavailable, while keeping hand-derived hard invariants as an auditable safety floor. The open, and genuinely hard, problems are guaranteeing that mined invariants are physical rather than schedule artefacts, and closing the slow-drift gap where an attacker hides inside the tolerance band, which is where the adversarial-robustness discussion of Section 38.6 begins.
Exercise
You are securing a two-tank system: tank T1 drains into tank T2 through a single metered line with valve MV1, and each tank has a level sensor and an inlet/outlet flow meter. (a) Write down one stateful invariant per tank and one cross-tank invariant linking them through MV1, and give the guard state each cross-tank rule needs. (b) An attacker freezes T2's level sensor but leaves all flow meters honest. Which of your invariants fires first, and why can the attacker not silence it by also spoofing MV1's reported position? (c) You mine a data-driven rule "T1-level=high ⇒ T2-level=high" that held on a year of logs. Give one physical reason it might be a genuine invariant and one reason it might be a coincidence of the operating schedule that will produce false alarms.
Self-Check
- Why is a mass-balance invariant harder for an attacker to defeat than a single level-sensor plausibility band, in terms of how many variables must be corrupted consistently?
- Explain the difference between a stateless invariant and a stateful (conservation-law) invariant, and give one example of each for a pump-and-tank system.
- A data-mined rule and a first-principles rule both hold on all your clean historian data. Which do you trust more when the plant enters a rarely-seen operating mode, and why?
What's Next
In Section 38.2, we confront the question this section carefully set aside: a violated invariant tells you the plant left the physically consistent region, but it does not tell you why. A stuck valve, a drifting sensor, and a deliberate cyber-attack can produce identical residuals. We build the vocabulary and the signatures that begin to separate malicious manipulation from ordinary equipment fault, the distinction on which every downstream response decision depends.