> For the complete documentation index, see [llms.txt](https://docs.kernel.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kernel.ai/integrations/s3-integration.md).

# S3 file exchange

Connect your Amazon S3 bucket, choose the input CSV, and map the results Kernel writes back.

Use CSV files in your own Amazon S3 buckets to send account data to Kernel and receive results. Open [Connections → Amazon S3](https://app.kernel.ai/settings/connection/s3) to set up access, choose the input file, and set the output destination.

Kernel uses a cross-account IAM role. You keep the buckets in your AWS account and grant access through the role's trust policy and permissions.

## Connect Amazon S3

### 1. Authentication

Choose a setup type and enter a **Connection name**:

* **Simple** uses one IAM role and one bucket for reading and writing.
* **Advanced** lets you use separate read and write roles and buckets.

Select **Continue**.

<figure><img src="https://1215786129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvRYB7XIKCnmUi9oCEQGV%2Fuploads%2Fgit-blob-88614c0946831f0a29b816c0e428355ae3e42747%2Fapp-s3-connection.png?alt=media" alt="Amazon S3 connection wizard with Simple and Advanced setup choices."><figcaption><p>Choose one shared role and bucket, or separate read and write access.</p></figcaption></figure>

### 2. IAM access

Create an IAM role in your AWS account. Copy the **Example trust policy** from Kernel, including its **External ID**, into the role's trust relationship. Attach permissions for the bucket and prefixes Kernel will use.

The [IAM permissions](#iam-permissions) section below explains the required access.

### 3. Role ARN

Enter the ARN of the role you created. In **Advanced** setup, enter a separate **Write role ARN** if you use one. Leaving it empty uses the read role for both directions.

### 4. Verify

Select **Verify credentials**, then **Save IAM connection**. This checks that Kernel can assume the role. Next, add a bucket on the **Connection** tab.

## Choose the input file

Under **Input file**, add the bucket Kernel should read. Enter its label, bucket name, region, and prefix, then select **Save bucket**. The region is optional; Kernel can detect it on first access.

In **Advanced** setup, you can add several input buckets. Open **Manage bucket → Add bucket** to add another. Use **Read from** in the same menu to choose the active input bucket. Kernel reads from one input bucket at a time.

Use **Change file** to select the exact CSV object. Kernel reads this file when you import accounts. The card shows its path, primary key, detected row count, and last change time.

For manual imports and scheduled **Fixed file** pickup, put each new version of your account file at the same object key. For example:

```
s3://acme-data-exchange/kernel/input/accounts.csv
```

**Refresh columns** reads the header row again without importing accounts. Use it after changing the file's columns, then review your mapping. Choosing a different input file loads its columns and keeps your saved mapping. Fix any columns marked **Not in the current file**, then select **Save mapping**.

## Map incoming columns

Open **Data flows → Account import → Edit**.

1. Choose the column that holds your **Record ID**. Use a stable identifier from your own system.
2. Map the CSV source columns to Kernel target fields, including the required fields shown in the editor.
3. Add any further fields Kernel should read.
4. Select **Save mapping**.

Each row should have a unique, non-empty record ID. Keep IDs as strings to preserve leading zeroes. Keep column names stable between uploads, and include every column used by the saved mapping.

Example:

```csv
source_account_id,account_name,website,parent_source_account_id,owner_id,last_activity_date
A001,Acme Ltd,https://acme.example,,OWNER-17,2026-08-10
A002,Beta GmbH,https://beta.example,A001,OWNER-22,2026-08-09
```

Use UTF-8 CSV, one header row, and one row per account. Leave unavailable values empty. Use a consistent date format such as `YYYY-MM-DD`.

A missing mapped column stops the import. Rows with blank record IDs are skipped; a file whose IDs are all blank is rejected. If the same ID appears more than once, Kernel uses its first occurrence.

Before import, Kernel checks a sample of the file. If the record ID column is empty throughout that sample, import cannot start. Choose the correct **Record ID** column and select **Save mapping**, or fix the file. Then select **Refresh columns**.

## Import accounts

After the file upload finishes:

1. Open [Accounts](https://app.kernel.ai/accounts) and select **Import accounts**.
2. Choose **Amazon S3**.
3. Check the file path and detected row count, then select **Next**.
4. Review the number of rows not already in Kernel and select **Import**.

When scheduled runs are enabled, manual S3 imports use the scheduled flow processing path. Existing source IDs retain their links, and changes to their identity inputs are flagged for review. See [What happens to accounts](/integrations/s3-integration/s3-scheduled-runs.md#what-happens-to-accounts).

This import adds new accounts from the configured file. There is no individual row selection, and accounts already in Kernel are skipped. A row's absence from the file does not delete its account. Results appear in Accounts as processing finishes.

## Choose the output destination

On the **Connection** tab, use **Destination bucket** to set the output bucket and prefix. With **Simple** setup, the input and output use the same bucket. With **Advanced**, add the write bucket separately.

Select **Change file**, enter a filename ending in `.csv`, and choose a delivery mode:

| Mode            | Result                                                 |
| --------------- | ------------------------------------------------------ |
| **Overwrite**   | Each push replaces the file at the configured path.    |
| **Timestamped** | Each push creates a file with a timestamp in its name. |

The filename is relative to the bucket prefix. For a timestamped destination named `accounts.csv`, a result could be `accounts-2026-08-12T14-55-30Z.csv`. The timestamp is UTC.

Keep the destination separate from the input file. Select **Save** after changing the name or delivery mode.

### Map the output columns

Open **Data flows → Account export → Edit**.

* Choose each Kernel source field and enter its output column name.
* Use the checkboxes to select the fields to write.
* Use **Add field** for one field or **Add all fields** to start with the available set.
* Give every column a distinct name, then select **Create mapping**, or **Save mapping** when updating an existing mapping.

Every output includes `id`, containing the identifier from your input file. Use it to join results to your own records. The name `id` is reserved, so use a different name for other output columns.

**Import CSV** and **Export CSV** exchange mapping definitions. They do not import or export account records.

### Write results

Select Amazon S3 as the **Current write source** when it should receive cleaned data. Use **Make write source** on the connection to change this setting. See [Write source](/integrations/write-source.md) for how Kernel chooses the connection that receives write-back data.

Start an output sync from **Accounts → Sync to sources** when that control is available, or from **Sync history → Run sync**. Select the output mapping, review the account count, and confirm. Follow progress in [Sync history](https://app.kernel.ai/data-flows).

## Read the connection status

**IAM connected** means the role is saved and bucket setup remains. **Connected** means the connection has a configured input bucket. **Unreachable** means Kernel could not access the connection; use **Recheck connection** after correcting access.

Input and output cards show more specific checks:

| Status                          | What to do                                                                                                 |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **No destination set**          | Choose the output filename.                                                                                |
| **Ready to deliver**            | The destination file will be created on the first push.                                                    |
| **Verified** on the destination | Kernel can reach the bucket and find the file. The next push checks write access.                          |
| **Can't check file**            | Kernel cannot read the destination file. Check the role's read permissions if you want file details shown. |
| **File outside prefix**         | Choose a destination inside the configured bucket prefix.                                                  |
| **Can't reach S3**              | Check the bucket, region, role, and permissions.                                                           |

## IAM permissions

### Trust policy

Use the trust policy shown in your connection wizard. It contains the Kernel role ARN and External ID for your environment.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "<KERNEL_ROLE_ARN>" },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": { "sts:ExternalId": "<EXTERNAL_ID_FROM_KERNEL>" }
      }
    },
    {
      "Effect": "Allow",
      "Principal": { "AWS": "<KERNEL_ROLE_ARN>" },
      "Action": "sts:TagSession"
    }
  ]
}
```

### Bucket access

The app provides an **Example IAM policy** when you add a bucket. It grants:

| Permission                           | Purpose                                                                                            |
| ------------------------------------ | -------------------------------------------------------------------------------------------------- |
| `s3:ListBucket` on the bucket        | Verify bucket access and browse the configured prefix. Both read and write buckets use this check. |
| `s3:GetObject` on the input objects  | Read the CSV and its headers.                                                                      |
| `s3:PutObject` on the output objects | Write results.                                                                                     |
| `s3:GetObject` on output objects     | Display the destination file's details.                                                            |

Scope object access to the prefixes your team uses. For customer-managed KMS encryption, the input role needs `kms:Decrypt`; the output role needs `kms:GenerateDataKey`. The KMS key policy must permit the role as well.

## Change or remove the connection

Use **View IAM** to review the role setup. Use the input or destination bucket's menu to edit or remove a bucket. **Clear destination file** removes the selected output path.

**Disconnect** removes the IAM connection and its configured buckets from this Kernel environment. Reconnecting requires the connection and bucket setup again.

***

## Scheduled imports and automatic exports

Once your connection, input mapping, and output destination are ready, use a scheduled flow to automate the exchange. Kernel picks up your CSV files, processes new accounts, and exports results when they are ready.

Choose a fixed file, the latest dated folder, or files not yet processed. Run daily, weekly, or monthly in your chosen timezone, and use **Run now** whenever needed. Each flow has its own setup, schedule, and run history.

Your Kernel team enables scheduled runs and creates the initial flow. Manage it from **Connections → Amazon S3 → Scheduled runs**.

{% content-ref url="/pages/8yQlMrhTHvCeoE0BSf7E" %}
[Scheduled imports and automatic exports](/integrations/s3-integration/s3-scheduled-runs.md)
{% endcontent-ref %}
