# AWS S3: SDK, CLI & BucketMate Integration Guide (2026)

> Set up AWS S3 credentials, then test the connection with aws sts get-caller-identity, aws s3 ls, and aws s3 mb. Includes fixes for AccessDenied and region errors.

Canonical: https://www.bucketmate.app/blogs/aws-s3-setup-bucketmate

Want a single playbook for Amazon S3 that covers the AWS CLI, rclone, s3cmd, and the AWS SDK for JavaScript - and finishes by putting your bucket inside BucketMate? This guide walks through credentials, environment variables, and copy-pasteable commands so you can move files fast and keep a native view for day-to-day work.


## 1) Choose your authentication method

[AWS recommends temporary credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) through IAM Identity Center for human users. Use a long-lived IAM access key only when an AWS profile is not available.


### AWS profile and IAM Identity Center (recommended)

1. Configure a profile with `aws configure sso --profile prod-s3`.
2. Sign in with `aws sso login --profile prod-s3`.
3. In BucketMate for macOS, choose AWS Profile, select `prod-s3`, and use Login with SSO when the session needs authentication.

BucketMate reads profiles from `~/.aws/config` and `~/.aws/credentials`, so you do not need to copy temporary access keys into the app. When the SSO session expires, log in again through the profile flow.


### IAM access key fallback

1. In the [IAM console](https://console.aws.amazon.com/iam/), open Users, choose Create user, and enter a purpose-specific name such as `bucketmate-editor`.
2. Add permissions and create an inline policy using the JSON editor.
3. Paste a least-privilege policy for the bucket:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::my-s3-bucket"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::my-s3-bucket/*"
    }
  ]
}
```

Replace `my-s3-bucket` with your bucket name. This policy intentionally limits access to one bucket. To build a variant such as read-only or upload-only, use the free [S3 IAM policy generator](/free-tools/s3-iam-policy-builder).

4. Finish creating the user, open Security credentials, and choose Create access key.
5. Select the use case that matches your setup and confirm that you understand the security recommendation.
6. Download the `.csv` containing the Access key ID and Secret access key. AWS shows the secret only once.
7. Note the bucket region, such as `us-east-1`.

In BucketMate, turn off "Credentials have permission to list buckets" and enter the bucket name because this scoped policy does not grant account-wide bucket listing.

> 🔐 Never create access keys for the AWS root user. Prefer IAM Identity Center, temporary credentials, and least-privilege permissions.


## 2) Configure the AWS CLI


The AWS CLI is still the quickest way to sanity-check your credentials before touching other tooling.


```shell
export AWS_ACCESS_KEY_ID="<your-access-key-id>"
export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"
export AWS_DEFAULT_REGION="us-east-1"  # match your bucket region
# Optional temporary credentials:
# export AWS_SESSION_TOKEN="<your-session-token>"
```


List buckets and copy an object:


```shell
aws s3 ls

aws s3 cp ./brand-guide.pdf s3://my-s3-bucket/docs/brand-guide.pdf
```


Prefer profiles? Run `aws configure --profile prod-s3` once, then set `export AWS_PROFILE=prod-s3` when you need it. To write `~/.aws/config` and `~/.aws/credentials` by hand, generate the entries with the [AWS profile config generator](/free-tools/aws-profile-config-generator).


## 3) Test your S3 connection with the AWS CLI

Run these checks in order. Each one narrows down where a failure comes from.

1. Confirm the credentials work at all:

```shell
aws sts get-caller-identity --profile prod-s3
```

This prints your account ID and the ARN of the user or role. If it fails, the problem is the credentials or the profile, not S3.

2. Confirm S3 access to your bucket:

```shell
aws s3 ls s3://my-s3-bucket --profile prod-s3
```

Listing a specific bucket works even when the policy does not allow `s3:ListAllMyBuckets`, so prefer this over a bare `aws s3 ls`.

3. Confirm write access with a round trip:

```shell
echo "connection test" > test.txt
aws s3 cp test.txt s3://my-s3-bucket/test.txt --profile prod-s3
aws s3 rm s3://my-s3-bucket/test.txt --profile prod-s3
```

4. Create a bucket if you need one. `aws s3 mb` makes a bucket in the given region:

```shell
aws s3 mb s3://my-new-bucket --region us-east-1 --profile prod-s3
```

Bucket names are global across all AWS accounts, so pick a unique name.

What the common errors mean:

| Error | Likely cause | Fix |
| --- | --- | --- |
| `Unable to locate credentials` | No keys, profile, or SSO session found | Run `aws configure` or `aws sso login --profile prod-s3` |
| `ExpiredToken` | Temporary or SSO credentials expired | Log in again with `aws sso login` |
| `AccessDenied` on `ls` | Missing `s3:ListBucket` on the bucket ARN | Add `s3:ListBucket` for `arn:aws:s3:::my-s3-bucket` |
| `AccessDenied` on `cp` | Missing object permissions | Add `s3:GetObject` / `s3:PutObject` on `arn:aws:s3:::my-s3-bucket/*` |
| `PermanentRedirect` or `AuthorizationHeaderMalformed` | Wrong region | Pass `--region` matching the bucket region |
| `SignatureDoesNotMatch` | Wrong secret key or clock drift | Re-enter the secret and enable automatic time sync |
| `BucketAlreadyExists` on `mb` | Name is taken by another account | Choose a different bucket name |


## 4) rclone: high-throughput syncs


`rclone` ships with an S3 backend that supports every region and storage class. Configure it like this:


```shell
rclone config
# n) New remote → name it "awsprod"
# s) Choose "Amazon S3 Compliant Storage Providers"
# 1) Pick "Amazon S3"
# Supply the access key, secret, and region
# Leave the endpoint blank (the AWS default will be used)
# Save

# Verify:
rclone ls awsprod:my-s3-bucket

# Sync a folder with server-side multipart uploads:
rclone sync ./dist awsprod:my-s3-bucket/releases --fast-list --s3-chunk-size 64M
```


Performance tip: set `--s3-upload-concurrency 16` for large batches to saturate your bandwidth.


## 5) s3cmd: script-friendly uploads


`s3cmd` is perfect when you want a simple `.ini` config and POSIX-like commands.


```shell
s3cmd --configure
# Access key: <your-access-key-id>
# Secret key: <your-secret-access-key>
# Default Region: us-east-1
# S3 Endpoint: s3.amazonaws.com (leave blank to accept default)
# Use HTTPS [Yes]
# Save settings? [Yes]

# Usage examples:
s3cmd ls s3://my-s3-bucket
s3cmd put hero.png s3://my-s3-bucket/assets/hero.png --acl-public
```


To avoid typing flags in CI/CD, store the config at `~/.s3cfg` and load it with `s3cmd --config ~/.s3cfg ...`.


## 6) AWS SDK for JavaScript (v3)


Ship features using the official SDK and modern async/await ergonomics.


```typescript
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  region: "us-east-1",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
    // sessionToken: process.env.AWS_SESSION_TOKEN, // if you use temporary credentials
  },
});

await s3.send(new PutObjectCommand({
  Bucket: "my-s3-bucket",
  Key: "marketing/welcome.txt",
  Body: "Hello from Amazon S3!",
  ContentType: "text/plain",
}));
```


Checklist for production:

- Use `AWS_PROFILE` or IAM roles when running on EC2/Lambda so that credentials rotate automatically.
- Set `ContentType` and `CacheControl` headers for assets that go to CDNs.
- Wrap calls in retries with exponential backoff for high-volume ingestion.

## 7) Browse S3 visually with BucketMate


[BucketMate](https://www.bucketmate.app/?utm_source=blog&utm_medium=guide&utm_campaign=aws-s3) is a native [S3 client for Mac](https://www.bucketmate.app/) that also runs on iOS and Web. It keeps your buckets a click away with multi-select, drag-and-drop uploads, and instant previews.

1. Download BucketMate and launch the app.
2. Click Add connection → Amazon S3.
3. Choose AWS Profile to use a profile from `~/.aws/config` or `~/.aws/credentials`.
4. Select the profile. For SSO profiles, use Login with SSO and finish the browser login.

![BucketMate Add Connection dialog showing AWS Profile authentication and profile selection](/blogs/aws-s3-setup-bucketmate/aws-profile-sso-connection.png)

5. For an SSO profile, choose Login with SSO. BucketMate opens your browser automatically. Enter the displayed verification code and finish signing in.

![BucketMate waiting for AWS SSO login with a verification code and browser URL](/blogs/aws-s3-setup-bucketmate/aws-profile-sso-login.png)

6. To use key-based authentication instead, choose Access Key, enter the access key ID and secret, and add the session token when required.
7. Choose the correct region and use Test connection.
8. Save the connection to browse buckets, rename keys, and edit metadata using a native interface.

> 🧭 BucketMate remembers every connection, so your team can store multiple AWS accounts and S3-compatible services side by side.


## Troubleshooting checklist

- AccessDenied: Confirm the IAM policy includes `s3:ListBucket` for the bucket and `s3:GetObject` / `s3:PutObject` for key prefixes.
- Region mismatch: If uploads hang, double-check that the CLI/SDK region matches the bucket region exactly.
- SignatureDoesNotMatch: Ensure your device clock is in sync or enable automatic time (NTP).
- rclone connection errors: Re-run `rclone config` and set `location_constraint` to the exact AWS region if prompted.
- s3cmd SSL issues: Upgrade to the latest release or set `ca_certs_file` in `~/.s3cfg` when behind a proxy.

For every BucketMate connection field and AWS-specific error, see the [Connect AWS S3 docs](https://docs.bucketmate.app/macos/providers/connect-aws-s3). For a quick overview, see the [AWS S3 GUI client page](/s3-client/aws-s3).


## FAQ

### How do I test my AWS CLI connection to S3?

Run `aws sts get-caller-identity` to confirm the credentials, then `aws s3 ls s3://your-bucket` to confirm S3 access. Add `--profile name` if you use a named profile.

### What does aws s3 mb do?

`aws s3 mb s3://bucket-name` creates a new S3 bucket. Add `--region` to choose where it lives. The name must be globally unique across all AWS accounts.

### Why does aws s3 ls return AccessDenied?

A bare `aws s3 ls` needs `s3:ListAllMyBuckets`, which least-privilege policies often leave out. List a specific bucket with `aws s3 ls s3://your-bucket` instead, which needs `s3:ListBucket` on that bucket.

### Where does the AWS CLI store credentials?

In `~/.aws/credentials` for access keys and `~/.aws/config` for regions, profiles, and SSO settings. Environment variables such as `AWS_ACCESS_KEY_ID` and `AWS_PROFILE` override the files.
