Setting up S3 like an FTP site

May 24, 2025

Helped a client who needed a cheap way to receive large files from a couple of their customers they work with. They current use a monthly service that allows for storing large files, that they can setup to allow certain people to upload into it. With the large files, they receive these so infrequently, with months of no activity. The ongoing cost doesn’t justify the expense of the service and needed something that would be pay for only when they need to use it.

We looked through various options, the only solutions that really fit their need are the cloud-based ones and with those we went with AWS using S3. With S3 they only pay for when they use it, with the storage of the files which are usually only there for a couple of days and then the download fees. To make it somewhat easy for them and their clients to use the program Cyberduck (a free FTP client) allows connecting to a private S3 bucket much like using an FTP site. Their clients would need to follow the instructions in setting up the connection, once setup and saved they can continue to go in and use it by opening the app and double click the bookmark.

On the business owner side, it does involve setting up a folder in the S3 bucket, the user with permissions so they can upload and view the folder assigned to them. The user and permission will be mostly creating a user in IAM and then copy and paste over the permissions and change the folder name from a template I supplied to them.

We have one bucket that only the owner has the full permission overall. Then inside that bucket created 2 folders each assigned a different user that has access just to view and write to that folder; they cannot delete or download. If the business owner needs to get a large file to somebody, they can upload to the main folder, then in Cyberduck right click on the file ‘Copy URL’ then they have choices of pre-signed URLs: 1 hour, 24 hour, 1 week; listed by the date/time they expire. They will need to remember to go in to delete later or we can add a policy to have it auto delete after x amount of time, to help make sure they’re not paying for storage they’re not needing.

This was a rush project they needed done as quickly as possible as the current solution was raising the costs, and they were preparing for the large work that was about to come in from these 2 customers. Some of the items listed above would normally be done when setting up a project like the auto delete. In future iterations we will be looking at updating those and make it more user friendly such as a user interface for the uploading.

Code and info about the code used in creating the permissions:

"s3:ListBucket" = This allows them to see what all is in the bucket, if you have a shared bucket you may want to remove this so they can’t see what else is in there, but this could have them trying to upload more than once.
"s3:GetObject", = This will allow them to download from the bucket
"s3:DeleteObject" = Deletes objects from the bucket, only useful if they would change mind and must alter file and reupload.
"s3:PutObjectAcl" = This controls the access layer of who has permission to do what.

A sample of a permission for a S3 bucket, this would be like the owners permissions.

Change ‘SuperBucket’ to the name of your bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListingOfSuperBucket",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::SuperBucket"
        },
        {
            "Sid": "AllowAllActionsInSuperBucket",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::SuperBucket/*"
        }
    ]
}

Sample of a user with permission to a single folder in the bucket:

{
  "Version": "2012-10-17",
  "Statement": [
     {
       "Sid": "AllowListingOfSuperBucket ",
       "Effect": "Allow",
       "Action": "s3:ListBucket",
       "Resource": "arn:aws:s3::: SuperBucket ",
       "Condition": {
           "StringLike": {
               "s3:prefix": "subfolder/*"
                          }
                      }
       },
       {
         "Sid": "AllowAllActionsInSuperBucket ",
         "Effect": "Allow",
         "Action": [
            "s3:PutObject"
                    ],
          "Resource": "arn:aws:s3:::SuperBucket/subfolder/*"
         }
     ]
}

Pin It on Pinterest

Share This