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

# Connect AWS for Storage Audit

> Create a read-only IAM role so BlobRouter can scan your S3 buckets. Exact console steps and correct policy JSON.

<Info>
  **BlobRouter v0.1** · Last updated: August 2026 · Architecture version: **2.0**
</Info>

This is the most important setup guide. Follow it carefully — most connection failures are External ID or trust-policy mismatches.

## Overview

You are creating a **read-only** IAM role in your AWS account that BlobRouter can **assume temporarily** (STS) to list buckets and object metadata.

With this role BlobRouter **cannot** modify, delete, or upload objects. Temporary credentials expire in about one hour and are never stored.

You will need values from the BlobRouter dashboard (**Connect AWS**):

* BlobRouter’s **AWS account ID** (12 digits)
* Your unique **External ID**

## Step 1: Create the IAM role

1. Open the [AWS IAM console → Roles](https://console.aws.amazon.com/iam/home#/roles)
2. Choose **Create role**
3. **Trusted entity type:** AWS account
4. Select **Another AWS account**
5. **Account ID:** paste BlobRouter’s account ID from the dashboard (do not invent a placeholder)
6. Check **Require external ID**
7. **External ID:** paste the value shown in the BlobRouter dashboard (copy/paste — do not retype)
8. Leave MFA options as-is unless your org requires MFA on assume-role
9. Choose **Next**

Your trust policy should look like this (IDs come from the dashboard):

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::BLOBROUTER_ACCOUNT_ID:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "YOUR_EXTERNAL_ID_FROM_DASHBOARD"
        }
      }
    }
  ]
}
```

The dashboard generates this JSON with your real values — prefer copying from there.

## Step 2: Attach permissions policy

On the permissions step, choose **Create policy** (JSON) and paste this **exact** policy:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BlobRouterScannerReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:GetMetricsConfiguration",
        "s3:GetObject",
        "s3:GetObjectAttributes",
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:ListMetrics"
      ],
      "Resource": "*"
    }
  ]
}
```

<Warning>
  Do **not** use `s3:HeadObject` or `s3:GetBucketMetricsConfiguration`. Those action names are invalid in IAM.
  The HeadObject API is authorized by `s3:GetObject`. Metrics configuration uses `s3:GetMetricsConfiguration`.
</Warning>

Name the policy something like `BlobRouterScannerReadOnly`, create it, attach it to the role, then continue.

## Step 3: Name and create the role

1. **Role name:** `BlobRouterScanner` (or any name you prefer)
2. Optional description: `Read-only S3 audit for BlobRouter`
3. Choose **Create role**

## Step 4: Copy the Role ARN

1. Open the role you just created
2. Copy the **ARN** from the summary

Format:

```text theme={null}
arn:aws:iam::123456789012:role/BlobRouterScanner
```

## Step 5: Paste into BlobRouter

1. Open [Dashboard → Connect AWS](https://app.blobrouter.com)
2. Paste the Role ARN
3. Choose **Connect AWS Account**

BlobRouter will AssumeRole, verify `ListBuckets`, store the connection, and start your first scan.

## Troubleshooting

### Error: Could not assume the IAM role / `connection_failed`

* External ID must match **exactly** (copy from dashboard)
* Trust policy Account ID must be BlobRouter’s 12-digit account ID from the dashboard
* Role must include the permissions policy above
* Wait \~10 seconds after creating the role (IAM propagation)

### Error: Invalid Role ARN format / `invalid_role_arn`

* Must start with `arn:aws:iam::`
* Account ID must be exactly 12 digits
* Must include `/role/RoleName` after the account ID

### Error: Scanner configuration error / `scanner_credentials_missing`

This is a BlobRouter-side configuration issue, **not** a problem with your IAM role. Contact support.

### AWS IAM Console: `Invalid Action: s3:HeadObject does not exist`

Use `s3:GetObject` instead. The HeadObject API uses the **GetObject** IAM action.

### AWS IAM Console: `s3:GetBucketMetricsConfiguration does not exist`

Use `s3:GetMetricsConfiguration` instead.

### Role connects but scan finds little waste

Access metrics improve classification. Without CloudWatch / metrics access, BlobRouter falls back to LastModified as a proxy for hot/cold/archive. That is expected and still useful.

## Security notes

* Role has **no** write, delete, or PutObject permissions
* BlobRouter uses STS temporary credentials only for scans
* Revoke access anytime by deleting the role or removing the trust statement

Next: review results in the dashboard, then optionally [approve migrations](/guides/migration) or [install the SDK](/quickstart).
