امنیت، هویت، استقرار و تاب‌آوری · فصل ۴ — Linux/Windows، Container، DNS، CDN و Storage · 100

S3 Object Storage, Presigned URLs and Multipart Uploads

Design a bounded S3-style object-upload path that separates storage identity, signer authority, presigned operation/key/expiry, browser transport concerns, single PUT versus multipart lifecycle, part retry/completion/abort evidence and final application verification. می‌تواند برای «S3 Object Storage, Presigned URL و Multipart» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

S3 Object Storage، Presigned URL و Multipart — fa-IR

Lesson summary

Design a bounded S3-style object-upload path that separates storage identity, signer authority, presigned operation/key/expiry, browser transport concerns, single PUT versus multipart lifecycle, part retry/completion/abort evidence and final application verification.

می‌تواند برای «S3 Object Storage, Presigned URL و Multipart» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

This lesson produces

می‌تواند برای «S3 Object Storage, Presigned URL و Multipart» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

Who it is for

Foundation

Walk through one fake PUT signature and one three-part upload ledger, explicitly labeling signer, key, expiry, upload-id and part state.

Repair

Hold bucket and payload constant while changing exactly one authorization or multipart variable—method, key, expiry, part number or completion set—to isolate the failure.

Experienced

Start from an incomplete upload ledger and restrictive signer policy; require the learner to design retry, abort and acceptance behavior without a presign recipe.

Prerequisites

1. The problem: “upload succeeded” is not one conclusion

An object-upload path usually contains several distinct layers: bucket/key identity, signer authority, the presigned request, browser/CORS behavior, transfer method, multipart state, final storage, and application acceptance. Collapsing them into one green/red status hides both cause and security boundaries.

The owned artifact is Object Upload Access and Multipart Evidence Record v1. It keeps authorization, transport, transfer lifecycle, and application acceptance separate.

2. Object storage and object identity

In object storage, an object is normally addressed by bucket and object key. A key is not merely a display filename; it is part of the namespace and often part of access policy. Metadata may also affect application behavior, but storage identity and business identity are not interchangeable.

Record the bucket, key, required metadata, and responsible actor explicitly. Similar filenames are not proof of the same storage target.

3. What a presigned URL is

In Amazon S3, a presigned URL grants time-limited access to an object operation without exposing the original credentials to the caller. Its effective authority comes from the principal that generated it; the URL does not create permissions beyond the signer boundary.

Treat presigning as a bounded capability: operation, bucket/key, and expiry must match the actual job.

4. Signer authority and least scope

If the signer has broad permissions, presigned requests are generated within that broad boundary. A safer design gives the signer only the prefix, operations, and resources required for the workflow.

Record signer_principal and allowed prefix/operation separately from the URL. A working URL does not prove least privilege.

5. Method and object key must match the capability

A URL signed for PUT against one key should not be assumed valid for a different method or key. In the local fixture, changing method or key without re-signing creates a binding mismatch.

Analyze this separately from expiry: a request can be time-valid yet fail operation/key binding.

6. Expiry is an authorization boundary

Presigned URLs are time-bounded. After the validity window, diagnose the failure first as an authorization-time issue rather than inferring object deletion or a network outage.

One lab case replays after expiry. The bounded conclusion is AUTH_EXPIRED, not “file missing” or “storage down.”

7. CORS is not authorization

CORS is a browser transport policy. A request may be storage-authorized while a browser blocks it because of CORS. Conversely, permissive CORS does not grant storage permission.

Keep cors_transport_boundary separate. If the same signed request remains valid outside the browser, the browser symptom does not invalidate the authorization model.

8. Single PUT or multipart: a workload decision

Single PUT is simpler and often sufficient for smaller workloads without resume needs. Multipart adds parallelism, independent part retry, and resumability, but also state and cleanup complexity.

Do not turn provider numbers into universal laws. AWS and R2 publish provider-specific guidance and limits that must be rechecked when they matter.

9. Multipart lifecycle: upload ID and part ledger

Multipart upload is managed with an upload ID and a set of numbered parts. Each part has its own transfer evidence; if one part fails, successful parts do not need to be retransmitted.

Record upload ID, part number, checksum/ETag or equivalent evidence, and retry history so recovery is deterministic.

10. Complete and Abort are different terminal actions

Until completion succeeds, uploaded parts are not the final assembled object. If the workflow will not continue, an explicit abort/cleanup decision is required; an abandoned multipart session remains open state.

A lab case intentionally remains incomplete so the learner must identify MULTIPART_ABORT_REQUIRED.

11. Storage completion is not application acceptance

An object can be stored successfully and still fail application checks such as checksum policy, media type, schema, malware scanning, or business rules. That rejection is not a transport failure.

The artifact therefore keeps stored_object_observation and application_acceptance as separate evidence.

12. R2 and the meaning of S3-compatible

Cloudflare R2 exposes S3-compatible APIs, but compatibility does not imply identical behavior in every feature. Current R2 documentation separately defines supported presigned operations, bearer-token handling, and upload-method constraints.

For provider-specific decisions, use that provider’s current documentation rather than copying an AWS assumption without verification.

13. Object Upload Access and Multipart Evidence Record v1

The record includes: bucket/key, signer scope, requested operation, signed constraints, issued/expiry time, authorization result, browser/CORS state, transfer method, upload ID, part state, retry evidence, complete/abort evidence, final object observation, application acceptance, inference, unknowns, and final decision.

This is a MAKNOW instructional synthesis, not a required AWS or Cloudflare form.

14. Lab and transfer

The lab is fully local and deterministic. Eight fixtures cover a valid single PUT, expiry, key mismatch, a CORS-only failure, multipart retry, an orphaned multipart upload, storage-complete-but-app-rejected, and a changed transfer with a new prefix/size/failed part.

In transfer, no token, key, expiry, or part decision from the first case may be copied; every state is recomputed from the changed evidence.

15. Sources, freshness, and claim limits

Current Amazon S3 documentation still describes presigned URLs as time-limited access using the signer’s credentials and multipart upload as independently uploaded parts with retry plus completion/abort semantics. Current Cloudflare R2 documentation treats presigned URLs as bearer tokens for specific operations and distinguishes upload methods by size, parallelism, resumability, and provider-specific limits.

These sources were rechecked on 2026-09-19 and are due for review on 2026-10-17. No provider-specific numeric limit is presented here as a universal object-storage rule.

Assessment

There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.

OPS-007-S1 retrieval

Explain why a presigned URL is a bounded capability rather than a public-bucket policy, naming signer scope, operation, key, and expiry.

lesson ✗AI ✗notes ✗

OPS-007-S2 application

For the supplied synthetic request, determine whether method/key/expiry authorize and whether browser CORS changes that authorization result.

lesson ✗AI ✗notes ✗

OPS-007-S3 diagnosis

Differentiate expired signature, wrong key binding, browser CORS failure, and a failed multipart part using discriminating evidence.

lesson ✗AI ✗notes ✗

OPS-007-S4 decision

Choose single PUT or multipart for a bounded workload and define retry, completion/abort, and cleanup evidence without claiming a universal threshold.

lesson ✗AI ✗notes ✗

OPS-007-S5 transfer

Rebuild the full access and multipart record for a changed key prefix, shorter expiry, larger object, and a different failed part.

lesson ✗AI ✗notes ✗
Assessment rubric
DimensionCriticalSufficient evidence
Presign authorityYesSigner scope, operation, key binding, and expiry are evaluated independently.
Transport boundaryYesBrowser CORS symptoms are kept separate from storage authorization.
Multipart lifecycleYesUpload ID, retained successful parts, retry, complete/abort, and cleanup are explicit.
Application acceptanceYesStored-object evidence is separated from application/business acceptance.
TransferYesChanged prefix, expiry, size, and failed part are recomputed from new evidence.

Failure: treating presign as public access, using CORS as authorization proof, restarting every multipart part without evidence, leaving incomplete uploads without a cleanup decision, or treating storage completion as business acceptance.

References & freshness

Amazon S3 — Download and upload objects with presigned URLs
·
Amazon S3 — Uploading an object using multipart upload
·
Amazon S3 multipart upload limits
·
Cloudflare R2 — Presigned URLs
·
Cloudflare R2 — Upload objects
·
MAKNOW instructional evidence design
·

Case studies

Lesson visuals

OPS007-V1

Lab files

Everything is local and synthetic. No AWS/Cloudflare account, real credential, external bucket, public endpoint, network egress, or real presigned link is used.

For each case produce eight states: storage_target_state, signer_authority_state, presign_binding_state, expiry_state, transport_boundary_state, transfer_method_state, multipart_lifecycle_state, and application_acceptance_state.

Rules:

  1. Evaluate signer scope, method/key binding, and expiry independently.
  2. CORS is a browser-transport fact, not storage authorization.
  3. Choose transfer method from the fixture workload; do not use one universal numeric threshold.
  4. For multipart, retain successful parts, retry only failed parts, and close with complete or abort/cleanup evidence.
  5. Storage completion is not application acceptance.
  6. The transfer case must be solved from its own prefix, expiry, size, and part ledger.

Run python -B run_checks.py for learner-visible structural checks. Hidden acceptance lives outside learner paths.

Lesson media & slides

MAKNOW_OPS-007_DECISION_EVIDENCE_TABLE_v1.0.0.svg
DECISION EVIDENCE TABLE v1.0.0.svg
MAKNOW_OPS-007_FAILURE_REPAIR_v1.0.0.svg
FAILURE REPAIR v1.0.0.svg
MAKNOW_OPS-007_PRIMARY_MODEL_v1.0.0.svg
PRIMARY MODEL v1.0.0.svg
MAKNOW_OPS-007_WORKED_EXAMPLE_v1.0.0.svg
WORKED EXAMPLE v1.0.0.svg

Teaching files (download)

XLSXObject Upload Access and Multipart Evidence Record v1 v1.0.0.xlsxTeaching files (download)
DOCXObject Upload Access and Multipart Evidence Record v1 WORKSHEET v1.0.0.docxTeaching files (download)
PDFObject Upload Access and Multipart Evidence Record v1 WORKSHEET v1.0.0.pdfTeaching files (download)