Fail-closed or fail-open? Decide per side effect, then check what your cache already decided
Fail-closed: when something a decision depends on is unavailable, the answer is no. Fail-open: the answer is yes. Fail-bounded: the answer is yes, inside a limit that does not need the missing dependency. "Fail-closed or fail-open" is the wrong question at the scale of a service. Ask it per dependency and per kind of request. And before you answer, check your cache client: ours was configured to…
Failure modes can be categorized as fail-closed, fail-open, or fail-bounded. Fail-closed means that when a dependency is unavailable, the system returns a negative response. Fail-open implies that when a dependency is missing, the system returns a positive response. Fail-bounded means that the system returns a positive response within certain limits, without relying on the missing dependency.
It is essential to consider each dependency and request type separately rather than adopting a one-size-fits-all approach. A direct quote from the source material is "fail securely," which translates to always closed in this context.
In the example provided, the cache client was configured to swallow errors, leading to a fail-open situation. This configuration turned any security decision built on the cache into an open mode without anyone realizing it.
The third definition, fail-bounded, does not have a standard name but is the most commonly used in this scenario. For instance, a weather widget's functionality may depend on a cache, and a cache outage would impact all apps running the widget.
The key to making the right decision lies in understanding the side effect of each dependency. A read-only connector should register as side-effecting, allowing the system to apply the appropriate settings. In the example, the proxy behind the table settles the question of fail-bounded behavior by checking the side_effecting flag and applying the appropriate column.
When a dependency becomes unavailable, the system should act accordingly based on the side effect. For instance, a read-only connector with a missing key should return a fail-closed response, while a side-effecting connector with a missing key should return a fail-open response.
In the case where the kill switch is unavailable, it is crucial to have a fail-bounded approach, as the kill switch lives in the primary database and is read on every request. The first row of the table has no nuance, as a signature that cannot be checked is not valid, regardless of the request.
In summary, the decision-making process should be based on per-dependency and per-request type considerations, with fail-bounded being the most appropriate approach when dealing with missing dependencies.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.