# Object Storage

Store content-addressed files and large values with integrity-verified reads and scoped public delivery.

Ferrite Object Storage keeps large values outside small Store records. Objects
are content-addressed and verified when read, making corruption and accidental
replacement visible.

## Store an object

```rust filename="src/uploads.rs"
let mut uploads = ctx.blob("uploads")?;
uploads.put(b"tenant/acme/evidence/report.pdf", &bytes).await?;
let report = uploads.get(b"tenant/acme/evidence/report.pdf").await?;
```

Use tenant-scoped logical keys even though the storage layer verifies content.
Store metadata, ownership, retention, and authorization state in Store; keep
the bytes in Object Storage.

## Serve static content

Map a content route to a blob binding and key prefix:

```json filename="ferrite.json"
{
  "services": [{ "name": "site-assets", "primitive": "blob" }],
  "applications": [{
    "name": "site",
    "artifact_key": "apps/site@v1",
    "artifact_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
    "bindings": [
      { "handle": "web-assets", "kind": "blob", "service": "site-assets" }
    ],
    "routes": [{
      "prefix": "/",
      "binding": "web-assets",
      "kind": "content",
      "key_prefix": "site/",
      "public": true
    }]
  }]
}
```

This developer portal uses the same pattern: Astro produces static assets, a
Ferrite function uploads them to its scoped blob space, and the Gateway serves
them with the correct route policy.

## Sensitive content

Do not mark a content route public when object access depends on a user or
tenant. Use an authenticated API that checks authorization before reading the
scoped object and returning its bytes.

See [Authorization](/developers/authorization/) and [Headers & Cookies](/developers/headers-cookies/).
