Skip to content

Create and Configure an AWS S3 Bucket

A tenant administrator can use a tenant-owned Amazon S3 bucket for object storage. After saving it, choose Manual selection on the OSS page and select that profile. Newly uploaded images, videos, audio files, PDFs, and other media are then stored directly in that bucket. The associated AWS account pays the storage, request, and download-transfer charges.

Recommended setup

Use a private bucket, keep Block all public access enabled, and leave Public base URL empty in the management app. The software uses temporary signed URLs to upload and access objects, so the bucket does not need to be public.

Prerequisites

Prepare the following items:

  • An active AWS account.
  • A globally unique bucket name.
  • The Region code for the bucket, such as ap-southeast-1.
  • The exact origin of the Web management app, such as https://admin.example.com, for CORS.
  • A Cloud tenant administrator account, or a tenant administrator signed in to the embedded service through an authenticated LAN connection.

Choose a Region close to the primary users. A bucket's Region cannot be changed after creation, and cross-Region access can add latency and transfer charges.

Create the S3 bucket

  1. Sign in to the AWS Management Console.
  2. Open Amazon S3.
  3. Open Buckets and select Create bucket.
  4. Select General purpose as the bucket type.
  5. Enter a globally unique bucket name. Lowercase letters, numbers, and hyphens are recommended, for example tenant-media-001.
  6. Select the AWS Region and record its Region code.
  7. Keep Bucket owner enforced under Object Ownership so ACLs remain disabled.
  8. Keep all four Block Public Access options enabled.
  9. Initially keep Bucket Versioning disabled unless version recovery is required.
  10. Select SSE-S3 for default encryption.
  11. Keep Object Lock disabled.
  12. Select Create bucket.

Do not disable Block Public Access simply to make media available. The management app can access private objects through presigned requests.

When Versioning is enabled, deleting media can leave noncurrent versions that continue to consume storage. Add lifecycle cleanup for noncurrent versions if version recovery is required.

Configure CORS for Web uploads

Android, iOS, and desktop clients do not require CORS. A bucket used by the Web management app must allow upload requests from the app's origin.

Open:

text
Bucket → Permissions → Cross-origin resource sharing (CORS)

Enter the following JSON and replace the sample origin with the real Web management origin:

json
[
  {
    "AllowedHeaders": [
      "*"
    ],
    "AllowedMethods": [
      "GET",
      "PUT",
      "HEAD"
    ],
    "AllowedOrigins": [
      "https://admin.example.com"
    ],
    "ExposeHeaders": [
      "ETag"
    ],
    "MaxAgeSeconds": 3600
  }
]

An AllowedOrigins entry includes the scheme, host, and any non-default port, but no path. For example, use https://admin.example.com, not https://admin.example.com/login.

Do not use "*" for AllowedOrigins in production. Add each approved management origin separately when more than one origin is required.

The browser must be able to read ETag to complete multipart uploads, so it must be included in ExposeHeaders.

Create a dedicated IAM user

Do not use an AWS root-user access key and do not grant account-wide administrative access to the storage identity.

  1. Open IAM.
  2. Open Users and select Create user.
  3. Enter a dedicated name such as tenant-media-storage.
  4. Do not enable AWS Management Console access.
  5. After creating the user, open its Permissions tab.
  6. Select Add permissions and create an inline policy.
  7. Open the JSON editor and enter the least-privilege policy below.

Replace YOUR_BUCKET_NAME with the actual bucket name:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "TenantObjectStorage",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload"
      ],
      "Resource": [
        "arn:aws:s3:::YOUR_BUCKET_NAME/*"
      ]
    }
  ]
}

These permissions cover downloads and object metadata checks, direct and multipart uploads, user-requested object deletion, and cancellation of incomplete multipart uploads. Tenant-owned storage is excluded from scheduled platform scans and cleanup, so s3:ListBucket is not required for that task. The software does not require AmazonS3FullAccess.

Additional KMS permissions are required when the bucket uses a customer-managed SSE-KMS key. SSE-S3 is recommended for an initial setup because it avoids additional permissions and KMS charges.

Create an access key

  1. Open the newly created IAM user.
  2. Open Security credentials.
  3. In Access keys, select Create access key.
  4. Select Application running outside AWS. Some console versions may show Other instead.
  5. Create and securely save the Access Key ID and Secret Access Key.

The Secret Access Key is normally displayed in full only once. Never send credentials through chat, email, support tickets, or screenshots.

Add the bucket to tenant object storage

Sign in with a Cloud tenant administrator account, or use an authenticated LAN tenant-administrator connection to the embedded service, and open:

text
Account Settings → Configuration management → Object Storage Service (OSS) → Add object storage

Use the following values for standard AWS S3:

FieldAWS S3 value
NameA recognizable name such as “AWS S3 Production.”
DescriptionOptional purpose, owner, and AWS account notes. Never include the Secret Key.
ProviderSelect S3-compatible storage.
EndpointLeave empty for standard AWS S3. Use it only for a third-party S3-compatible service.
RegionEnter the Region code, such as ap-southeast-1, not a display name such as “Singapore.”
BucketEnter the exact bucket name.
Access KeyEnter the IAM user's Access Key ID.
Secret KeyEnter the corresponding Secret Access Key.
Public base URLLeave empty for a private AWS S3 bucket so the software generates signed download URLs.
Use path-style accessDisable for standard AWS S3.

Public base URL

Do not enter the ordinary URL of a private bucket. When Public base URL is set, the software treats it as a directly accessible public or CDN domain and does not generate an S3 signature for the download URL. Private objects will then return HTTP 403.

Only enter a Public base URL after a public CDN or custom domain has been configured and verified to serve objects directly.

Test, save, and select the profile

  1. After completing the form, select Test connection.
  2. The server uploads a small temporary object, reads its metadata, and attempts to delete it.
  3. After a successful test, select Save. Testing does not save the form.
  4. Return to the object storage list and change the selection mode to Manual selection.
  5. Select the saved AWS S3 profile and save the setting.

A new configuration is not selected automatically. Selecting it affects only uploads that start afterward:

  • Existing media continues to use its original object storage.
  • An upload already in progress continues with the configuration selected when it started.
  • Objects are not automatically moved between buckets.

Clean up incomplete multipart uploads

To prevent interrupted multipart uploads from consuming storage indefinitely, open:

text
Bucket → Management → Create lifecycle rule

Create a rule that applies to the entire bucket:

  • Lifecycle rule action: delete incomplete multipart uploads.
  • Days after initiation: 7 days is recommended.

This action removes only incomplete multipart parts and does not delete successfully completed objects.

Production verification

Complete these checks before normal use:

  1. Upload a small image and confirm that direct upload and preview work.
  2. Upload a larger file and confirm that multipart upload works.
  3. Confirm that an object appears on the S3 Objects page.
  4. Open or play the media and confirm that the signed download URL works.
  5. Delete a dedicated test media item that is not referenced by a programme and confirm that the object can be removed.
  6. Test once from the Web management app and once from a native client.

Object keys normally use this structure:

text
<uuid>.<ext>

Object keys are flat filenames without tenant or profile folders. No folder needs to be created in the S3 console.

Troubleshooting

The connection test returns AccessDenied

Check the Access Key, Secret Key, bucket name, and IAM policy. Also confirm that an AWS Organizations SCP, bucket policy, or permissions boundary does not explicitly deny the operation.

The request returns PermanentRedirect or SignatureDoesNotMatch

First confirm that Region exactly matches the bucket's actual Region. For standard AWS S3, leave Endpoint empty and disable path-style access.

Native upload works but Web upload fails

This normally indicates a CORS issue. Confirm that AllowedOrigins exactly matches the browser's scheme, host, and port; allow PUT and all signed request headers; and expose ETag.

Upload succeeds but opening media returns 403

Leave Public base URL empty for a private bucket. Clear any bucket URL or CDN domain that cannot serve objects anonymously, then test again.

Canceling a multipart upload fails

Confirm that the IAM policy includes s3:AbortMultipartUpload and configure a lifecycle rule to clean up incomplete multipart uploads.

Credentials cannot be updated

Access Key and Secret Key must both be entered or both left empty. When editing an existing configuration, leave both empty to retain the saved credentials.

Security and cost recommendations

  • Keep all Block Public Access settings enabled.
  • Use a dedicated IAM user with least-privilege bucket access and rotate its access key regularly.
  • Never use a root access key or grant AmazonS3FullAccess.
  • Use AWS Budgets and bucket or cost-allocation tags to monitor costs.
  • Do not enable Versioning unless recovery is required; clean up noncurrent versions when it is enabled.
  • Configure lifecycle cleanup for incomplete multipart uploads.
  • Before disabling or deleting credentials, confirm that no object storage configuration still uses them.

AWS references