> ## Documentation Index
> Fetch the complete documentation index at: https://docs.specific.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Object storage

> S3-compatible object storage that works with any S3 client.

Managed S3-compatible object storage, powered by [Tigris](https://www.tigrisdata.com) in production. Works with any S3 SDK or tool.

```hcl specific.hcl theme={null}
service "api" {
  build = build.api
  command = "./api"

  endpoint {
    public = true
  }

  env = {
    S3_ENDPOINT   = storage.uploads.endpoint
    S3_ACCESS_KEY = storage.uploads.access_key
    S3_SECRET_KEY = storage.uploads.secret_key
    S3_BUCKET     = storage.uploads.bucket
  }
}

storage "uploads" {}
```

You can declare multiple buckets; each `storage` block is its own bucket with its own credentials.

## Connection attributes

| Attribute    | Description                                                               |
| ------------ | ------------------------------------------------------------------------- |
| `endpoint`   | S3-compatible endpoint URL (for example, `http://127.0.0.1:5000` in dev). |
| `access_key` | Access key for authentication.                                            |
| `secret_key` | Secret key for authentication.                                            |
| `bucket`     | Bucket name.                                                              |

## Example: AWS SDK (JavaScript)

```javascript theme={null}
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: "us-east-1", // Required but ignored locally
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY,
    secretAccessKey: process.env.S3_SECRET_KEY,
  },
  forcePathStyle: true, // Required for local S3-compatible servers
});

await s3.send(
  new PutObjectCommand({
    Bucket: process.env.S3_BUCKET,
    Key: "myfile.txt",
    Body: "Hello, world!",
  })
);
```

## Local development

During `specific dev`, a local S3-compatible server runs automatically, and the same `storage.*` references resolve to it. Browse bucket contents from the [local dashboard](/concepts/dashboard#the-local-dashboard).

## Production

Browse bucket contents and manage stored files from the [dashboard](https://dashboard.specific.dev).

If a service outside of Specific needs to read from or write to a bucket, generate direct S3-compatible credentials (read/write or read-only) from the storage resource's **Access** tab in the dashboard.

In [preview environments](/guides/previews), object storage is forked from the parent environment.
