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

# S3

> Set up AWS S3 credentials for the S3 VFS.

## Credentials

The S3 VFS needs an AWS access key pair with read (and optionally write) access to your bucket.

### 1. Create an IAM User

1. Go to [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)
2. **Users** -> **Create user**
3. Attach the `AmazonS3ReadOnlyAccess` policy (or `AmazonS3FullAccess` for write)
4. **Security credentials** -> **Create access key** -> **Application running outside AWS**
5. Copy the **Access key ID** and **Secret access key**

### 2. Set Environment Variables

```bash theme={null}
# .env.development
AWS_S3_BUCKET=my-bucket
AWS_DEFAULT_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJal...
```

### Alternative: AWS Profile

If you have `~/.aws/credentials` configured, you can use a profile name instead of explicit access keys.

For the Python VFS API, see the [S3 VFS doc](/python/vfs/s3).

## Scoping a VFS to a key prefix

Both runtimes support a key prefix option that transparently scopes every operation to a subpath of the bucket, so agents see clean paths while the underlying S3 keys carry the full prefix.

<CodeGroup>
  ```ts TypeScript theme={null}
  const s3 = new S3VFS({
    bucket: 'app-data',
    region: 'eu-west-1',
    keyPrefix: `users/${userId}/`,
  })
  ```

  ```python Python theme={null}
  S3VFS(S3Config(
      bucket="app-data",
      region="eu-west-1",
      key_prefix=f"users/{user_id}/",
  ))
  ```
</CodeGroup>

Leading slashes are stripped and a trailing slash is added automatically. `None` / `undefined` and empty strings both mean "no prefix." For browser security considerations, see the [TypeScript S3 setup doc](/typescript/setup/s3).

## Content type of uploads

A write carries no content type of its own, so the mount decides what S3 stores and serves back. Set `default_content_type` (`defaultContentType` in TypeScript) to stamp every upload with it. Unset, S3 picks its own default, and the browser's presigned PUT, which has to sign a type, sends `application/octet-stream`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.