# Private file access

Source: https://docs.settlemint.com/docs/developer-guides/api-integration/private-file-access
Understand how DALP serves private files through authenticated dapp URLs, checks object-key scope, and protects stored evidence from public access.



Private file access protects stored files that must not be exposed as public asset URLs. The dapp serves these files only after DALP confirms the user is signed in, validates the requested object key, checks the allowed scope, and reads the object from storage with no-cache response headers.

Use this explanation when you need to understand why a private file link works for one DALP user and fails for another. For operator steps, see [Open private files](/docs/user-guides/user-management/open-private-files). Do not build private file URLs by guessing object keys. Use the workflow that returns or records the file reference, then request the returned URL from an authenticated dapp session.

The URL is tied to DALP authentication and object-key scope. Sharing the path with another user does not grant access unless that user also has the required DALP session and scope.

## Access model [#access-model]

<Mermaid
  chart="flowchart TD
  A[Operator opens a DALP private file URL] --> B{Signed-in DALP session?}
  B -- No --> C[401 Unauthorized]
  B -- Yes --> D[Validate object key]
  D -- Invalid path --> E[403 Forbidden]
  D -- Valid path --> F{Scope allowed for user?}
  F -- No --> G[403 Forbidden]
  F -- Yes --> H[Read object storage]
  H -- Missing object --> I[404 File not found]
  H -- Storage unavailable --> J[503 Service unavailable]
  H -- Found --> K[Return file headers and body]"
/>

The route supports `GET` and `HEAD`. `HEAD` returns metadata headers without the file body. `GET` returns the file body and metadata headers.

## Object-key scopes [#object-key-scopes]

DALP allows private reads only for recognised object-key scopes.

| Object-key scope        | Who can read it                                       | Typical use                                     | Notes                                                                |
| ----------------------- | ----------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------- |
| `kyc/{userId}/...`      | The same user, or an admin user                       | KYC evidence and KYC profile document envelopes | The `{userId}` segment must match the signed-in user's DALP user ID. |
| `org/{orgId}/...`       | A member of the active organisation, or an admin user | Organisation-scoped documents and files         | The `{orgId}` segment must match the active organisation in session. |
| `admin/...`             | Admin users only                                      | Administrative files                            | Non-admin users receive `403 Forbidden`.                             |
| Any other first segment | No one by default                                     | Not a supported private file scope              | DALP denies unknown scopes instead of falling back to public access. |

Object keys are normalised before access checks. Keys containing `.` or `..` path segments are rejected to prevent traversal outside the allowed object-key namespace.

## Request behaviour [#request-behaviour]

The private file route supports `GET` and `HEAD`. `HEAD` returns metadata headers without the file body. `GET` returns the file body and metadata headers.

```http
HEAD /dalp/private/kyc/user_123/version_456/document_789/envelope.json
```

When access is allowed and the object exists, DALP returns metadata headers such as:

```http
200 OK
Content-Type: application/json
Content-Length: 2480
ETag: "9b2cf535f27731c974343645a3985328"
Last-Modified: Tue, 26 May 2026 10:30:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
```

A `GET` request to the same URL returns the object body with the same cache-control posture. Treat the URL as an authenticated dapp route, not as a public object-storage URL.

## Status codes [#status-codes]

| Status | Meaning                                                          | Client action                                                                |
| ------ | ---------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `200`  | DALP found the object and the signed-in user can read it.        | Use the returned file body or metadata headers.                              |
| `400`  | The private file path is incomplete.                             | Request a URL returned by DALP instead of constructing the path manually.    |
| `401`  | No signed-in DALP session is available.                          | Sign in again, then retry the URL from the dapp context.                     |
| `403`  | The object key is invalid, unknown, or outside the user's scope. | Stop and request the file through the owning workflow or an authorised user. |
| `404`  | The object-storage provider has no object at the allowed key.    | Recheck the upload or document record before retrying.                       |
| `503`  | DALP cannot reach object storage.                                | Retry after the storage service recovers.                                    |
| `500`  | DALP hit an unexpected storage read failure.                     | Retry only after checking operational status or support guidance.            |

## Security notes [#security-notes]

Private file access is separate from public branding and asset-document URLs. It requires an authenticated DALP session and enforces object-key scope before reading storage.

DALP sets `Cache-Control: no-cache, no-store, must-revalidate`, `Pragma: no-cache`, and `Expires: 0` on private file responses. Do not persist private file contents in shared caches. Store downloaded files only where your organisation's retention and access policy allows it.

A successful private file read proves only that the signed-in DALP user can read the stored object at that key. It does not prove that a participant is approved, that an asset transfer is compliant, or that a document satisfies a regulator's evidence requirements.

## Related pages [#related-pages]

* [KYC document uploads](/docs/developer-guides/api-integration/kyc-document-uploads) for the upload and confirmation workflow that stores KYC evidence.
* [Token documents](/docs/developer-guides/api-integration/token-documents) for asset document metadata and download behaviour.
* [Request headers](/docs/developer-guides/api-integration/request-headers) for API context headers used by integration clients.
* [Error handling](/docs/developer-guides/api-integration/error-handling) for production retry and recovery patterns.
