A financial platform's policy service fails in three regions for twenty minutes. APIs include reading account balances, initiating transfers, retrieving public product information and requesting password resets. Propose a degraded behavior matrix and recovery procedure with measurable security limits.
Capacity, Isolation & Operations · Staff
The policy service is down. Should the gateway let everyone through?
Who Gets In When the API Is Full? · Part 6 of 6 · 5 min read
Read the worked explanation ↓Think first
A financial platform's policy service fails in three regions for twenty minutes. APIs include reading account balances, initiating transfers, retrieving public product information and requesting password resets. Propose a degraded behavior matrix and recovery procedure with measurable security limits.
Take a few minutes to form an approach, then compare it with the worked explanation.
Reveal the worked explanation
Interview question. A gateway depends on authentication, an external rate limiter, fraud scoring and feature flags. At 10:15 the shared policy service becomes unreachable. Some requests could continue without it, while others could create financial loss or expose private data. Choose fail-open or fail-closed behavior per decision, and design recovery without turning one dependency failure into a platform outage.
The outage begins with a chart that seems simple: policy RPC success falls to zero. An engineer proposes a single emergency switch, skip_policy_checks=true. That would make most of the API available again. It could also allow unauthorized account reads, let an attacker bypass abusive-traffic limits, or approve payments the risk team would never have permitted. Saying “availability is important” does not decide whether an unknown security decision should be treated as allowed. We need to name each policy, the harm of a wrong decision, and what evidence remains trustworthy when its dependency fails.
Start with authentication. If the gateway already possesses a trusted public key and enough verified claims to validate a signed access token locally, an identity service outage need not prevent every request. Local verification still checks the signature, expiry, issuer, intended audience and relevant claims. It does not automatically know about a token revoked five seconds ago, an emergency account suspension, or a missing authorization rule. The documented contract may permit cached verification for a short interval, especially for low-risk reads, while high-risk changes require a fresher decision. If no trustworthy credential or policy material is available, an unauthenticated write must not be admitted by default.
Rate limiting is different. If the global limiter is unavailable, refusing every harmless API read could take down a service whose business logic is healthy. Some routes can continue under a conservative local token bucket with a per-identity cap. Expensive exports might be denied or given a very small allowance. Account-login and password-reset flows need stronger protection against abuse, possibly with local emergency rules or edge mitigation that does not rely on the failed service. Calling that “fail open” hides the actual design. It is usually a bounded degraded policy with explicit blast-radius limits.
Fraud checks deserve their own decision. Suppose a retailer handles fifty thousand checkout requests a minute during a major sale. Fraud scoring is unreachable. Allowing every high-value order could turn a resilience incident into irreversible financial loss. Blocking every small purchase might create unacceptable customer harm, too. The product and risk teams should decide beforehand which transaction amounts, identities, regions and payment methods may continue under a known fallback. For some transactions, authorize but hold fulfillment, or route to manual review. For others, stop. The fallback must respect regulatory requirements, and it must not invent a positive fraud score merely because the scoring service timed out.
Feature flags are another category. For a cosmetic layout choice, a locally cached value or a safe default may be adequate. For a kill switch disabling a vulnerable money-transfer path, an expired cached “on” value could be dangerous. Treat safety-critical flags as policy controls with freshness requirements, versioning and explicit invalidation behavior. A flag service is a control plane. The data plane should not need a fresh remote lookup for every harmless branch, but stale configuration cannot grant arbitrary permission forever.
Now design the request path. Tag each policy evaluation with a type, risk class, maximum tolerated staleness and failure mode. Evaluation has a bounded deadline and a separate result for ALLOW, DENY and UNAVAILABLE. Do not collapse UNAVAILABLE into DENY or ALLOW without an explicit rule. If multiple policies apply, a local allow from one cannot override a mandatory deny from another. Keep authenticated identity binding on policy caches so that a cached result for tenant A cannot be reused for tenant B. Do not trust caller-provided headers to select the relaxed policy class.
The HTTP response should reflect what actually happened. A user failing authorization may get 403, or 401 if valid authentication is missing. A user who exceeded a known quota may receive 429. If the server cannot perform a required policy decision because an internal dependency is unavailable, an appropriate 503 may be more honest than pretending the user exceeded their quota. Avoid leaking details of the security policy in public error messages. For permitted degraded execution, record that the request passed under the specific fallback policy version so later audits can distinguish it from a fully checked decision.
Failover also creates recovery risks. When the global rate limiter returns, don't replace every locally spent allowance with a fresh full bucket. Reconcile metering where possible and keep explicit uncertainty in accounting. When fraud scoring returns, process held decisions before shipping goods, according to the product's stated contractual obligations. When revocation data becomes fresh again, invalidate affected cache entries and recheck sensitive sessions. Policy versions should roll out atomically enough that half the fleet does not enforce contradictory emergency rules.
I would rehearse this outage in a staging environment and in narrowly scoped production experiments. Disconnect the policy service while sending legitimate read traffic, a revoked token, expensive write bursts, suspicious high-value payments and emergency feature-flag updates. Verify which operations remain available, which stop, how fallback allowance decays, and whether the system recovers without synchronized retries. Measure allowed-by-fallback decisions, denied-by-risk decisions, policy staleness, revalidation work, audit completion and customer-visible errors.
The strongest interview answer refuses the false binary. Fail open and fail closed are meaningful shorthand only after naming what is being allowed, whose risk matters and which safeguards remain. One policy service can fail, but it should not be allowed to decide, by accident, the security and availability posture of every product operation.
Go deeper
Some policy systems use a remote authorization filter with a configurable failure mode. Even when the proxy has a convenient failure_mode_allow flag, the application remains responsible for domain-specific permissions that require fresh object state. An emergency bypass must be narrowly scoped, short-lived, logged, independently authorized and readily reversible. Think about session revocation and delegated credentials separately from JWT signature verification. For writes with irreversible effects, safety often requires a durable pending state rather than direct allow or deny.
Check your reasoning
- Separate authentication verification from revocation and object authorization.
- Distinguish ALLOW, DENY and UNAVAILABLE with policy-specific fallbacks.
- Define local bounded rate protection, fraud holds and safety-flag freshness.
- Match HTTP errors and audits to what was actually decided, without leaking sensitive rules.
- Test service disconnection, stale policy, identity spoofing and recovery reconciliation.
Common mistake: If the shared policy service fails, the most available design is to bypass all security policy checks.
Read the answer explanation
Apply route-specific degraded behavior with freshness, scope, fallback limits and audit — The impact of missing fraud, auth, abuse protection and cosmetic flags differs. Unavailable is not the same as either allowed or exceeded quota.
Apply it elsewhere
A hospital appointment service depends on a third-party eligibility checker that becomes unreachable. Decide which actions can continue and how to distinguish provisional scheduling from final authorization without exposing patient information.
Compare your approach
Classify each dependency and data sensitivity, separate unknown from deny, set freshness and deadline requirements, bound local fallback, preserve domain authorization, give honest HTTP outcomes, and plan audit and reconciliation on recovery.
One more constraint
If a gateway verifies a signed JWT using a cached public key, does that guarantee the token has not been revoked since the key was cached?
Quick revision
Do not apply one fail-open rule to every policy. Local JWT verification may continue while revocation freshness is bounded, but unknown authorization must not silently become permission. Rate limits can degrade to conservative local budgets for suitable routes. Fraud can require a risk-based hold or denial, and safety-critical flags need freshness constraints. Model ALLOW, DENY and UNAVAILABLE separately. Log fallback decisions and reconcile them during recovery.