> For the complete documentation index, see [llms.txt](https://manual-v2.firstresonance.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual-v2.firstresonance.io/platform/data-snapshots/customer-s3-delivery-setup.md).

# Customer S3 Delivery Setup

### Overview

This guide walks you through setting up an S3 bucket in your AWS account to receive automated data snapshots from ION. Once configured, snapshots are delivered directly to your bucket as `.tar` archives.

### What You Need

* An S3 bucket in your AWS account
* An IAM role that First Resonance assumes to write to your bucket
* An external ID (provided by First Resonance) for secure role assumption

Once configured, snapshots are delivered to:

```
s3://<your-bucket>/<tenant-schema>/<job-id>/
```

***

### Step 1: Create an S3 Bucket

Create a bucket in your preferred AWS region, either through the AWS console or using the CLI:

```bash
aws s3 mb s3://<your-bucket> --region <your-region>
```

We recommend enabling:

* **Versioning** -- protects against accidental overwrites.
* **Server-side encryption** (SSE-S3 or SSE-KMS) -- encrypts data at rest.

***

### Step 2: Create an IAM Role

Create an IAM role that First Resonance will assume to deliver snapshots to your bucket.

#### Trust Policy

The trust policy allows First Resonance to assume the role using an external ID. Replace `<fr-account-id>` with the First Resonance AWS account ID for your environment (provided by your account team), and `<external-id>` with the external ID we provide.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<fr-account-id>:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<external-id>"
        }
      }
    }
  ]
}
```

The external ID prevents the [confused deputy problem](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html) and ensures only First Resonance can assume this role.

#### Permission Policy

Attach the following policy to the role. Replace `<your-bucket>` with your bucket name.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SnapshotDeliveryBucketAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::<your-bucket>",
        "arn:aws:s3:::<your-bucket>/*"
      ]
    }
  ]
}
```

{% hint style="info" %}
`s3:PutObject` handles the core upload. The additional permissions allow First Resonance to clean up incomplete uploads and list bucket contents for verification.
{% endhint %}

***

### Step 3: Send Your Configuration

Provide the following details to your account team:

| Field         | Description                                     |
| ------------- | ----------------------------------------------- |
| Bucket name   | Your S3 bucket name.                            |
| Bucket region | The AWS region where your bucket is located.    |
| Role ARN      | The full ARN of the IAM role created in Step 2. |

First Resonance will provide the external ID and configure your snapshot schedule.

***

### Step 4: Validation

After we receive your configuration, our system validates access by:

1. Assuming the IAM role with the external ID.
2. Verifying the bucket exists and is accessible.
3. Writing and deleting a small test object.

If validation fails, we will reach out with the specific error so you can adjust permissions.

***

### What Gets Delivered

Each snapshot creates files under your bucket with this structure:

```
s3://<your-bucket>/
  └── <tenant-schema>/
      └── <job-id>/
          ├── snapshot_tables_<job-id>.tar
          └── snapshot_attachments_<job-id>.tar
```

For large snapshots that are split into multiple files, each file includes a part number (e.g., `snapshot_tables_part1_<job-id>.tar`, `snapshot_tables_part2_<job-id>.tar`).

* **snapshot\_tables** -- all database tables as compressed CSV files, bundled into a tar archive.
* **snapshot\_attachments** -- file attachments bundled into a tar archive.

***

### Troubleshooting

| Issue                                        | Cause                                                   | Fix                                                                                              |
| -------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Role assumption fails (AccessDenied)         | Trust policy does not allow the First Resonance account | Verify the `Principal` in the trust policy matches the account ID provided by your account team. |
| Role assumption fails with correct principal | External ID mismatch                                    | Verify the `sts:ExternalId` condition matches the value provided by First Resonance.             |
| Access denied to bucket                      | Missing or incorrect permission policy                  | Verify the permission policy is attached to the role and the bucket name matches.                |
| Test write fails (AccessDenied)              | Role lacks `s3:PutObject` permission                    | Check the permission policy includes `PutObject` on the bucket resource.                         |
| Bucket does not exist                        | Wrong bucket name or region                             | Verify the bucket name and that it exists in the expected region.                                |

***

### Security Notes

* First Resonance uses **STS AssumeRole** with short-lived credentials that are automatically refreshed during long-running snapshots. No credentials are stored.
* The **external ID** ensures only First Resonance can assume the role.
* First Resonance only writes to your tenant's prefix and does not read or modify other data in your bucket.
* All data is transmitted over HTTPS (TLS).

***

### Related Pages

For an overview of data snapshots, see [Data Snapshots](/platform/data-snapshots.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://manual-v2.firstresonance.io/platform/data-snapshots/customer-s3-delivery-setup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
