Search code examples
laravelamazon-web-servicesamazon-s3amazon-iamlaravel-filesystem

AWS AssumeRole with Laravel Filesystem


I'm currently trying to figure something out. I have 2 AWS Accounts. Account A has a bucket called my_awesome_files. Account B has users, that would like to be able to see those documents in my_awesome_files.

I have the following policies and roles setup:

Account A (the one who has the bucket): role: allow-account-b-access-s3-bucket-role policy:

{
    "Statement": [
        {
            "Action": "s3:GetObject",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my_awesome_files"
            ]
        }
    ],
    "Version": "2012-10-17"
}

policy: (trusted entities)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<account_id_account_b>:root"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Account B (the one who wants to have access to the bucket): Has a user with this attached Policy:

{
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Resource": "arn:aws:iam::<account_id_account_a>:role/allow-account-b-access-s3-bucket-role"
        }
    ],
    "Version": "2012-10-17"
}

If I read the documentation correctly, this should work.

Now to my questions:

  1. Is this indeed correct, or am I missing something?
  2. If it is indeed correct iam-configuration: Am I missing something with my laravel s3 config?

Do I need some special fancy configuration for it to get that it needs to assume that role or to make it work? Currently, the filesystem config looks like this:

'my_awesome_files_bucket_config' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID', 'xxxx'),
    'secret' => env('AWS_SECRET_ACCESS_KEY', 'xxxx'),
    'region' => env('DEFAULT_REGION', 'eu-central-1'),
    'bucket' => env('MY_AWESOME_FILES_BUCKET', 'xxxx')
]

Solution

  • So I kind of figured it out. The policies are correct, but laravel filesystem automatically does not assume roles (obviously) and I didn't find a way to configure it to do so. (This would actually be a nice feature to the Filesystem lib)

    So my solution was: using directly the AWS SDK to get the correct credentials, and then fetch the files from s3. This looks like this:

    $stsClient = new StsClient([
        'region' => 'eu-central-1',
        'version' => '2011-06-15',
        'credentials' => [
            'key'    => $access_key_id,
            'secret' => $secret_access_key ,
        ],
    ]);
    
    $sessionName = "s3-access";
    
    $result = $stsClient->AssumeRole([
        'RoleArn' => $ARN,
        'RoleSessionName' => $sessionName,
    ]);
    $access_key_id = $result['Credentials']['AccessKeyId'];
    $secret_access_key = $result['Credentials']['SecretAccessKey'];
    $session_token = $result['Credentials']['SessionToken'];
    

    Then the fetching of the file is as easy as reading documentation:

    $s3Client = new S3Client([
        'version'     => '2006-03-01',
        'region'      => 'eu-central-1',
        'credentials' =>  [
            'key'    => $access_key_id,
            'secret' => $secret_access_key,
            'token'  => $session_token
        ]
    ]);
    
    $private_file = $s3Client->getObject([
        'Bucket' => env('BUCKET_NAME'),
        'Key' => 'filename.txt',
    ]);