Hacker DirectoryHacker Directory

WEB / WEB-16.S03

Paths, upload, and download authorization

Follow distinct owners of display names, stored keys, owner policy, and response bodies.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Accepted upload

  1. Attachment intent ready

    The attachment intent is supplied: Alice; catalog.txt; text/plain; Tea. The principal is supplied context, not real login evidence. No operation I/O or consumer result has occurred yet.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    No policy decision
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  2. Operation-policy decision

    Supplied Alice context permits upload. catalog.txt is an approved display name; text/plain, three Tea bytes and strict UTF-8 pass. No write has run yet.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    Policy accepted
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  3. Storage-key and root selection

    The application selects new key asset-02.dat inside its root; display catalog.txt is not used as a path. Exclusive creation is for a separate file without overwriting asset-01.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    Mapped own storage root
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  4. Owned storage operation

    Tea bytes were written to new asset-02.dat: reads=0, writes=1. asset-01 bytes remain unchanged. This local write is not proof of a distributed disk/metadata transaction.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    Mapped own storage root
    Owned storage
    Reads=0; writes=1
    Consumer
    No result
  5. Operation result ready

    Completed upload metadata is ready with storedId=asset-02. Display catalog.txt remains separate; upload produces no download body or headers. Consumer update is the next local step.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    Mapped own storage root
    Owned storage
    Stored asset-02 metadata
    Consumer
    No result
  6. Consumer outcome completed

    The local consumer received new storedId=asset-02 metadata. Existing asset-01 remains unchanged; this upload outcome is not a download body, browser receipt or permission for another resource.

    Attachment intent
    Alice; catalog.txt; text/plain; Tea
    Policy gate
    Mapped own storage root
    Owned storage
    Stored asset-02 metadata
    Consumer
    Uploaded asset-02

Owner download

  1. Attachment intent ready

    The attachment intent is supplied: Alice; asset-01 download. The principal is supplied context, not real login evidence. No operation I/O or consumer result has occurred yet.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    No policy decision
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  2. Operation-policy decision

    Alice matches asset-01 metadata owner Alice. This finite resource policy admits the read; ID knowledge or filename alone grants no permission. The file has not been read yet.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    Policy accepted
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  3. Storage-key and root selection

    Metadata selects key asset-01.dat and its resolved parent matches the example root. Root checking differs from resource permission; the model adds no general race-free guarantee between resolve and open.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    Mapped own storage root
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  4. Owned storage operation

    Tea bytes were read from selected asset-01.dat: reads=1, writes=0. A body can be prepared now; the consumer has not used the result and browser delivery is not established.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    Mapped own storage root
    Owned storage
    Reads=1; writes=0
    Consumer
    No result
  5. Operation result ready

    The response record is ready with body=Tea, Content-Type text/plain; charset=utf-8 and attachment; filename="memo.txt". The header is presentation advice; the consumer has not received it and browser saving is unproven.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    Mapped own storage root
    Owned storage
    Approved Tea response record
    Consumer
    No result
  6. Consumer outcome completed

    The local consumer received Tea and approved download metadata. reads=1, writes=0 remain; no actual file-save outcome is inferred because this model runs no HTTP server/browser.

    Attachment intent
    Alice; asset-01 download
    Policy gate
    Mapped own storage root
    Owned storage
    Approved Tea response record
    Consumer
    Delivered Tea; reads=1

Denied download

  1. Attachment intent ready

    The attachment intent is supplied: Bob; asset-01 download. The principal is supplied context, not real login evidence. No operation I/O or consumer result has occurred yet.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    No policy decision
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  2. Operation-policy decision

    Bob does not match record owner Alice; resource-policy is rejected. This decision precedes storage operations; no file read or new write starts.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    Rejected: resource-policy
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  3. Storage-key and root selection

    The preceding policy rejection prevents storage mapping/root evaluation. No operation file is opened or created; initial metadata and bytes remain unchanged.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    Storage not evaluated
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  4. Owned storage operation

    The rejected operation retains reads=0 and writes=0. A separate inspection read does not count as I/O by the rejected download or upload.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    Storage not evaluated
    Owned storage
    Reads=0; writes=0
    Consumer
    No result
  5. Operation result ready

    No new storedId, body or headers are prepared. Rejection does not reuse an earlier Tea result as empty success; the consumer has not updated yet.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    Storage not evaluated
    Owned storage
    No body; no metadata change
    Consumer
    No result
  6. Consumer outcome completed

    The consumer shows resource-policy rejection: body=null, headers=null and no new metadata. No storage I/O ran; this local outcome is not an HTTP status or browser-download observation.

    Attachment intent
    Bob; asset-01 download
    Policy gate
    Storage not evaluated
    Owned storage
    No body; no metadata change
    Consumer
    No result; resource-policy

Media mismatch

  1. Attachment intent ready

    The attachment intent is supplied: Alice; catalog.txt; image/png; Tea. The principal is supplied context, not real login evidence. No operation I/O or consumer result has occurred yet.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    No policy decision
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  2. Operation-policy decision

    Declared image/png does not satisfy required text/plain; text-profile is rejected. This decision precedes storage operations; no file read or new write starts.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    Rejected: text-profile
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  3. Storage-key and root selection

    The preceding policy rejection prevents storage mapping/root evaluation. No operation file is opened or created; initial metadata and bytes remain unchanged.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    Storage not evaluated
    Owned storage
    Seed unchanged; no operation I/O
    Consumer
    No result
  4. Owned storage operation

    The rejected operation retains reads=0 and writes=0. A separate inspection read does not count as I/O by the rejected download or upload.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    Storage not evaluated
    Owned storage
    Reads=0; writes=0
    Consumer
    No result
  5. Operation result ready

    No new storedId, body or headers are prepared. Rejection does not reuse an earlier Tea result as empty success; the consumer has not updated yet.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    Storage not evaluated
    Owned storage
    No body; no metadata change
    Consumer
    No result
  6. Consumer outcome completed

    The consumer shows text-profile rejection: body=null, headers=null and no new metadata. No storage I/O ran; this local outcome is not an HTTP status or browser-download observation.

    Attachment intent
    Alice; catalog.txt; image/png; Tea
    Policy gate
    Storage not evaluated
    Owned storage
    No body; no metadata change
    Consumer
    No result; text-profile

ACTORS · STATE · DATA FLOW

Resource IDs, display filenames, and storage paths differ

Atlas keeps three names for a text attachment. asset-01 is the resource ID, memo.txt is a presented display filename, and asset-01.dat is the application’s own storage key. A client filename does not directly become a filesystem path. The download handler receives a resource ID, locates its metadata record, and chooses a path from that record. Opaque naming does not replace authorization; the relevant policy is still evaluated on each read.

The example’s local storage holds Tea bytes. Existing asset-01 stays unchanged; an accepted upload creates separate asset-02.dat. The display name catalog.txt is another metadata field. This mapping exposes why storage naming and HTTP presentation naming differ. Local file behavior does not establish the behavior of an object store, web-server alias, or shared volume.

A canonical path is not a permission decision

Python Path.resolve resolves symlinks in the own filesystem and produces an absolute path. Here public-link.dat points to asset-01.dat inside the same root: the lexical basename differs while the resolved target is the same file. Allowed-root decisions do not use a raw string prefix. The selected profile requires the resolved parent to equal the own root exactly; it does not support nested directories.

That check is separate from resource-owner policy. Even when Alice is permitted to read her asset, metadata accidentally pointing to catalog.txt in an own sibling directory causes storage-root rejection before the operation reads the file. The native fixture creates this ordinary incorrect mapping itself, without traversal input or an external file. It gives no general race-free guarantee between resolve and later open. Production file handles, directory ownership, and filesystem concurrency need additional design.

Upload admission includes more than a filename

This teaching profile accepts only memo.txt/catalog.txt display choices, declared text/plain, 1–16 bytes, and strict UTF-8 text. Supplied Alice context permits upload, while Bob causes no write. A declared image/png with ordinary Tea bytes stops at the text-profile gate. Content-Type is a client declaration; putting a value in a header does not prove that the bytes have the required format.

An accepted upload uses exclusive creation at a generated storage key rather than overwriting an existing resource with the same display filename. Metadata is prepared after writing bytes. Actual write/readback checks observe Tea and the asset-02 key, without claiming a distributed transaction across disk and metadata. Real upload services also need multipart parsing, authentication, CSRF policy, quarantine/scanning, storage quotas, and cleanup. No image/PDF/parser payload or malware sample is processed here.

Download permission precedes reading bytes

The download branch evaluates a finite policy between the supplied principal and metadata owner before reading a body. Alice is admitted for asset-01, the resolved storage root is checked, and Tea bytes are then read. Bob receives resource-policy rejection for the same known resource: reads=0, null body, and null headers. Successful resource lookup and delivery to a caller are separate facts.

A missing principal is NOT-COMPUTED; absent identity evidence does not become permission. An unknown asset ID also performs no read. A real endpoint’s disclosure policy across not-found/denied responses is a separate design choice; no HTTP status or timing is observed here. Identity aliases are fixed supplied context, not real login/session verification. Keeping that boundary explicit prevents the policy model from being presented as a working authorization infrastructure.

Content-Type and Content-Disposition have different roles

For an admitted download, the application selects text/plain; charset=utf-8 and attachment; filename="memo.txt" in a response record. Content-Type indicates the representation’s media type. Content-Disposition attachment suggests default save handling to a recipient; the filename is advisory rather than the recipient’s storage path or the server’s resource ID. Preparing a header does not establish that a browser actually saved the file.

The native check starts no HTTP server; headers are local typed records. ASCII display labels come from an approved fixed set. Arbitrary filename-header serialization, Unicode filename* interoperability, and MIME-sniffing behavior are not tested. Choosing a media type does not bypass download authorization; denied branches have neither header. Showing this artifact in the static site does not expose an actual download endpoint for these bytes.

Keep four stages of operation evidence separate

The artifact distinguishes intent, policy, storage I/O, and consumer outcome. Upload success produces writes=1 and a storedId, without a download body. Download success produces reads=1 and body Tea, without mutating the file. Media mismatch and denied read retain I/O count=0. The consumer changes only after a completed approved operation, so an earlier success cannot hide a new rejection.

Separate operation counts from reads used to verify the result. Reading an existing file for inspection does not mean the rejected-download function read it. Specify the expected Tea bytes, metadata keys, and new-file state separately for each branch. This keeps the operation’s result distinct from subsequent observation. Local file examples provide no general guarantee for arbitrary paths or OS isolation.

2. Red · Trust & Impact

Read every scenario without motion

Owner mismatch

  1. The requested file operation was selected

    Bob requests download of asset-01, owned by Alice. Knowing the asset ID does not grant read permission.

    Upload/download context
    case=denied
    Resource/format policy
    Gate not examined
    Storage/response boundary
    No I/O
  2. The authoritative consumer rule was separated

    The fixture uses supplied Alice-equals-owner policy, without actual authentication. Bob is a known mismatch, not a missing principal.

    Upload/download context
    case=denied
    Resource/format policy
    Known owner mismatch
    Storage/response boundary
    No I/O
  3. The first failing gate stopped before I/O

    Expected decision is REJECT with reason resource-policy. Metadata relationship checking occurs before reading file bytes.

    Upload/download context
    case=denied
    Resource/format policy
    Reason: resource-policy
    Storage/response boundary
    No I/O
  4. The negative I/O outcome was preserved

    reads=0, writes=0 and storedId=null remain. Denial is not shown as hiding a completed read/write; the operation does not proceed in this case.

    Upload/download context
    case=denied
    Resource/format policy
    No storage operation
    Storage/response boundary
    Reads=0; writes=0
  5. Body and header projection stayed closed

    body=null and headers=null form the negative consumer boundary. An attachment filename or response media type cannot create passage through the failed resource/profile gate.

    Upload/download context
    case=denied
    Resource/format policy
    REJECT
    Storage/response boundary
    No body or headers
  6. The denial scope was not generalized incorrectly

    The fixture shows owner mismatch; opaque IDs or UI links do not replace authorization. General root/race-hardening guarantees are not inferred from this record.

    Upload/download context
    case=denied
    Resource/format policy
    Known: failed consumer gate
    Storage/response boundary
    Known: I/O/body/header withheld

Media mismatch

  1. The requested file operation was selected

    Alice requests a text-profile upload with display name catalog.txt but declares media image/png. Client filename and media are neither storage keys nor accepted format.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    Gate not examined
    Storage/response boundary
    No I/O
  2. The authoritative consumer rule was separated

    The profile requires declaredMedia=text/plain and strict UTF-8 text. Even passing the media declaration cannot replace byte validation; this media gate already mismatches.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    Known text-profile mismatch
    Storage/response boundary
    No I/O
  3. The first failing gate stopped before I/O

    Expected decision is REJECT with reason text-profile. The upload stops at this profile boundary before storage writing starts.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    Reason: text-profile
    Storage/response boundary
    No I/O
  4. The negative I/O outcome was preserved

    reads=0, writes=0 and storedId=null remain. Denial is not shown as hiding a completed read/write; the operation does not proceed in this case.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    No storage operation
    Storage/response boundary
    Reads=0; writes=0
  5. Body and header projection stayed closed

    body=null and headers=null form the negative consumer boundary. An attachment filename or response media type cannot create passage through the failed resource/profile gate.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    REJECT
    Storage/response boundary
    No body or headers
  6. The denial scope was not generalized incorrectly

    The fixture shows declared-media mismatch; a text profile is not safety for every PDF/archive/media decoder. Other formats need their own validation and isolation contracts.

    Upload/download context
    case=media-mismatch
    Resource/format policy
    Known: failed consumer gate
    Storage/response boundary
    Known: I/O/body/header withheld

ASSUMPTION · BOUNDARY · CONTROL

Review metadata mapping alongside access decisions

In a file review, separate names influenced by the client from names selected by the backend. Display filename, resource ID, and actual storage key differ in the artifact. A UI link labeled memo.txt does not establish a disk path. Likewise, hard-to-guess asset IDs do not replace owner/resource policy; consider the read decision in every request context.

Rejection is measured beyond a text error. The actual function returns reads=0, no body/headers, and unchanged own existing bytes. An incorrect storage mapping stops at the root gate even when the owner is permitted. These failures differ: resource policy versus a storage boundary. A review should not combine them into a single not-found conclusion without stating its evidence.

Ordinary failures do not certify format safety

A declared-media mismatch shows upload admission taking effect. A text/plain declaration alone does not establish content safety; selected bytes are separately decoded as strict UTF-8. This profile is not an HTML, PDF, archive, or media-processing pipeline. Passing strings to another interpreter involves separate boundaries in the preceding interpretation and following isolation lessons.

The Path.resolve observation is narrow too. Resolving a symlink within the same root does not establish safe handling of concurrent filesystem changes or every possible path. The review is supported by the explicit relationship among owner aliases, key mappings, root policy, observed I/O, and consumer outcome. Concurrency and filesystem permissions outside that relationship require separate assessment.

3. Blue · Secure development & defense

Read every scenario without motion

Name mapping

  1. The download metadata was selected

    Seed resource id asset-01, storageKey asset-01.dat and displayName memo.txt are separate fields. These names establish different roles for the same file.

    File metadata observation
    Asset metadata
    Mapping/context review
    Mapping not examined
    Evidence conclusion
    No header/body outcome
  2. The resource-owner decision was read

    The download for principal Alice expects ACCEPT. This alias does not replace identity verification; it is a limited input under the profile’s owner-equality rule.

    File metadata observation
    Resource asset-01; owner Alice
    Mapping/context review
    Declared owner match
    Evidence conclusion
    No header/body outcome
  3. Storage and display names were compared

    The application-selected storage key is asset-01.dat. Download filename memo.txt is approved presentation metadata; recipients should not treat it as a server disk path.

    File metadata observation
    Storage: asset-01.dat
    Mapping/context review
    Display: memo.txt
    Evidence conclusion
    Distinct naming roles
  4. The response projection was read

    Expected body is Tea with Content-Type text/plain; charset=utf-8. Content-Disposition attachment; filename="memo.txt" is metadata, not read permission.

    File metadata observation
    Reads=1; writes=0
    Mapping/context review
    Selected text response
    Evidence conclusion
    Attachment presentation only
  5. The upload’s exclusive identity stayed separate

    The accepted upload produces storedId=asset-02, not an overwrite of seed asset-01. Display name catalog.txt is not a path converted into this new opaque storage key.

    File metadata observation
    Seed retained: asset-01
    Mapping/context review
    Upload separate: asset-02
    Evidence conclusion
    Display/storage mapping explicit
  6. The metadata conclusion stayed in scope

    The ledger shows I/O counts and header/body projection. Browser saving, actual object-store consistency and general filename-serializer safety need separate evidence.

    File metadata observation
    Known: distinct naming roles
    Mapping/context review
    Known: selected response projection
    Evidence conclusion
    Broader storage/browser behavior unknown

Missing principal

  1. The missing-principal scope was selected

    The scope starts with missing.principal=null. The known subject from the Bob-mismatch row is not inserted into this gap; trusted identity evidence is missing.

    File metadata observation
    Principal=null
    Mapping/context review
    Policy not computed
    Evidence conclusion
    No I/O/body
  2. The NOT-COMPUTED decision was read

    The decision is NOT-COMPUTED. Missing input establishes neither known owner denial nor existence/absence of an unknown resource.

    File metadata observation
    Principal=null
    Mapping/context review
    Decision NOT-COMPUTED
    Evidence conclusion
    No owner-attribution result
  3. Reads and writes were checked separately

    reads=0 and writes=0 remain. Failure to resolve a trusted principal does not justify storage processing or guessed Alice context.

    File metadata observation
    Missing identity evidence
    Mapping/context review
    No storage operation
    Evidence conclusion
    Reads=0; writes=0
  4. No response body was produced

    body=null remains. A public display name in metadata does not automatically expose file bytes to a consumer with missing principal evidence.

    File metadata observation
    Missing identity evidence
    Mapping/context review
    No accepted download
    Evidence conclusion
    Body=null
  5. A trusted-context source was requested

    A resource action needs server identity binding and owner-policy evidence. Client-supplied names or attachment headers cannot verify this missing context.

    File metadata observation
    Missing principal known
    Mapping/context review
    Trusted binding evidence required
    Evidence conclusion
    No guessed permission
  6. Unknown and hostile remained distinct

    The known outcome is no I/O and no body; the caller’s actual identity or permission outcome is unknown. A missing principal is not automatically evidence of malicious intent.

    File metadata observation
    Known: input missing
    Mapping/context review
    Known: not computed
    Evidence conclusion
    UNKNOWN: identity/permission

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Generate storage keys and authorize before reads

Use an approved application key mapping rather than reusing client filenames as storage identifiers. The fixed generated asset-02 key differs from existing asset-01; exclusive creation prevents overwriting existing bytes. Download metadata-owner policy runs before reading a body. Root checking remains a separate storage responsibility, so successful authorization does not legitimize a wrong mapping.

Production identity evidence must come from trusted server context; static Alice does not test it. Upload admission, storage commit, metadata publication, and serving policies also need failure/cleanup plans. This artifact covers ordinary text and finite context decisions only. Reduced motion preserves no-body rejection and completed read/write counts for the consumer.

Include headers and format policy in regression evidence

Do not treat an upload declaration as the sole proof of byte format. Record admitted-format validation, byte budgets, and storage naming together. Download metadata should select the right media type and an approved safe display name; recipients should not trust advisory filenames as storage-path instructions. Attachment handling does not replace authorization. The header check here is neither a browser-save nor a general serializer test.

Specify expected I/O and outcomes separately for accepted upload, admitted read, denied read, and media-mismatched upload. Keep unknown resources distinct from missing principals. Operation counters exclude reads made to verify the result. Streaming limits, MIME sniffing, malware scanning, object-store consistency, and filesystem races lie outside this local text profile. A successful control does not establish those additional responsibilities.

NOW APPLY IT TO THE CASE

At which gate must upload/download withhold I/O?

The application generates storage keys while display metadata remains separate. Negative resource-policy and text-profile branches produce no reads, writes, body or headers.

Separate decisions for verified actor, tenant relation and requested action in the case. Do not substitute authentication or proof success for object permission.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas text attachment responsibility ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "profile": {
    "displayNames": [
      "memo.txt",
      "catalog.txt"
    ],
    "declaredMedia": "text/plain",
    "byteRange": [
      1,
      16
    ],
    "contentValidation": "strict UTF-8 text",
    "storageKeys": "application-generated opaque IDs",
    "rootRule": "resolved parent equals own root; no nested dirs",
    "ownerPolicy": "supplied Alice equals record owner; no real authentication"
  },
  "seed": {
    "id": "asset-01",
    "owner": "Alice",
    "storageKey": "asset-01.dat",
    "displayName": "memo.txt",
    "bytesHex": "546561"
  },
  "inputs": {
    "upload": {
      "principal": "Alice",
      "display": "catalog.txt",
      "media": "text/plain",
      "bytesHex": "546561"
    },
    "download": {
      "principal": "Alice",
      "resourceId": "asset-01"
    },
    "denied": {
      "principal": "Bob",
      "resourceId": "asset-01"
    },
    "media-mismatch": {
      "principal": "Alice",
      "display": "catalog.txt",
      "media": "image/png",
      "bytesHex": "546561"
    }
  },
  "expected": {
    "upload": {
      "decision": "ACCEPT",
      "reason": "stored-text",
      "reads": 0,
      "writes": 1,
      "storedId": "asset-02",
      "body": null,
      "headers": null
    },
    "download": {
      "decision": "ACCEPT",
      "reason": "delivered-text",
      "reads": 1,
      "writes": 0,
      "storedId": "asset-01",
      "body": "Tea",
      "headers": {
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Disposition": "attachment; filename=\"memo.txt\""
      }
    },
    "denied": {
      "decision": "REJECT",
      "reason": "resource-policy",
      "reads": 0,
      "writes": 0,
      "storedId": null,
      "body": null,
      "headers": null
    },
    "media-mismatch": {
      "decision": "REJECT",
      "reason": "text-profile",
      "reads": 0,
      "writes": 0,
      "storedId": null,
      "body": null,
      "headers": null
    }
  },
  "missing": {
    "principal": null,
    "decision": "NOT-COMPUTED",
    "reads": 0,
    "writes": 0,
    "body": null
  }
}
seed / inputs
Own ordinary text and supplied identity aliases; opaque IDs, paths, and displays differ.
reads / writes
Operation I/O counts, separate from proof inspection.
storedId / body
Upload metadata differs from completed download delivery.
headers
Approved local response record, not actual HTTP/browser execution.

Own auto-cleaned local text files and finite supplied-context policy; actual Path.resolve/internal symlink. No HTTP/browser, real identity/tenant, arbitrary paths/traversal, OS-race isolation, scanning, or cloud verification.

Two reality checks

An opaque asset ID or canonical path establishes permission.

ID/path resolution and caller-resource policy make distinct decisions.

Content-Type and attachment establish complete file safety.

Byte validation, storage policy, authorization, and recipient handling are different boundaries.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

Bob requests asset-01, but Alice owns the record. Is the file read or a body prepared?

  1. No. reads=0, writes=0 and body=null.
  2. Yes. Any existing resource ID is a public download for every principal.
Read the explained answer

No. reads=0, writes=0 and body=null. — The resource-policy rejection applies before storage reads. Knowing the resource ID does not grant download permission.

Why are the memo.txt display name and asset-01.dat storage key separate?

Selected lesson artifact fields; teaching example

seed.id
asset-01
seed.storageKey
asset-01.dat
seed.displayName
memo.txt
expected.download.headers
{"Content-Type":"text/plain; charset=utf-8","Content-Disposition":"attachment; filename=\"memo.txt\""}
  1. The filename in Content-Disposition determines the entire filesystem path.
  2. The display name is presentation; the application chooses the storage key.
Read the explained answer

The display name is presentation; the application chooses the storage key. — The attachment header presents memo.txt while the backing key remains asset-01.dat. A client display name grants no filesystem-path authority.

Tea bytes labelled image/png are rejected by text-profile. Why are content validation and owner policy separate, and what happens with a missing principal?

Read the explained answer

This narrow upload contract requires text/plain, a byte range and strict UTF-8. Acceptable content does not grant the principal resource permission. The application generates the storage key and separately restricts root mapping. Missing principal yields NOT-COMPUTED with no reads, writes or body. This text-only example is no guarantee for every file type or real authentication.

□ I separated content validation from owner permission.

□ I did not turn missing principal into automatic allow or hostile attribution.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope