# Amazon's S3

Use our AWS S3 implementation (including CloudFront and CloudFront Signed URLs) for faster and more secure delivery via pre-signed URLs.

## S3 Storage

Follow these steps to upload and configure your data on Amazon S3:

1. **Create an S3 Bucket:**
   1. Go to the [AWS Console](https://aws.amazon.com/console/) and log in or create an account.
   2. Search for **S3** and click `Buckets > Create bucket`.
   3. Set a `Bucket name` and `Region`.
   4. Enable `ACLs` and disable `Block all public access`.
   5. Acknowledge the warning: `I acknowledge that the current settings might result in this bucket and the objects within becoming public`.
   6. Click **Create bucket**.
2. **Create an IAM User with S3 Permissions:**
   1. Go to `IAM > Access management > Users` and click **Add users**.
   2. Assign a `Username` and choose `Attach policies directly`.
   3. Select `AmazonS3FullAccess` and proceed.
   4. After creation, open the user page and generate an **Access key** under **Security credentials**.
   5. Copy the `Access Key ID` and `Secret Access Key`. You won’t be able to see the secret again later.
3. **Set CORS Configuration:**
   1. Select your bucket and go to the **Permissions** tab.
   2. Scroll down to **Cross-origin resource sharing (CORS)** and click **Edit**.
   3. Paste the following JSON config and save:<br />
`[
    {
        "AllowedHeaders": ["*"],
        "AllowedMethods": ["GET"],
        "AllowedOrigins": ["*"],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]`

<Info>
You can restrict `AllowedOrigins` to your actual domain for better security (e.g., `["https://yourdomain.com"]`).
</Info>

1. **Configure S3 in the Admin Panel:**
   1. Go to `Admin > Settings > Storage`.
   2. Fill in the `Bucket name`, `AWS Access Key ID`, and `AWS Secret Access Key`.

## S3 + CloudFront

Use CloudFront to distribute your content globally:

1. Search for **CloudFront** in the AWS Console and go to `Distributions > Create distribution`.
2. Copy the `Distribution domain name` (e.g., `abc123.cloudfront.net`) and configure it in `Admin > Settings > Storage` under `Aws CloudFront Domain Name`.
3. Adjust your **CDN Distribution Origin** settings:
   1. Open your distribution and navigate to the **Origins** tab.
   2. Edit your origin and set `Origin access` to `Origin access control settings`.
   3. Under **Origin Access Control**:
      1. Click **Create new OAC** and keep the default settings.
      2. Click **Create**.
   4. Select the newly created OAC from the dropdown list.
   5. Click **Save changes**.
4. Update the S3 bucket policy to allow CloudFront access while retaining IAM user write permissions:<br />
`{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontAccess",
            "Effect": "Allow",
            "Principal": {"Service": "cloudfront.amazonaws.com"},
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::your-account-id:distribution/your-cdn-distribution-id"
                }
            }
        },
        {
            "Sid": "AllowIAMUserWrite",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::your-account-id:user/your-iam-user-name"},
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}`
5. Adjust **Bucket Access Settings**:
   1. Disable **Block all public access**.
   2. Manually select options to allow write access for IAM users while restricting object access to CloudFront. Disable **Block all public access** and **enable** all the options manually except `Block public access to buckets and objects granted through new access control lists (ACLs)`

## S3 + CloudFront + Signed URLs

Follow these steps to use signed URLs for secure access:

1. **Create a key pair (e.g., via OpenSSL):**

<Info>
The steps below use OpenSSL as an example. There are other methods as well.
</Info>

- Generate a private key: `openssl genrsa -out private_key.pem 2048`
- Extract the public key: `openssl rsa -pubout -in private_key.pem -out public_key.pem`

1. **Upload the public key to CloudFront:**
   1. Log into [CloudFront console](https://console.aws.amazon.com/cloudfront/v3/home).
   2. Go to `Key management > Public keys > Create public key`.
   3. Paste the contents of `public_key.pem` and save.
   4. Copy the **Public Key ID** after adding. This is your `Key-Pair-Id` (and corresponds to `Aws CloudFront Key Pair Id` in the admin panel).
2. **Create a key group:**
   1. Go to `Key management > Key groups > Create key group`.
   2. Add the uploaded public key to the group and save.
3. **Link the key group to your distribution:**
   1. Open your distribution settings and edit the behavior for the desired path.
   2. Enable **Restrict Viewer Access** and select the trusted key group.
4. Navigate to **Admin &gt; Settings &gt; Storage** in your admin panel.

- Add the following:
- Enable **CloudFront PreSigned URLs**.

For more information, refer to the official [AWS documentation on private content with signed URLs](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html).
