Sliick Files + Amazon S3: storage setup
Backing Sliick Files with your own Amazon S3 bucket is the cleanest way to keep file bytes out of Salesforce. With S3 storage configured, file bytes travel browser to your bucket directly over short-lived presigned URLs. Salesforce remains the access-control gatekeeper - it decides who can read, write, and delete - but the bytes themselves never land in Salesforce file storage, so they never appear on your Salesforce storage bill.
You enter your S3 credentials once in Sliick Settings and click Connect. Sliick sets up the Salesforce side for you; the only step you do by hand is granting one permission set so your users can use the storage (section 2).
This works with any S3-compatible provider, not just AWS. Backblaze B2, Wasabi, Cloudflare R2 (BYOB), and a self-hosted MinIO all speak the same S3 API. The Salesforce side of the setup is identical regardless of provider - only the provider-side account flow and the endpoint URL differ.
The whole job takes about 15 minutes and costs nothing until you start storing files. S3 standard storage runs at roughly $0.023/GB-month with no upfront cost (pricing current as of June 2026; check AWS’s pricing page for the latest). Below, section 1 covers the AWS side (with S3-compatible equivalents at the end), section 2 is the one-time Salesforce setup, and section 3 is the connect step in Sliick Settings.
1. AWS / S3 provider account setup
These steps happen outside Salesforce, in the AWS Management Console. If you’ve never used AWS before, follow each subsection in order.
Using a different provider? Skip to S3-compatible providers at the bottom of this section for Backblaze B2, Wasabi, Cloudflare R2, and MinIO equivalents. The Salesforce side is identical regardless of provider.
1a. Create an AWS account (skip if you already have one)
- Go to https://aws.amazon.com/ and click Create an AWS Account.
- Provide email, account name, billing info, and verify your phone number. AWS requires a credit card even for the free tier.
- Choose the Basic Support - Free plan when prompted.
- Sign in to the AWS Management Console as the root user.
Security note: don’t use the root user for day-to-day work. After first login, AWS will prompt you to enable MFA on the root account and create an IAM admin user - do both. The rest of this guide assumes you have an admin IAM user (not root) signed in.
1b. Pick a region
Every S3 bucket lives in a single AWS region. Pick the one closest to your Salesforce org and your users - it affects upload/download latency and your Salesforce to S3 callout speed. Common choices:
| Region code | Location |
|---|---|
us-east-1 | N. Virginia (default) |
us-east-2 | Ohio |
us-west-2 | Oregon |
eu-west-1 | Ireland |
eu-central-1 | Frankfurt |
ap-southeast-2 | Sydney |
Write down the exact region code - you’ll enter it as the Region in Sliick
Settings, and it must match the bucket’s region or AWS will reject every signed
request with SignatureDoesNotMatch.
In the top-right of the AWS console, click the region dropdown and select your chosen region. Stay in this region for the rest of section 1.
1c. Create the S3 bucket
- In the AWS console search bar, type S3 and open the S3 service.
- Click Create bucket.
- Bucket name - must be globally unique across all of AWS. Use something
like
sliick-files-acme-prod(lowercase, hyphens, no underscores). Write the exact name down. - AWS Region - confirm it matches the region from step 1b.
- Object Ownership - leave at ACLs disabled (recommended).
- Block Public Access settings - leave all four boxes checked. Sliick Files uses presigned URLs for browser access; the bucket should never be publicly readable.
- Bucket Versioning - Disable. Sliick manages its own version history at the application layer; enabling S3 versioning will silently double your storage costs and complicate deletions.
- Default encryption - leave at SSE-S3 (Amazon S3 managed keys).
- Object Lock - leave Disabled.
- Click Create bucket.
1d. Configure CORS on the bucket (critical for browser uploads)
Without this step, browser-direct uploads from the Sliick LWC will fail with a CORS error in the browser console. Salesforce to S3 callouts from Apex will still work, so the symptom is “uploads from the UI fail but admin diagnostics pass” - easy to misdiagnose.
The same GET rule also powers the photo editor: large images (over the 4 MB
Apex limit) load directly into the canvas via a cross-origin request. Without
GET in the CORS rule - or if your Salesforce origin isn’t listed - large
external images open in view-only mode instead of being editable (editing is
capped at 50 MB).
-
Open the bucket you just created.
-
Go to the Permissions tab.
-
Scroll to Cross-origin resource sharing (CORS) and click Edit.
-
Paste the following JSON. Replace the entries in
AllowedOriginswith your actual Salesforce org domains - list every domain users will upload from (production org, sandboxes, Experience Cloud sites):[ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET", "PUT", "HEAD"], "AllowedOrigins": [ "https://your-org.lightning.force.com", "https://your-org.my.salesforce.com", "https://your-org.sandbox.my.salesforce.com", "https://your-experience-site.my.site.com" ], "ExposeHeaders": ["ETag"], "MaxAgeSeconds": 3000 } ] -
Click Save changes.
Finding your Salesforce domains: in Salesforce Setup → My Domain, the Current My Domain URL and Lightning URL are the two you need for the production org. Sandboxes have their own equivalents. Experience Cloud sites appear in Setup → Digital Experiences → All Sites.
1e. Create an IAM policy
The IAM policy is the JSON document that says “this identity can do these specific things on this specific bucket.” Creating a reusable policy first (rather than inlining permissions on the user) makes rotation and auditing easier.
-
In the AWS console search bar, type IAM and open it.
-
Click Policies in the left sidebar, then Create policy.
-
Switch to the JSON tab and paste the following, replacing
YOUR-BUCKET-NAME(twice) with the exact bucket name from step 1c:{ "Version": "2012-10-17", "Statement": [ { "Sid": "BucketLevelOperations", "Effect": "Allow", "Action": ["s3:ListBucket", "s3:GetBucketLocation"], "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME" }, { "Sid": "ObjectLevelOperations", "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"], "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*" } ] }The two statements split intentionally: bucket-level actions (
ListBucket,GetBucketLocation) need the bare bucket ARN; object-level actions need the/*suffix to scope to objects inside the bucket. WithoutGetBucketLocation, the connection test Sliick runs after you save your credentials may fail. -
Click Next.
-
Policy name -
SliickFilesS3Access(or similar). -
Description - optional, e.g. “Sliick Files access to bucket YOUR-BUCKET-NAME”.
-
Click Create policy.
1f. Create an IAM user and attach the policy
- In IAM, click Users in the left sidebar, then Create user.
- User name -
sliick-files-app(or similar). This user represents the Sliick Files integration, not a person. - Leave Provide user access to the AWS Management Console unchecked - this user only needs programmatic (API) access.
- Click Next.
- Permissions options - choose Attach policies directly.
- Search for the policy you created (
SliickFilesS3Access) and check the box next to it. - Click Next, review, then Create user.
1g. Generate the access key
-
From the user list, click into the user you just created.
-
Go to the Security credentials tab.
-
Scroll to Access keys and click Create access key.
-
Use case - choose Application running outside AWS. (Salesforce is technically a third-party application.)
-
Acknowledge the recommendation banner and click Next.
-
Description tag - optional, e.g. “Sliick Files Salesforce”.
-
Click Create access key.
-
You’ll see the Access key ID and Secret access key.
Copy both now. The secret is shown exactly once - if you close this page without copying it, you must delete the key and create a new one. Paste them into a password manager or keep the tab open until you’ve finished step 3 below.
-
Click Done.
1h. (Optional) Quick sanity check with AWS CLI
If you have the AWS CLI installed, you can confirm the credentials work before plugging them into Salesforce:
AWS_ACCESS_KEY_ID=AKIA... \
AWS_SECRET_ACCESS_KEY=... \
AWS_REGION=us-east-1 \
aws s3 ls s3://YOUR-BUCKET-NAME
If this returns without error (even with empty output - the bucket is empty),
you’re set. If it errors with AccessDenied, the IAM policy is wrong; with
InvalidAccessKeyId, the key didn’t save correctly.
S3-compatible providers (Backblaze, Wasabi, R2, MinIO)
The Salesforce side of setup is identical - only the provider-side flow differs:
| Provider | Credential type | Where to create |
|---|---|---|
| Backblaze B2 | Application Key | Account → App Keys → Add a New Key |
| Wasabi | Access Key | Access Keys → Create New Access Key |
| Cloudflare R2 | API Token (S3-compatible) | R2 → Manage R2 API Tokens → Create Token |
| MinIO/self-hosted | Service Account / User Keys | MinIO Console → Identity → Service Acct |
For each, grant the same four S3 actions (GetObject, PutObject,
DeleteObject, ListBucket) scoped to your bucket. CORS configuration also
applies - every S3-compatible provider exposes CORS settings on the bucket; use
the same JSON from step 1d.
2. Salesforce setup - one-time per org
There is nothing to pre-configure before connecting. The S3_Storage Named and
External Credential are created automatically when you click Connect in
Sliick Settings (section 3) - no URL, region, or principal-secret edits in
Setup. The Salesforce-side work is assigning permission sets.
2a. Assign the Sliick Files permission sets
Sliick Files ships packaged permission sets. Assign them in Setup → Permission Sets, then Manage Assignments → Add Assignment:
- Sliick Files Admin - to admins who configure storage and open Sliick Settings.
- Sliick Files User - to anyone who uploads, views, tags, or shares files.
Without one of these, a user can’t open Sliick Settings or upload files.
2b. Grant the S3 Storage principal on a permission set
The credential Sliick creates at connect isn’t covered by a packaged permission set, so you grant access on a permission set you control:
- Setup → Permission Sets → open (or create) a permission set you manage for storage users.
- Add External Credential Principal Access for the
S3 Storageprincipal (sliick__S3_Storage-Default). - Assign that permission set to anyone who will upload, download, or delete S3-backed files (admins included).
Without this grant, the Connection Test and file downloads fail with a “couldn’t access the credential” error.
You never enter the AWS keys in Setup. They live only in Sliick Settings; the permission set just authorises your users to use the credential.
3. Connect in Sliick Settings
After the one-time setup above, connect the storage. You do this once, and again only if you rotate keys:
- Open Sliick Settings.
- Provider = Amazon S3 (or S3-Compatible / B2 / Wasabi / R2 - same form).
- Paste Access Key ID, Secret Access Key, Bucket Name, and Region from step 1. Endpoint is optional - leave blank for standard AWS S3.
- Click Connect.
Sliick saves your settings and sets up the credential, then leaves the connection awaiting validation. After you complete step 2b, click Test connection. On success the status flips to Active; if the running user lacks the principal grant, the test fails inline with a pointer to the permission-set step.
To rotate keys, update the Access Key ID / Secret in Sliick Settings and reconnect. There is no second copy to maintain.
Data residency (read before enabling the pipeline)
By default your file bytes travel browser to your S3 bucket directly over presigned URLs. Salesforce is the access-control gatekeeper, but the bytes themselves never pass through Sliick-operated infrastructure.
There is one opt-in exception: the Image Processing Pipeline toggle in Sliick Settings. When enabled, newly uploaded image files are routed through Sliick’s processing service (Google Cloud Run) to perform HEIC to JPEG conversion, resizing, and thumbnail generation, and the processed image is then written back to your bucket. While processing:
- Only image content types are routed; non-image files (PDFs, docs, video) and all downloads never transit Sliick.
- The pipeline is off by default and gated per tenant - it does nothing until an admin turns it on here.
- The hop is authenticated (per-tenant HMAC) and the service holds bytes only transiently for the duration of processing; it is not a durable store.
If your data-handling policy requires that image bytes never leave your own infrastructure, leave the pipeline disabled. Uploads still work - images are stored as-is without server-side conversion/thumbnails.
Enabling the image pipeline (optional)
If you do want server-side HEIC to JPEG conversion, resizing, and thumbnails, enable the packaged Sliick Pipeline Integration External Client App once:
- Setup → App Manager (or External Client App Manager) → find Sliick Pipeline Integration → Edit Policies.
- Under OAuth Policies, enable Client Credentials Flow.
- Set Run As User to a dedicated integration user that has the Sliick Pipeline Integration permission set assigned.
- In Sliick Settings, toggle the Image Processing Pipeline on and click Verify.
Pipeline access is gated per tenant. If Verify fails with a “not authorised” message, contact Sliick to enable it for your org.
Troubleshooting
| Symptom (where it appears) | Likely cause |
|---|---|
LWC: Unauthorized endpoint | The connection didn’t finish setting up, or the endpoint is wrong. Reconnect in Sliick Settings. |
LWC: We couldn't access the credential(s) | The running user lacks External Credential Principal access for S3 Storage. Complete step 2a - grant the principal on a permission set you control and assign it. |
AWS: 403 SignatureDoesNotMatch | The Region saved in Sliick Settings doesn’t match the bucket’s region, or the secret is wrong. Re-enter Region + Secret in Sliick Settings and reconnect. |
AWS: 403 InvalidAccessKeyId | The Access Key ID saved in Sliick Settings is wrong or deactivated. Rotate via Sliick Settings. |
AWS: 403 AccessDenied on PUT/GET/DELETE | IAM policy on the access key doesn’t allow that action on this bucket/key. Confirm s3:GetObject / s3:PutObject / s3:DeleteObject are granted on the bucket. |
Browser console: CORS policy: No 'Access-Control-Allow-Origin' header | Bucket CORS is missing or doesn’t list your Salesforce domain. Re-do step 1d and confirm every Salesforce origin (Lightning, My Domain, sandbox, scratch org if developing, Experience site) is in AllowedOrigins. Scratch-org domains look like https://<name>-dev-ed.scratch.lightning.force.com and must be added explicitly - S3 CORS does not support wildcards for subdomains. |
LWC toast or upload-queue row: Could not reach storage from origin "..." | The same CORS rejection above, surfaced inline by cloudUploadService instead of leaving the raw “Failed to fetch” in the DevTools console. Copy the origin from the message and add it to the bucket’s AllowedOrigins. |
| LWC upload succeeds but Apex server-side GET (e.g. photo editor) fails | Upload (browser-direct) needs only the keys in Sliick Settings; server-side GET also needs the S3 Storage principal grant. If uploads work but the editor/download fails, complete step 2a. |
What’s automatic vs. what you do
| Component | Who configures |
|---|---|
| The S3 Storage credential | Automatic - set up for you when you click Connect, no Setup edits |
| Your S3 settings (key, secret, bucket, region) | You enter them once in Sliick Settings |
Permission-set grant for the S3 Storage principal | You add External Credential Principal Access and assign it to your storage users |
We'll audit your architecture, security, and integration posture.