Setting up an Amazon S3 bucket for Shareboxed
Shareboxed uploads straight into a bucket you own. Files keep their own names and stay visible in your console. This guide sets one up with the AWS CLI, and shows the same for Cloudflare R2, Backblaze B2 and MinIO.
AWS S3
1. Create the bucket
aws s3api create-bucket --bucket my-uploads --region eu-west-1 \
--create-bucket-configuration LocationConstraint=eu-west-1
Leave Block Public Access on (the default).
2. Create an IAM user
Save this as shareboxed-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListForTheConnectionTest",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-uploads"
},
{
"Sid": "WriteAndTakeBack",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::my-uploads/*"
}
]
}
aws iam create-user --user-name shareboxed
aws iam put-user-policy --user-name shareboxed \
--policy-name shareboxed-uploads \
--policy-document file://shareboxed-policy.json
3. Create the access key
aws iam create-access-key --user-name shareboxed
The output shows AccessKeyId and SecretAccessKey once. Paste them into the
Credentials fields of the connection in Shareboxed:
| Field | Value |
|---|---|
| Endpoint | https://s3.eu-west-1.amazonaws.com |
| Region | eu-west-1 |
| Credentials | the AccessKeyId and SecretAccessKey |
4. Optional: abort incomplete uploads
Shareboxed aborts a failed multipart upload itself, but a crash or power-off cannot:
aws s3api put-bucket-lifecycle-configuration --bucket my-uploads \
--lifecycle-configuration '{"Rules":[{"ID":"abort-incomplete","Status":"Enabled","Filter":{},"AbortIncompleteMultipartUpload":{"DaysAfterInitiation":7}}]}'
5. Optional: delete uploads after 7 days
aws s3api put-bucket-lifecycle-configuration --bucket my-uploads \
--lifecycle-configuration '{"Rules":[{"ID":"expire","Status":"Enabled","Filter":{"Prefix":""},"Expiration":{"Days":7}}]}'
Cloudflare R2
R2 has its own connection type in Shareboxed that asks for an account id instead of an endpoint; see the Cloudflare R2 guide. To use it as a plain S3 connection anyway:
npx wrangler r2 bucket create my-uploads
Create a token under R2 → Manage R2 API Tokens with Object Read & Write on that bucket.
| Field | Value |
|---|---|
| Endpoint | https://<account-id>.r2.cloudflarestorage.com |
| Region | auto |
| Credentials | the token's Access Key ID and Secret Access Key |
Backblaze B2
b2 bucket create my-uploads allPrivate
b2 key create --bucket my-uploads shareboxed \
listBuckets,listFiles,readFiles,writeFiles,deleteFiles
The second command prints the keyID and applicationKey once.
| Field | Value |
|---|---|
| Endpoint | https://s3.us-west-004.backblazeb2.com (the region shown on your bucket) |
| Region | the matching region, e.g. us-west-004 |
| Credentials | the keyID and applicationKey |
MinIO, on your own machine or NAS
docker run -d --name minio -p 9000:9000 -p 9001:9001 \
-e MINIO_ROOT_USER=admin -e MINIO_ROOT_PASSWORD=change-me-please \
-v ~/minio-data:/data quay.io/minio/minio:latest server /data --console-address ":9001"
| Field | Value |
|---|---|
| Endpoint | http://127.0.0.1:9000 |
| Region | us-east-1 |
| Credentials | the root user and password, or a key made in the console on :9001 |
Over plain http the traffic is unencrypted. On a LAN that may be fine; over
the internet, put it behind TLS.
Turning on Shareboxed download links
Off by default. With the switch on (connection settings → Sharing),
finishing an upload also copies a shareboxed.app link anyone can download
from. A link lives seven days, like every Shareboxed share; switching the
setting off deletes the stored key and ends every live link from this
connection at once.
The bucket needs two things for those links to work.
1. Let the key read back what it wrote. Add s3:GetObject to the second
statement in shareboxed-policy.json and push the policy again:
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
]
aws iam put-user-policy --user-name shareboxed \
--policy-name shareboxed-uploads \
--policy-document file://shareboxed-policy.json
2. Allow the download page to read the bytes (CORS):
aws s3api put-bucket-cors --bucket my-uploads \
--cors-configuration '{"CORSRules":[{"AllowedOrigins":["https://shareboxed.app"],"AllowedMethods":["GET","HEAD"],"AllowedHeaders":["*"],"MaxAgeSeconds":3600}]}'
R2, B2 and MinIO have an equivalent CORS setting; the rule is the same.
When something does not work
Press Test Connection first. What it can say:
| Test Connection says | Fix |
|---|---|
| Missing credentials | The Credentials fields are empty or were not saved. Enter the key and secret again. |
| Invalid endpoint | The Endpoint is not an address. Use the full https:// URL. |
| Not reachable | Nothing answered at the endpoint. Check the address and the port. |
| Incorrect region | The Region field does not match the bucket's region. |
| Invalid credentials | The access key or the secret is wrong. |
| Insufficient permissions | The key works but the policy does not allow s3:ListBucket on this bucket. |
| Bucket not found | Typo in the bucket name, or the endpoint points at the wrong region. |
| Missing CORS rule | Download links are on but the bucket has no CORS rule for https://shareboxed.app. |
| Server errored | The storage service itself failed. Try again, and check the provider's status page. |
Two more that only show up later:
- Test passes, uploads fail with Check the access key, the secret and its
permissions: Test Connection only ever reads, so it cannot see a key that
may list but not write. Check that the second statement in the policy names
arn:aws:s3:::my-uploads/*with the/*and the same bucket name as the first. On R2 the usual cause is a token created as Object Read only, on B2 a key withoutwriteFiles. - A recipient sees "Connection refused, please ask the sender to check on
the permissions": the CORS rule is missing or does not allow
GETfromhttps://shareboxed.app. A recipient who sees "Unable to access these files" clicked a file the cleanup rule from step 5 already deleted; the link itself is fine.