Skip to content

S3 Express client doesn't resolve cached credentials #257

@joostdebruijn

Description

@joostdebruijn

Describe the bug

I'm trying to write an object to an S3 Express bucket. When I create a S3-client and call putObject with a cached Laravel-config I receive the error: Error retrieving credentials from the instance profile metadata service..

Following the code path I noticed that there is a new S3Client created with temporary credentials:

https://github.com/aws/aws-sdk-php/blob/master/src/Identity/S3/S3ExpressIdentityProvider.php#L42-L52

It seems that this new client doesn't respect the configuration set by Laravels configuration file, but instead starts seeking to credentials which fails.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

The S3-client should work based on the credentials set in config/aws.php for S3 Express as well.

Current Behavior

It works as long as the config is not cached and AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are readable from the environment variables.

Reproduction Steps

  1. Create a S3 Express-bucket
  2. Get a S3-client via the Facade: AwsFacade::createClient('s3')
  3. Try puting a file in the S3 Express-bucket:
$this->client->putObject([
    'Bucket' => $this->bucket,
    'Key' => $path,
    'Body' => $body
]);
  1. It returns an error: Error retrieving credentials from the instance profile metadata service.

Possible Solution

The class Aws\Identity\S3\S3ExpressIdentityProvider has a $config-parameter in the constructor. When initiating this class in Aws\S3\S3Client in the static function _default_s3_express_identity_provider, there is no config given. A possible solution would be to pass an S3-client with the already resolved credentials to the client option.

Another solution would be to initiate the new S3-client in another way to ensure the config of Aws\Sdk as build in the Laravel SDK is honored.

Additional Information/Context

For now I resolved it by setting a custom CredentialProvider:

use Aws\Credentials\CredentialProvider;
use Aws\Credentials\Credentials;
use Aws\Laravel\AwsFacade;

$bootstrapping_client = AwsFacade::createClient('s3');
$result = $bootstrapping_client->createSession([
    'Bucket' => $this->bucket,
]);

$temp_credentials = $result->get('Credentials');
$credentials = new Credentials(
    $temp_credentials['AccessKeyId'],
    $temp_credentials['SecretAccessKey'],
    $temp_credentials['SessionToken'],
    $temp_credentials['Expiration'],
);
$provider = CredentialProvider::fromCredentials($credentials);

$client = AwsFacade::createClient('s3', [
    'region' => $this->region,
    's3_express_identity_provider' => $provider
]);

SDK version used

3.356.32

Environment details (OS name and version, etc.)

Ubuntu 24.04, PHP 8.4.13, AWS SDK PHP Laravel 3.10, Laravel 12.32.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions