Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

guezandy's avatar

L5.1 Upload file to AWS S3 using filesystem AWS PERMISSIONS PROBLEM I think

It seems awesome that Laravel made it so much easier to use alternate storage systems. Following this guide: http://laravel.com/docs/5.1/filesystem#introduction

I was able to upload a file locally (storage->app) by doing:

  public function store() {
    \Storage::disk('local')->put('file.txt', 'Contents');
    return "Done";
  }

I added this to my composer.json and updated:

        "league/flysystem-aws-s3-v3": "~1.0"

Next i updated my config->filesystem file:

        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_KEY'),
            'secret' => env('AWS_SECRET'),
            'region' => env('AWS_LOCATION'),
            'bucket' => 'bucket_name',
        ],

Changed my controller method to:


  public function store() {
  //  \Storage::disk('local')->put('file.txt', 'Contents');
    \Storage::disk('s3')->put('file.txt', 'Contents');
    return "Done";
  }

This is the error i get:

S3Exception in WrappedHttpHandler.php line 152:
Error executing "HeadObject" on "https://s3.amazonaws.com/testrbucket/file.txt"; AWS HTTP error: Client error: 403 (client): 403 Forbidden (Request-ID: BF4C61A3B6218425) 

Anyone got something similar?

0 likes
6 replies
sieabah's avatar

So, funny thing with v3 that no one documented anywhere is that you need to have the 'credentials' => [ 'key', 'secret'] config set when creating the S3Client. I've been spending hours debugging getting FlySystem to work with Google Cloud Storage but running into a lot of road blocks.

guezandy's avatar

hey @sieabah is that in the filesystem.php like this:

        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_KEY'),
            'secret' => env('AWS_SECRET'),
            'region' => env('AWS_LOCATION'),
            'bucket' => 'testrbucket',
            'credentials' => [ env('AWS_KEY'), env('AWS_SECRET')], 
        ],

I tried above and nothing changed. Can you give me a little more insight?

opilo's avatar

I'm having the exact same problem. I tried to use the adapter directly and it worked:

$this->filesystem->disk('S3')->getAdapter()->getClient()->putObject([
            'SourceFile' => $fileToUpload,
            'Key'        => $finalFileName,
            'ACL'        => $visibility,
            'Bucket'     => $bucket
        ]);
opilo's avatar

I solved the problem by changing the permission policy in IAM. Here's my policy:

"Statement": [
        {
            "Sid": "Stmt11111111111111111",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::bucket_name",
                "arn:aws:s3:::bucket_name/*"
            ]
        }
    ]

Adding arn:aws:s3:::bucket_name in addition to arn:aws:s3:::bucket_name/* fixed the problem.

3 likes
SpAwN_gUy's avatar

Changing the IAM policy to "s3:*" solved the problem of uploading with public and private ACL. This set of actions is now enough to upload a file and add Public-Read acl.

{
            "Sid": "AppBucketAccess",
            "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:HeadObject*",
                "s3:PutObject*",
                "s3:DeleteObject"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::testbucket",
                "arn:aws:s3:::testbucket/*"
            ]
        }

just a few stars.

1 like

Please or to participate in this conversation.