Authority Placement: Control Layers and Enforcement Boundaries
#Infrastructure

Authority Placement: Control Layers and Enforcement Boundaries

Backend Reporter
6 min read

A Kong gateway plugin that rejects API requests violating contract rules before they reach upstream services illustrates a fundamental distributed systems principle: enforcement must be placed at the correct layer to provide meaningful control. The distinction between stopping invalid actions before execution versus reporting failures after the fact determines system reliability, auditability, and failure modes.

The Gateway Plugin Example

A Kong gateway plugin was implemented to reject API requests violating a contract rule (len(values) ≤ n) before they reach upstream services. Enforcement is placed at the gateway layer, preventing invalid requests from entering downstream execution paths. This simple example reveals a deeper architectural pattern about where authority should reside in distributed systems.

The Control Layer Principle

In distributed systems, enforcement can occur at multiple layers. The critical distinction is whether enforcement prevents execution or reports failure after the fact. A control layer is one where invalid actions are stopped before execution. This differs from validation layers, which detect violations after the action has been attempted and report the failure.

The invariant: Enforcement placed after execution is reporting, not control. Control answers: "May this action proceed?" Validation answers: "Was this action invalid?" These questions are not interchangeable. Systems that conflate them accumulate hidden failure modes. This reflects an upstream control-layer denial pattern, where authority is exercised before execution rather than delegated to downstream validation.

Where This Pattern Holds

This pattern applies when:

The contract is decidable at the boundary. The gateway has sufficient information to make the enforcement decision without calling downstream services. For the len(values) ≤ n example, the gateway can count array elements without consulting any database or business logic. The decision is purely syntactic and available in the request itself.

Prevention is cheaper than cleanup. Stopping an invalid request costs less than processing it through multiple layers, then rolling back or handling exceptions. Consider a request that would violate database constraints: rejecting it at the gateway saves database CPU, network round trips, transaction overhead, and potential rollback complexity. The cost difference is often orders of magnitude.

Authority must be explicit. The system requires auditable proof that invalid actions were denied before execution, not discovered during execution. Gateway logs provide clear evidence: "Request ID 12345 rejected at 14:32:01 for violating contract rule X." This audit trail is impossible when validation occurs downstream because the request never reaches the point of failure detection.

Where This Pattern Breaks

This pattern fails when:

The rule requires downstream context. If enforcement depends on database state, current load, or business logic deep in the application, the gateway cannot make the decision. For example, "user has remaining quota" requires querying a database. "Request rate is below current capacity" requires monitoring system state. These decisions belong downstream where the context exists.

The contract is dynamic per-request. User-specific limits, learned rules, or contextual constraints require more than static configuration at the gateway. A machine learning model that predicts fraud risk for each request cannot be implemented at the gateway layer. The model's parameters and training data reside in specialized services.

Upstream services disagree about constraints. When the gateway enforces one limit but downstream services can handle more, the control layer creates artificial restrictions. Imagine a gateway enforcing a 100KB request size limit, but the upstream service can handle 1MB. The gateway becomes a bottleneck, forcing all clients to conform to the lowest common denominator.

Trade-Offs and System Design

Moving enforcement upstream trades flexibility for authority. The gateway becomes a hard boundary. It prevents invalid actions but cannot negotiate, adapt, or reason about context. This is acceptable when contracts are simple and universal. It becomes a liability when contracts are complex and contextual.

The common mistake is not choosing one approach over the other, but assuming downstream validation provides the same guarantees as upstream control. Consider these scenarios:

Scenario 1: Rate Limiting

  • Upstream control: Gateway rejects requests exceeding rate limit. Clean, auditable, prevents resource exhaustion.
  • Downstream validation: Service processes request, discovers rate limit violation, returns error. Request consumed resources (CPU, memory, network) before rejection.

Scenario 2: Input Validation

  • Upstream control: Gateway validates JSON schema, rejects malformed requests. Prevents parsing errors in downstream services.
  • Downstream validation: Service attempts to parse JSON, fails, logs error. Potential for inconsistent error handling across services.

Scenario 3: Business Rules

  • Upstream control: Gateway enforces "all requests must include API key." Simple, universal rule.
  • Downstream validation: Each service checks for API key. Duplication of logic, potential for inconsistent enforcement.

Implementation Patterns

When implementing upstream control layers, consider these patterns:

Circuit Breakers as Control Layers Circuit breakers represent upstream control for failure modes. They prevent requests from reaching unhealthy services. The circuit breaker state (open, closed, half-open) determines whether the action may proceed. This is control, not validation.

API Gateways as Policy Enforcement Points API gateways naturally serve as control layers for cross-cutting concerns: authentication, authorization, rate limiting, request/response transformation. These are policies that must be enforced before request processing begins.

Load Balancers as Control Layers Load balancers control which backend server receives a request based on health checks and routing algorithms. They prevent requests from reaching unhealthy instances.

When to Use Downstream Validation

Downstream validation remains essential for:

Context-Dependent Rules Business rules that require database state, user history, or real-time calculations. Example: "User has not exceeded monthly spending limit" requires querying transaction history.

Complex Validation Logic Validation that requires multiple service calls or complex computations. Example: "Order total is within fraud risk threshold" requires fraud detection service.

Service-Specific Constraints Constraints that only apply to specific services. Example: A document service may enforce different size limits than an image service.

The Hybrid Approach

Most systems benefit from a hybrid approach:

  1. Gateway Layer: Enforce universal, simple, decidable rules (authentication, rate limiting, basic input validation)
  2. Service Layer: Enforce context-dependent, complex rules (business logic, data integrity, domain-specific constraints)
  3. Database Layer: Enforce data integrity constraints (unique keys, foreign keys, data types)

Each layer enforces what it can decide with available context. The gateway handles what it knows; services handle what they know; databases handle what they guarantee.

Monitoring and Observability

Control layers provide superior observability. When enforcement happens upstream:

  • Clear audit trails: Gateway logs show exactly why requests were rejected
  • Consistent error responses: Single point of failure handling
  • Resource protection: Downstream services see only valid requests
  • Performance metrics: Rejection rates are measurable at the boundary

Downstream validation obscures these metrics. Failed requests consume resources before rejection, making it harder to distinguish between legitimate traffic and attacks.

Conclusion

The choice between upstream control and downstream validation is not about which is "better," but about matching enforcement to the decision's nature. Simple, universal, decidable rules belong at the gateway. Complex, contextual, service-specific rules belong downstream.

The critical insight is that these are fundamentally different questions. "May this action proceed?" requires control at the boundary. "Was this action invalid?" requires validation after execution. Systems that conflate these questions accumulate hidden failure modes, inconsistent behavior, and auditability gaps.

The Kong gateway plugin example demonstrates upstream control done right: a simple, decidable rule enforced at the boundary before any downstream processing begins. This pattern, when applied appropriately, creates systems that are more reliable, auditable, and efficient.


References and Further Reading:

Featured image

Build seamlessly, securely, and flexibly with MongoDB Atlas. Try free.

pic

Comments

Loading comments...