skip to content

A team is deciding whether to let clients upload directly to object storage via pre-signed URLs, or keep proxying uploads through their application server. Name two concrete scenarios where proxying through the app server is the better choice, and explain why the Valet Key pattern falls short there.

level: seniorimportance: must knowfreq 55%

answer

  1. no inline scan without a proxy
  2. TOCTOU gap for quotas
  3. quarantine bucket as middle ground
  4. token frozen at issuance, storage can't call back

basics

~20 s

If you need to check, transform, or tightly control the file as it arrives, like scanning for viruses before it's stored or enforcing a quota that can change moment to moment, routing through your server lets you do that inline. Direct-to-storage uploads only let you react after the fact.

solid answer

~30 s

First, inline validation or transformation requirements: for example needing to virus-scan or reject malformed files synchronously before they're visible to other systems. Valet Key only allows post-hoc processing via storage events, introducing a race window between upload and scan. Second, fine-grained, request-time business authorization that can't be baked into a static token, such as enforcing a quota that can change between issuance and use, or per-request billing metering. The storage service can't evaluate app-specific business state at request time, only whatever coarse permissions were frozen into the token when it was issued.

go deeper

for a junior

Should be able to name one example, like virus scanning, where the app server needs to see the bytes.

for a middle

Should articulate both the inline-validation and the request-time-authorization gaps as distinct concerns.

for a senior

Should propose concrete mitigations, such as the quarantine-bucket pattern and short-TTL single-use tokens, rather than just naming the problem.

for a principal

Should frame the decision as a system-wide trade-off between infrastructure cost and control, and design a hybrid approach when neither pure choice fits.

## What the pattern optimizes for The Valet Key pattern optimizes for one thing very well: **removing the application server from the data path** of a storage transfer. That optimization comes at the direct cost of removing your application's ability to inspect, transform, or make request-time business decisions about the bytes as they move, because by design those bytes never pass through code you control. Two classes of requirement expose that cost clearly. ## Inline content validation or transformation The first is inline content validation or transformation. Consider a requirement that: - uploaded files must be virus-scanned before they're considered accepted, - or that an uploaded image must be resized or watermarked before it's usable, - or that a document must be validated against a schema before downstream systems trust it. With Valet Key, the client writes directly to storage; your application server never sees the bytes in flight, so it cannot reject a malicious upload before it lands, nor transform it inline. The only recourse is **post-hoc**: react to the object's arrival via a storage event notification, such as an S3 event triggering a Lambda or an Azure Blob trigger firing a Function, scan or transform it after the fact, and then either delete or quarantine it or move it somewhere the rest of the system trusts. That introduces a **race window**, since anything that reads directly from the upload location between the write and the scan completing sees unvalidated content, and adds asynchronous complexity such as: - retry logic, - dead-letter handling for failed scans, - and eventual-consistency handling for consumers. If the business requirement is that nothing unscanned is ever visible, proxying the upload through the app server, running validation synchronously, and only then writing to storage is simpler and closes that race entirely, at the cost of the app tier paying for the bandwidth and compute of every byte transferred. ## Request-time business authorization The second is request-time business authorization that depends on state the storage service has no way to evaluate. A pre-signed URL's permissions are **frozen at the moment it's issued**; the storage service only checks whether the signature matches and whether the request falls inside the time window, it doesn't call back into your application to ask whether this user is still under their storage quota right now, or whether their subscription was cancelled in the last thirty seconds. If your business rule needs to be evaluated at the moment of the actual transfer rather than at token-issuance time, Valet Key introduces a **time-of-check-to-time-of-use gap**: the token was valid when issued, but the business state it was predicated on may have changed by the time the client actually uses it, and nothing stops them from using it, possibly repeatedly if the scope allows multiple uses, up until expiry. Proxying every request through the app server lets you re-evaluate that business state on every single transfer, which is exactly the guarantee some domains require, such as: - metered billing per request, - hard real-time quota enforcement, - or per-transfer audit logging with business context attached. ## The middle ground None of this means Valet Key is wrong for these systems wholesale; it usually means picking a middle ground rather than an all-or-nothing choice. 1. A common compromise for the validation case is the **quarantine-bucket pattern**: uploads land in a bucket nothing downstream trusts by default, an event-driven scanner promotes clean files by copying or moving them into the trusted bucket, and consumers are pointed only at the trusted bucket, accepting a short propagation delay instead of full synchronous inspection. 2. For the business-authorization case, teams often keep tokens **single-use and short-TTL**, seconds to low minutes, so the time-of-check gap is small enough to be an acceptable risk, or they issue one token per logical operation rather than one reusable token per session, shrinking the gap between checked and used to something close to negligible. ## The broader principle The broader principle for choosing between the two designs is that Valet Key trades away inline, synchronous control over the data plane in exchange for taking the app tier's compute and bandwidth off the critical path of every transfer. When the business genuinely needs that inline control, because unscanned or unvalidated content is unacceptable even briefly, or because authorization must reflect state that can change between issuance and use, proxying through the app server, even at higher infrastructure cost, is the safer default. Valet Key earns its keep specifically when the transferred bytes are large, frequent, and don't need synchronous business logic applied to them.

  • If a team truly needs inline virus scanning but still wants to offload bandwidth, what compromise exists?
    The quarantine-bucket pattern: uploads land in an untrusted bucket, an event-triggered scan runs asynchronously, and only clean files get promoted or copied to the trusted bucket consumers actually read from, accepting a short not-yet-available window instead of full synchronous inspection.
  • How does the Valet Key pattern interact with per-user upload quotas that can change between requests?
    Quota is evaluated once at token-issue time, so there's a time-of-check-to-time-of-use gap: nothing stops the user from continuing to use a not-yet-expired token to write again beyond the intended count, unless the token is made single-use or issued with a very short TTL to shrink that window.
  • What's the operational cost difference between proxying and Valet Key at high upload volume?
    Proxying scales app-tier compute and bandwidth cost directly with traffic, while Valet Key shifts data-plane cost to the storage service and CDN, freeing app instances to only handle lightweight signing calls, which is usually cheaper and scales further, but at the cost of losing the ability to meter or inspect bytes as they pass.

Like a package locker at an apartment building: it's great for letting a courier drop off a box without a doorman checking every parcel, but if the building requires every package to be X-rayed before residents are notified it's ready, the locker system alone can't do that; you need someone physically inspecting it, which means going back to a staffed front desk for that specific requirement.

saying these in an interview costs you the question

  • Says direct-to-storage is always strictly better with no downsides
  • Doesn't recognize inline validation or transformation is impossible with Valet Key alone
  • Ignores the time-of-check-to-time-of-use gap for quota or business-state checks
  • Thinks a pre-signed URL can enforce arbitrary business logic at use-time

context