---
title: AWS S3
description: Exchange files with Figure through an S3 bucket that you host or that Figure hosts.
---

## Partner-hosted S3 bucket

Use this when Figure delivers files to you, such as [Data Export](/data-integration/data-export) files.

You provide an S3 bucket. Figure writes objects using short-lived AWS credentials coordinated during onboarding.

For partner-hosted S3, **cross-account IAM role assumption** is the recommended path: you create a delivery role in your account; Figure assumes that role to upload files. **Long-lived IAM user access keys** remain supported when role assumption is not an option.

{% callout type="tip" title="Prefer GCS when you can" %}

If your organization can host a GCS bucket, that path uses IAM grants instead of AWS keys or cross-account roles. See [Partner-hosted GCS bucket](/data-integration/file-exchange/google-cloud-storage#partner-hosted-gcs-bucket).

{% /callout %}

### How Figure authenticates to your S3

- Figure file delivery runs on **Google Cloud**. Figure does not run compute inside your AWS account.
- On the IAM role path, Figure does **not** use long-lived access keys. Figure obtains short-lived credentials, then calls [`sts:AssumeRole`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) into **your** delivery role to call S3.
- Your role trust policy must allow a **Figure IAM role ARN** (Role A) that Figure provides during onboarding. Trust the **role ARN** (`arn:aws:iam::…:role/…`), not an `assumed-role/…/session` form from STS.

### Cross-account IAM role (recommended) {% #cross-account-iam-role-recommended %}

You create an IAM role in your AWS account (Role B) that Figure assumes to write to your bucket or prefix.

**Figure IAM roles to trust (Role A)** — Figure provides separate IAM role ARNs for test and production during onboarding over a secure channel (not email or tickets). Use the test principal for non-production integrations and the production principal for live delivery. The ARN shape is:

`arn:aws:iam::<figure-aws-account-id>:role/<figure-file-transfer-role>`

**What Figure needs from you**

- Bucket name and AWS Region
- Optional prefix / directory
- The **ARN of your delivery role** (Role B)
- An **ExternalId** your organization generates, if your trust policy requires it (Figure stores and sends it on every `AssumeRole`; coordinate through a secure channel — not email or tickets)
- Separate test and production buckets and roles where applicable
- Confirmation that the [file-exchange IP addresses](/ips#file-exchange-ip-addresses) are allowlisted if you restrict by source IP

**What you configure in AWS (Role B)**

- **Trust policy**: allow `sts:AssumeRole` from the Figure Role A ARN for that environment; use an `sts:ExternalId` condition when required
- **Permissions**: least privilege on the bucket or prefix — typically `s3:PutObject`, `s3:ListBucket` (scoped to the prefix), and `s3:DeleteObject` only if needed
- Bucket must not be public. If the bucket uses default encryption (for example SSE-KMS), align expectations during onboarding

Example trust policy statement — substitute the **Principal** and **ExternalId** with the values Figure and your organization exchange during onboarding:

```json
{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::<figure-aws-account-id>:role/<figure-file-transfer-role>"
  },
  "Action": "sts:AssumeRole",
  "Condition": {
    "StringEquals": {
      "sts:ExternalId": "<partner-issued-external-id>"
    }
  }
}
```

Use the production Role A ARN in production trust policies and the test Role A ARN in non-production trust policies.

{% details summary="Static IAM user or access keys (alternate)" %}

Figure can write using an IAM user or access keys scoped to your bucket, exchanged through a secure channel — not email or tickets.

**What Figure needs from you**

- Bucket name
- Optional prefix / directory
- AWS access credentials for that bucket (or a scoped IAM user that can write to it)

Least-privilege on the bucket or prefix is preferred (`s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, and `s3:DeleteObject` as needed).

{% /details %}

## Figure-hosted S3 bucket

Use this when you deliver files to Figure.

Figure provides an S3 bucket. You access it with an IAM role or credentials that you provide.

For more information about how to [upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)
and [download](https://docs.aws.amazon.com/AmazonS3/latest/userguide/download-objects.html)
with S3 buckets, see the linked AWS documentation.

### What Figure needs from you

- The full ARN of your AWS role, or the credentials you will use to access the bucket

### What you will need from Figure

- The name of the S3 bucket

## Common questions

- [Does Figure need our AWS access keys?](/data-integration/faq#does-figure-need-our-aws-access-keys)
- [Can Figure assume a role in our account using an ExternalId?](/data-integration/faq#can-figure-assume-a-role-in-our-account-using-an-externalid)
- [Do you support cross-account IAM role access instead of long-lived access keys?](/data-integration/faq#do-you-currently-support-cross-account-iam-role-access-instead-of-long-lived-access-keys)
- [Does Figure's uploader run in AWS?](/data-integration/faq#does-figures-uploader-run-in-aws-does-it-use-an-execution-role-in-our-account)
