Skip to main content
Back to Blog

Observe before you enforce: how we turn on deny-by-default controls

Rob, CEO & Founder9 min read

Why this post exists

This is an operator-side transparency post about a piece of our engineering discipline, not an announcement of a new product feature. EU B2B buyers — DPOs, Heads of Compliance, CTOs, Legal Counsel — increasingly ask a sharp procurement question: "When you turn on a security control that can reject my traffic, how do you know it won't reject the wrong thing?"

The honest answer is a general method we apply to every control of this kind. We never flip a rejecting control straight from "off" to "on." We run it first in a watch-only mode, gather evidence on real traffic, and only enforce once that evidence is clean. This post explains the method in plain language. It is deliberately written about the discipline, not about any one control — the discipline is what is portable, and it is what survives even when an individual control is later changed or rolled back.

What "deny-by-default" means — and why it is dangerous to turn on

A deny-by-default control is one that rejects a request when a check fails, rather than letting it through. "Fail closed" is the same idea: if the control is unsure, the safe answer is no.

Fail-closed is usually the right posture for security. A door that locks when the power is cut protects what is behind it. But the exact property that makes the control protective is also what makes it dangerous to switch on: if the check is subtly wrong, a fail-closed control does not degrade quietly — it rejects. A control that rejects too much is not a security improvement; it is a self-inflicted outage. And because it is meant to reject, nothing about a wrong rejection looks like a failure from the inside.

That asymmetry sets the bar. Turning on a control that can say "no" to a customer is a higher-stakes action than shipping almost any feature, so it deserves a higher standard of proof than "we wrote it carefully and the tests pass."

The observe mode: log-only before reject

Our standard is that a deny-by-default control spends time in observe mode before it ever rejects anything.

In observe mode, the control runs on every single request and reaches a verdict — I would reject this one or I would allow this one — but it does not act on the verdict. It writes the decision down and lets the request through. Functionally, the control is fail-open: nothing is blocked, no customer is affected. What we get is a recording of exactly how the control would have behaved against real production traffic, at full volume, with none of the risk of actually enforcing.

Only after observe-mode evidence is clean do we consider flipping the same control to actually reject. The code path that decides "allow or reject" is the same in both modes; the only thing that changes is whether the verdict is acted on. That matters: it means the thing we observed is the thing we later enforce, not a near-relative of it.

The three things observe mode must prove

Observe mode is not just "leave it on for a while and glance at the logs." We require it to establish three specific things before a control earns the right to enforce.

1. Completeness — no request slipped past unevaluated. It is not enough that the control fired on the requests we happened to look at. We need confidence that it evaluated every path a request can take to reach us. We get that from a gapless count: the control numbers its evaluations, and we confirm the sequence has no holes. A gap is not a cosmetic problem — it means some requests reached the service without being evaluated at all, and on those paths an enforcing control would be making decisions blind. A control you are about to trust with rejections has to be proven complete first.

2. The control actually fires. A control that has been silent throughout observe mode is ambiguous: either nothing bad arrived, or the control is quietly broken and would never catch anything. "Quiet" is not the same as "working." So we deliberately send a known-bad request — one the control is supposed to reject — and confirm that, in observe mode, it would have rejected exactly that one. This turns a hopeful assumption into a positive test against the real running system. You do not want the first time a control fires for real to also be the first time you learn whether it can.

3. Zero false-positives on real traffic. Across a soak window of genuine customer traffic, the control must flag nothing legitimate. Not "almost nothing" — nothing. A single legitimate request marked for rejection in observe mode is a guaranteed customer rejection the moment we enforce, and that is a stop signal. When it happens, we do not enforce; we go and understand why the control disagreed with reality, fix the cause, and restart the window. The whole point of observing first is to convert "we are fairly sure this is safe" into "we watched it not reject a single real customer, at volume, for the entire window."

Only when all three hold do we move on.

The trap: an intentional denial is invisible to your error tracker

There is a subtle failure mode worth calling out, because it has misled careful teams.

Most production monitoring is built around exceptions — code that threw, a request that crashed, a dependency that timed out. A deny-by-default rejection is none of those things. When the control does its job and turns a request away, that is the control working, not an error. So it produces no exception, no stack trace, nothing for an ordinary error tracker to surface.

The consequence is counter-intuitive: after you enforce, your exception tracker can be completely quiet while the control is rejecting real customers. "The error tracker is green" tells you nothing about whether the control is turning away traffic it should not. Silence is not evidence of safety here — it is the absence of the one signal you actually need.

So a deny-by-default control needs its own explicit signal, separate from exception monitoring: a dedicated record of what it rejected and why, that an operator can read directly. Without that, you are flying on an instrument that is structurally blind to the exact thing you are worried about.

Only then: the flip to enforce — with a kill-switch

When the three proofs hold and the dedicated signal is in place, enforcing becomes a small, deliberate step rather than a leap. We treat the flip as exactly that: a conscious decision, made on the strength of the observe-mode evidence, never an automatic promotion that happens just because some time has passed.

We also keep the flip reversible. A control we have just begun enforcing can be returned to observe mode immediately if anything looks wrong, without a redeploy or a code change. That reversibility is part of the discipline, not an afterthought: we do not ship a control whose safety depends on a one-way door. The ability to step back instantly is what lets us enforce with confidence — and what lets the new posture bake under real traffic before we treat it as permanent.

What this looks like to regulators and buyers

Under GDPR Article 32 — security of processing — a controller must put in place appropriate technical and organisational measures to keep personal data secure, balanced against the risk to the people whose data it is. Availability is part of that balance: a measure that protects data by routinely making the service unavailable to legitimate users is not, on its own, an appropriate measure.

Observe-then-enforce is precisely the kind of organisational measure that keeps a protective control from tipping into a data-availability problem. It says, in effect: we will add controls that reject suspicious traffic, and we will prove on real traffic that they do not reject legitimate traffic before we let them act. That is the shape of a security practice that a regulator or an enterprise customer's audit can look at and find reasonable — not a guarantee that nothing will ever go wrong, but a documented, repeatable method for not turning a defensive control into an outage.

What this is not

  • Not a magic safety net. Observe mode proves the specific invariants we chose to check — completeness, that the control fires, no false-positives on the traffic we saw. It cannot prove the absence of a failure mode nobody thought to look for. As we learn new ones, we add them to what observe mode must establish.
  • Not unique to HumanKey. Watching a control before enforcing it — dark launches, shadow mode, canaries — is well-trodden engineering. What we are publishing is that we actually gate the flip on clean evidence, and treat "we reasoned it would be fine" as insufficient. That discipline is the part procurement teams find hard to verify from the outside.
  • Not a description of any one control. We have deliberately kept this post about the method. We do not name the specific control we most recently took through it, or how that control works, because publishing the mechanism of a live security control would weaken it — and the method is what is worth sharing anyway.

Reference points

  • GDPR Article 32 — Security of processing (appropriate technical and organisational measures, proportionate to risk, including availability)
  • Our Privacy Notice and DPIA describe the categories of data we process and the safeguards around them

HumanKey is an EU-based, GDPR-native analytics platform for publishers and e-commerce sites. Operator transparency posts cover the compliance and engineering choices that B2B buyers evaluate during procurement. This post reflects our operational practice and is not legal advice.

If you are evaluating HumanKey, our DPIA and the rest of our legal documentation are public. For a free trial, the snippet takes under two minutes to install.

Know Your AI Traffic

Start tracking AI crawlers visiting your website today. Free for up to 1,000 verifications per month.

Start Free Trial