---
id: WF-COM-CAT-008
title: Download an entitled file
trigger: >-
  A buyer retrieves a purchased private file through a download grant. Limited access consumes capacity before
  the signed delivery link is returned.
product_area: commerce
module: catalog
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-CAT-009
crosses:
  - SVC-COM-CAT-catalog
idempotency: >-
  Limited access consumes once per file and request key. Omitting a key substitutes the request identity, so
  unrelated requests consume separately.
concurrency: >-
  The grant register serializes capacity consumption. Limited downloads for a holder and product draw from the
  register’s shared available balance.
hops:
  - 'n': 1
    actor_or_service: Catalog service to entitlements register
    action: Resolve the download grant and require its owner or a supporting console caller.
    anchor: 'services-commerce:modules/catalog/services/entitlements/entitlements-port.ts'
    seam: sync
    on_failure: Reject another member’s grant and return not found for missing or wrong-kind grants.
    left_inconsistent: No use has been consumed.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#refuses an expired grant 409 and
      another member’s grant 403
  - 'n': 2
    actor_or_service: Catalog service
    action: Require a file belonging to the grant’s product listing.
    anchor: 'services-commerce:modules/catalog/services/persistence/product-listings.ts:getListingFile'
    seam: sync
    on_failure: Return not found for a file outside that product.
    left_inconsistent: The grant balance is unchanged.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#answers 404 for a grant of another
      kind, an unknown grant, and a file the product does not have
  - 'n': 3
    actor_or_service: Entitlements register (orders module)
    action: >-
      For a member, consume limited capacity using the request key; staff support skips consumption and expiry
      checks.
    anchor: 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
    seam: sync
    on_failure: 'Reject exhausted, expired or revoked access.'
    left_inconsistent: Capacity changes only for a permitted consumption.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives the grant’s owner a signed link
      and consumes one use per Idempotency-Key (a retry costs nothing), until the grant is exhausted (409)
  - 'n': 4
    actor_or_service: Asset pipeline delivery
    action: Generate a private download link with a fifteen-minute lifetime.
    anchor: 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
    seam: sync
    on_failure: Return delivery failure even if the earlier consumption succeeded.
    left_inconsistent: A granted use can remain consumed without a returned link.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: inferred
    source: 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
branches:
  - Unlimited grants do not decrement a remaining-use balance.
waits:
  - A returned private link remains valid for fifteen minutes.
evidence:
  - >-
    services-commerce at c8b66a98: modules/catalog/services/downloads/downloads.ts;
    services/entitlements/entitlements-port.ts; aws/api/storefront.routes.ts (downloadEntitledFile, the
    idempotency key header); tests/e2e/downloads.e2e.spec.js.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-CRY-001, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002]
---

# Download an entitled file

## What It Does

A buyer retrieves a purchased private file through a download grant. Limited access consumes capacity before the signed delivery link is returned.

## The Flow

```mermaid
sequenceDiagram
  participant B as Buyer or staff
  participant K as Catalog service
  participant G as Grant register
  participant F as Asset delivery
  B->>K: download (grant, file, request key)
  K->>G: find grant, check owner
  K->>K: file belongs to the product's listing
  opt member and limited grant
    K->>G: consume one use for the key
  end
  K->>F: signed link (15 minutes)
  K-->>B: link
```

## When Something Fails

Reject another member’s grant and return not found for missing or wrong-kind grants. No use has been consumed. Return not found for a file outside that product. The grant balance is unchanged. Reject exhausted, expired or revoked access. Capacity changes only for a permitted consumption. Return delivery failure even if the earlier consumption succeeded. A granted use can remain consumed without a returned link.

## Open Design Questions

The implemented recovery and concurrency behaviour above defines the current boundary. Any change to transaction scope or product authority requires a recorded decision.
