Skip to content
Shareboxed

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 without writeFiles.
  • A recipient sees "Connection refused, please ask the sender to check on the permissions": the CORS rule is missing or does not allow GET from https://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.