Published on
·6 min read

Securing your Backend APIs for external resources

Authors

Exposing APIs to external vendors or third-party applications introduces a non-trivial attack surface that requires careful architectural consideration. The security boundary between your internal cluster and external consumers demands rigorous design principles to maintain confidentiality, integrity, and availability guarantees.

Drawing from several years of building fintech systems where data sensitivity is paramount, I've distilled a set of architectural patterns that provide strong security guarantees while maintaining system composability. This discussion assumes baseline transport security (TLS 1.3, certificate pinning) and focuses on application-layer security primitives.

Cryptographically Signed URLs for Resource Authentication

Signed URLs provide a stateless authentication mechanism where access credentials are embedded directly in the URL through cryptographic signatures. The general construction follows:

SignedURL=BaseURLResourcePathParamsSignature\text{SignedURL} = \text{BaseURL} \parallel \text{ResourcePath} \parallel \text{Params} \parallel \text{Signature}

Where the signature is computed as:

Signature=HMAC-SHA256(k,m)\text{Signature} = \text{HMAC-SHA256}(k, m)

Here, kk represents the secret signing key and mm is the canonical message constructed from the request parameters (resource path, expiration timestamp, allowed operations).

The verification complexity is O(1)O(1) with respect to the number of previously issued URLs, making this approach highly scalable compared to session-based alternatives that require O(logn)O(\log n) or O(n)O(n) lookups.

A typical implementation includes:

  • Expiration timestamp (texpt_{exp}): Enforces temporal bounds on URL validity
  • Resource scope: Limits access to specific object paths
  • Operation constraints: Restricts HTTP methods (GET, PUT, DELETE)
  • Client binding: Optional IP address or user-agent restrictions

Ensure comprehensive audit logging by persisting signature generation events with the tuple (tgen,resource,principal,texp,client_metadata)(t_{gen}, \text{resource}, \text{principal}, t_{exp}, \text{client\_metadata}) to enable forensic analysis and access pattern monitoring.

Event-Driven Architecture: Receive Events, Not Data

Rather than accepting raw data payloads, design your external APIs to receive semantic events that trigger internal data processing pipelines. This pattern provides several formal guarantees:

Separation of Concerns: Let EE be the set of external events and DD be your internal data domain. Define a mapping function:

f:EDf: E \rightarrow D

This function ff executes within your trust boundary, allowing you to enforce invariants, apply transformations, and validate constraints before data enters your persistence layer.

Reduced Attack Surface: The external API contract becomes:

APIext:E{200,202,400,401,403}\text{API}_{ext}: E \rightarrow \{200, 202, 400, 401, 403\}

External consumers only observe acknowledgment responses, with no visibility into internal state or processing logic.

Asynchronous Processing: Events can be queued with guaranteed delivery semantics. For a message queue with replication factor rr and acknowledgment requirement ww:

Durability={Strongif wr/2+1Weakotherwise\text{Durability} = \begin{cases} \text{Strong} & \text{if } w \geq \lfloor r/2 \rfloor + 1 \\ \text{Weak} & \text{otherwise} \end{cases}
aaaa

This architecture enables horizontal scaling of event processors independently from the API gateway layer, with each component maintaining single-responsibility semantics.

Referential Transparency in Request Handlers

Implement request handlers as pure functions to achieve deterministic, testable, and cacheable behavior. A function ff exhibits referential transparency if:

x:f(x)=f(x)\forall x: f(x) = f(x)

In practical terms, given identical request parameters, the handler produces identical outputs without observable side effects during computation.

Benefits for Security:

  1. Memoization for Audit Trails: Pure functions enable caching of computation results indexed by request hash:

    Cache:Hash(Request)Response\text{Cache}: \text{Hash}(\text{Request}) \rightarrow \text{Response}

    Cache hits provide implicit replay detection with O(1)O(1) lookup complexity.

  2. Deterministic Testing: Security invariants can be formally verified through property-based testing since f(x)f(x) is independent of execution context.

  3. Parallelization: Pure handlers can process concurrent requests without synchronization primitives, eliminating race conditions:

    Throughput=nThroughputsingle\text{Throughput} = n \cdot \text{Throughput}_{single}

    where nn is the number of parallel workers (assuming no shared mutable state).

Rate Limiting with Formal Guarantees

Rate limiting protects against denial-of-service attacks and resource exhaustion. Two primary algorithms provide different trade-off profiles:

Token Bucket Algorithm

Tokens accumulate at rate rr tokens/second up to bucket capacity bb. Each request consumes one token. Let T(t)T(t) denote tokens available at time tt:

T(t)=min(b,T(t0)+r(tt0))T(t) = \min(b, T(t_0) + r \cdot (t - t_0))

A request at time tt is admitted iff T(t)1T(t) \geq 1.

Properties:

  • Allows bursts up to bb requests
  • Sustained rate converges to rr requests/second
  • Space complexity: O(1)O(1) per client

Generic Cell Rate Algorithm (GCRA)

GCRA maintains a Theoretical Arrival Time (TAT) representing when the next request should ideally arrive. For emission interval τ\tau and limit interval TT:

TATnew=max(TATold,tarrival)+τ\text{TAT}_{new} = \max(\text{TAT}_{old}, t_{arrival}) + \tau

Request is allowed iff:

TATnewtarrivalT\text{TAT}_{new} - t_{arrival} \leq T

This provides smoother rate enforcement compared to token bucket, with identical O(1)O(1) space complexity.

For distributed systems, implement rate limiting at the edge (API gateway) with consistent hashing to route client requests to specific rate limiter instances, avoiding the need for distributed state synchronization.

References and Further Reading