Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssumeRole using STSClient #2178

Closed
2 of 3 tasks
nesar77 opened this issue Dec 28, 2020 · 15 comments
Closed
2 of 3 tasks

AssumeRole using STSClient #2178

nesar77 opened this issue Dec 28, 2020 · 15 comments
Assignees
Labels
closed-for-staleness guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@nesar77
Copy link

nesar77 commented Dec 28, 2020

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
In an eks cluster, using the sdk I'm not able to initialize the s3 client correctly as reported by the guide
https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_assume_role.html

I'm getting the error:
error: "Cannot read credentials from /.aws/credentials" but the ini file is not setted.

Version of AWS SDK for PHP?
3.158.1

Version of PHP (php -v)?
PHP 7.4.13 (cli) (built: Dec 11 2020 08:24:16) ( NTS )

To Reproduce (observed behavior)
`
self::$__stsclient = new StsClient(
[
'profile' => 'arn:aws:iam:instance-profile/pod-role',
'version' => 'latest',
'region' => 'eu-west-1',
]
);
$result = self::$__stsclient->AssumeRole([
'RoleArn' => 'arn:aws:iam::ROLE',
'RoleSessionName' => 'sessionname',
]);

            self::$__client = new S3Client([
                'version'     => 'latest',
                'region'      => 'eu-west-1',
                'credentials' =>  [
                    'key'    => $result['Credentials']['AccessKeyId'],
                    'secret' => $result['Credentials']['SecretAccessKey'],
                    'token'  => $result['Credentials']['SessionToken']
                ]
            ]);`

Expected behavior
I'm not able to use the S3 storage

Additional context
docker image
FROM php:7.4-apache

@nesar77 nesar77 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 28, 2020
@SamRemis
Copy link
Member

SamRemis commented Dec 28, 2020

Hi @nesar77,
You're seeing this because the default provider chain is attempting to get the credentials to provide to your $__stsclient. You can skip checking for the config and credentials provider in the default chain by setting use_aws_shared_config_files to false in the credentials provider:

self::$__stsclient = new StsClient(
[
      'profile' => 'arn:aws:iam:instance-profile/pod-role',
      'version' => 'latest',
      'region' => 'eu-west-1',
      'use_aws_shared_config_files' => false,
]
);

Note that the above will also disable checking for credentials in the config file.

If you would prefer specifying a credentials for the STS client, you could also fix this by setting the credentials variable with hard coded credentials or a specific credentials provider.

@SamRemis SamRemis added the closing-soon This issue will automatically close in 4 days unless further comments are made. label Dec 29, 2020
@nesar77
Copy link
Author

nesar77 commented Dec 29, 2020

Hi @SamRemis,

thanks a lot for your suggestion but I'm still getting the same error.

`{"error":"Cannot read credentials from /.aws/credentials"}
-> Entering step init, name 'idempotency_auto_fill'

command was set to array(3) {
["instance"]=>
string(32) "000000007d9f40fc000000005f5ec550"
["name"]=>
string(10) "AssumeRole"
["params"]=>
array(4) {
["RoleArn"]=>
string(58) "arn:aws:iam::ROLE"
["RoleSessionName"]=>
string(11) "sessionname"
["@http"]=>
array(1) {
["debug"]=>
resource(215) of type (stream)
}
["@context"]=>
array(0) {
}
}
}

request was set to array(0) {
}

-> Entering step validate, name 'validation'

no changes

-> Entering step build, name 'builder'

request.instance was set to 000000007d9f40a3000000005f5ec550
request.method was set to POST
request.headers was set to array(4) {
["X-Amz-Security-Token"]=>
string(7) "[TOKEN]"
["Host"]=>
array(1) {
[0]=>
string(17) "sts.amazonaws.com"
}
["Content-Length"]=>
array(1) {
[0]=>
string(3) "143"
}
["Content-Type"]=>
array(1) {
[0]=>
string(33) "application/x-www-form-urlencoded"
}
}

request.body was set to Action=AssumeRole&Version=2011-06-15&RoleArn=arn%3Aaws%3Aiam%3A%3A348770413080%3Arole%2FROLE&RoleSessionName=sessionname
request.scheme was set to https

-> Entering step build, name 'ApiCallMonitoringMiddleware'

no changes

-> Entering step build, name ''

request.instance changed from 000000007d9f40a3000000005f5ec550 to 000000007d9f415e000000005f5ec550
request.headers.User-Agent was set to array(1) {
[0]=>
string(19) "aws-sdk-php/3.171.0"
}

-> Entering step build, name 'endpoint_parameter'

no changes

-> Entering step build, name 'EndpointDiscoveryMiddleware'

no changes

-> Entering step sign, name 'StreamRequestPayloadMiddleware'

no changes

-> Entering step sign, name 'invocation-id'

request.instance changed from 000000007d9f415e000000005f5ec550 to 000000007d9f4159000000005f5ec550
request.headers.aws-sdk-invocation-id was set to array(1) {
[0]=>
string(32) "7d019691c522fe3d7f5dd7109cdad008"
}

-> Entering step sign, name 'retry'

request.instance changed from 000000007d9f4159000000005f5ec550 to 000000007d9f40a0000000005f5ec550
request.headers.aws-sdk-retry was set to array(1) {
[0]=>
string(3) "0/0"
}

<- Leaving step sign, name 'retry'

error was set to array(6) {
["instance"]=>
string(32) "000000007d9f4158000000005f5ec550"
["class"]=>
string(34) "Aws\Exception\CredentialsException"
["message"]=>
string(46) "Cannot read credentials from /.aws/credentials"
["file"]=>
string(80) "/usr/local/backend/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php"
["line"]=>
int(861)
["trace"]=>
string(6576) "#0 /usr/local/backend/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php(520): Aws\Credentials\CredentialProvider::reject('Cannot read cre...')
#1 /usr/local/backend/vendor/aws/aws-sdk-php/src/Middleware.php(121): Aws\Credentials\CredentialProvider::Aws\Credentials{closure}()
#2 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\Middleware::Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#3 /usr/local/backend/vendor/aws/aws-sdk-php/src/RetryMiddleware.php(275): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#4 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\RetryMiddleware->__invoke(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#5 /usr/local/backend/vendor/aws/aws-sdk-php/src/Middleware.php(206): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#6 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\Middleware::Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#7 /usr/local/backend/vendor/aws/aws-sdk-php/src/StreamRequestPayloadMiddleware.php(83): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#8 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\StreamRequestPayloadMiddleware->__invoke(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#9 /usr/local/backend/vendor/aws/aws-sdk-php/src/EndpointDiscovery/EndpointDiscoveryMiddleware.php(171): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#10 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\EndpointDiscovery\EndpointDiscoveryMiddleware->__invoke(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#11 /usr/local/backend/vendor/aws/aws-sdk-php/src/EndpointParameterMiddleware.php(87): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#12 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\EndpointParameterMiddleware->__invoke(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#13 /usr/local/backend/vendor/aws/aws-sdk-php/src/ClientResolver.php(694): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#14 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\ClientResolver::Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#15 /usr/local/backend/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/AbstractMonitoringMiddleware.php(126): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#16 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\ClientSideMonitoring\AbstractMonitoringMiddleware->__invoke(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#17 /usr/local/backend/vendor/aws/aws-sdk-php/src/Middleware.php(96): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), Object(GuzzleHttp\Psr7\Request))
#18 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\Middleware::Aws{closure}(Object(Aws\Command), NULL)
#19 /usr/local/backend/vendor/aws/aws-sdk-php/src/Middleware.php(80): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), NULL)
#20 /usr/local/backend/vendor/aws/aws-sdk-php/src/TraceMiddleware.php(99): Aws\Middleware::Aws{closure}(Object(Aws\Command), NULL)
#21 /usr/local/backend/vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php(77): Aws\TraceMiddleware->Aws{closure}(Object(Aws\Command), NULL)
#22 /usr/local/backend/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(64): Aws\IdempotencyTokenMiddleware->__invoke(Object(Aws\Command))
#23 /usr/local/backend/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(58): Aws\AwsClient->executeAsync(Object(Aws\Command))
#24 /usr/local/backend/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(86): Aws\AwsClient->execute(Object(Aws\Command))
#25 /usr/local/backend/src/BackEnd/Services/AWSS3.php(281): Aws\AwsClient->__call('AssumeRole', Array)
#26 /usr/local/backend/src/BackEnd/Services/AWSS3.php(222): BackEnd\Services\AWSS3->setClient()
#27 /usr/local/backend/src/BackEnd/Services/CfgReader.php(383): BackEnd\Services\AWSS3->__construct('', '', false, 's3-eu-west-1.am...', 'stage-wmai-file...', 'esperienze', 'eu-west-1')
#28 /usr/local/backend/src/BackEnd/Controllers/Api/ResourceController.php(35): BackEnd\Services\CfgReader->getS3()
#29 [internal function]: BackEnd\Controllers\Api\ResourceController->createAction(Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#30 /usr/local/backend/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(40): call_user_func(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#31 /usr/local/backend/vendor/slim/slim/Slim/Route.php(281): Slim\Handlers\Strategies\RequestResponse->__invoke(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#32 /usr/local/backend/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\Route->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#33 /usr/local/backend/vendor/slim/slim/Slim/Route.php(268): Slim\Route->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#34 /usr/local/backend/vendor/slim/slim/Slim/App.php(503): Slim\Route->run(Object(Slim\Http\Request), Object(Slim\Http\Response))
#35 /usr/local/backend/src/middleware.php(93): Slim\App->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#36 [internal function]: Closure->{closure}(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#37 /usr/local/backend/vendor/slim/slim/Slim/DeferredCallable.php(57): call_user_func_array(Object(Closure), Array)
#38 [internal function]: Slim\DeferredCallable->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#39 /usr/local/backend/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(70): call_user_func(Object(Slim\DeferredCallable), Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#40 /usr/local/backend/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\App->Slim{closure}(Object(Slim\Http\Request), Object(Slim\Http\Response))
#41 /usr/local/backend/vendor/slim/slim/Slim/App.php(392): Slim\App->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#42 /usr/local/backend/vendor/slim/slim/Slim/App.php(297): Slim\App->process(Object(Slim\Http\Request), Object(Slim\Http\Response))
#43 /usr/local/backend/public/index.php(30): Slim\App->run()
#44 {main}"
}

Inclusive step time: 0.00098395347595215

<- Leaving step sign, name 'invocation-id'

no changes
Inclusive step time: 0.0010771751403809

<- Leaving step sign, name 'StreamRequestPayloadMiddleware'

no changes
Inclusive step time: 0.0011389255523682

<- Leaving step build, name 'EndpointDiscoveryMiddleware'

no changes
Inclusive step time: 0.0011889934539795

<- Leaving step build, name 'endpoint_parameter'

no changes
Inclusive step time: 0.0012409687042236

<- Leaving step build, name ''

no changes
Inclusive step time: 0.0013091564178467

<- Leaving step build, name 'ApiCallMonitoringMiddleware'

no changes
Inclusive step time: 0.0013809204101562

<- Leaving step build, name 'builder'

no changes
Inclusive step time: 0.0017709732055664

<- Leaving step validate, name 'validation'

no changes
Inclusive step time: 0.0029380321502686

<- Leaving step init, name 'idempotency_auto_fill'

no changes
Inclusive step time: 0.003201961517334

`

@SamRemis
Copy link
Member

@nesar77, would you be able to post the code that you're using to initialize the clients? That way I could potentially reproduce it on my local- I haven't been able to yet.

@nesar77
Copy link
Author

nesar77 commented Dec 29, 2020

Hi @SamRemis ,

this is my code

@github-actions github-actions bot removed the closing-soon This issue will automatically close in 4 days unless further comments are made. label Dec 30, 2020
@SamRemis
Copy link
Member

SamRemis commented Dec 30, 2020

Hi @nesar77,
I think I see what's going on. You're using 'profile', which calls the _apply_profile function. This should have been caught by the SDK when you set use_aws_shared_config_files to false since they are incompatible. It tries to read data from that profile you specified in the credentials file, which right now doesn't exist. The profile in the client constructor is used to read from the config/credentials files. I'm not sure how you're trying to apply the role under 'profile', but the first step is going to be deleting it from the client constructor.

@nesar77
Copy link
Author

nesar77 commented Jan 4, 2021

Hi @SamRemis ,

working on your suggestion.
I'd like to assume the role used by a pod in a eks cluster: initializing an s3 client does not allow me to check if the assumed role is correct.

Using the following code returns an access denied error

               self::$__client = new S3Client([
                   'version'     => '2006-03-01',
                   'region'      => 'eu-west-1',
                   'debug'   => true
               ]);
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>0E6A1C4FD6DCE7CB</RequestId><HostId>O32exxVuPq3Q763HgFYINolBJN1UIanyKxpmPxgs28xUk0mSmjMizmXPYxR1n5C+ltn8ZbKZSuQ=</HostId></Error>
#0 /usr/local/backend/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php(97): Aws\WrappedHttpHandler->parseError(Array, Object(GuzzleHttp\Psr7\Request), Object(Aws\Command), Array)
#1 /usr/local/backend/vendor/guzzlehttp/promises/src/Promise.php(204): Aws\WrappedHttpHandler->Aws\{closure}(Array)

this is the detailed error

Using the following example the sts client is looking for the credential file but I've setted the param use_aws_shared_config_files to false.

@SamRemis
Copy link
Member

SamRemis commented Jan 4, 2021

@nesar77 It appears that the detailed error link is broken. The access denied error suggests you are using invalid credentials. The fact that it occurs in the WrappedHttpHandler on line 97 tells me that your request was sent successfully but rejected by the service (so you didn't have access to STS or S3 with the credentials given).

As for as the use_aws_shared_config_files input parameter goes, it can be overridden by using either the profile or the credentials client configurations, so be sure that those are not set. This applies to both the S3Client and the StsClient that you are initializing/

@nesar77
Copy link
Author

nesar77 commented Jan 4, 2021

Hi @SamRemis ,
well.. using aws cli on pod I'm able to upload or delete an object in the bucket; I've tested the policies and they work fine.
So I'm able to use the s3 bucket using console but not by code.

Here is a new hastebin url .
Thank you so much for your time.

@SamRemis
Copy link
Member

SamRemis commented Jan 4, 2021

I'm not sure what's going on since I don't have access to the source to see how you're using the credentials. To me, it just looks like something is blocked using the bucket policy or bad credentials. If you post the code for your client constructors, I may be able to see more. It's likely that your CLI is using different credentials than your SDK.

The stack trace just says that the request went out properly and S3 returned an error response with access denied.

@nesar77
Copy link
Author

nesar77 commented Jan 5, 2021

This is the constructor:
` public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = null, $bucketname = null, $basepath = null, $region = 'eu-west-1')
{
if (($accessKey !== null && $accessKey !== "") && ($secretKey !== null && $secretKey !== "")) {
self::setAuth($accessKey, $secretKey);
self::$__accessKey = $accessKey;
self::$__secretKey = $secretKey;
}

    self::$useSSL = $useSSL;
    self::$endpoint = $endpoint;
    if ($basepath !== null)
        self::setBasepath($basepath);

    if ($bucketname !== null)
        self::setBucketname($bucketname);

    if ($region !== null)
        self::setRegion($region);
}`

and this is the setClient function, the value of hasAuth() is false

public function setClient() { //Se sono in possesso delle credenziali mi autentico, altrimenti uso il ruolo associato all'utenza try { if (self::hasAuth()) { self::$__client = new S3Client([ 'version' => 'latest', 'region' => $this->getRegion(), 'credentials' => [ 'key' => self::$__accessKey, 'secret' => self::$__secretKey, ], ]); } else { self::$__client = new S3Client([ 'version' => '2006-03-01', 'region' => $this->getRegion(), 'debug' => true ]); } } catch (AwsException $e) { echo $e->getMessage(); echo "\n"; } }

@SamRemis
Copy link
Member

SamRemis commented Jan 8, 2021

The S3 client constructor that is in the else statement could be why you're still seeing it attempting to access those files. Either specify a credentials provider there, or add the use_aws_shared_config_files = false and let it go through the default chain without it.
Consider putting a print statement after your constructor to double check that you're using the same credentials that worked on the CLI. The SDK doesn't modify the credentials you supply, so my guess is that you have credentials somewhere else that are being supplied.

@oikosengineering
Copy link

Hi @SamRemis ,
I've commented the else statement and the ctor is:
`
public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = null, $bucketname = null, $basepath = null, $region = 'eu-west-1')
{
// if (($accessKey !== null && $accessKey !== "") && ($secretKey !== null && $secretKey !== "")) {
// self::setAuth($accessKey, $secretKey);
// self::$__accessKey = $accessKey;
// self::$__secretKey = $secretKey;
// }

    self::$useSSL = $useSSL;
    self::$endpoint = $endpoint;
    if ($basepath !== null)
        self::setBasepath($basepath);

    if ($bucketname !== null)
        self::setBucketname($bucketname);

    if ($region !== null)
        self::setRegion($region);

    // $this->setClient();
}

`
and I'm still getting the same access denied error.

@ajredniwja ajredniwja self-assigned this Jul 8, 2021
@ZT00OK53
Copy link

ZT00OK53 commented Jan 3, 2022

I am getting access denied error using AWS PHP SDK
I followed the complete AWS document reference https://docs.aws.amazon.com/code-samples/latest/catalog/php-sts-AssumeRole.php.html

$stsClient = new Aws\Sts\StsClient([
'profile' => 'default',
'region' => 'us-west-2',
'version' => '2011-06-15'
]);

$ARN = "MyARN Role";
$sessionName = "get_files_session";

$result = $stsClient->AssumeRole([
'RoleArn' => $ARN,
'RoleSessionName' => $sessionName,
]);
dd($result);
$s3Client = new S3Client([
'version' => '2006-03-01',
'region' => 'us-west-2',
'credentials' => [
'key' => $result['Credentials']['AccessKeyId'],
'secret' => $result['Credentials']['SecretAccessKey'],
'token' => $result['Credentials']['SessionToken']
]
]);

Exception:
image

@ajredniwja ajredniwja assigned SamRemis and stobrien89 and unassigned ajredniwja and SamRemis Mar 16, 2022
@stobrien89 stobrien89 added guidance Question that needs advice or information. and removed needs-triage This issue or PR still needs to be triaged. bug This issue is a bug. labels Mar 23, 2022
@stobrien89
Copy link
Member

stobrien89 commented Mar 23, 2022

Hi everyone,

Can you confirm if you're still experiencing this issue? If so, can you also confirm whether or not instantiating a Credentials object or using the STS helper method to do the same as described in this documentation resolves the issue? Thanks!

@stobrien89 stobrien89 added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Mar 23, 2022
@github-actions
Copy link

This issue has not recieved a response in 1 week. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added closing-soon This issue will automatically close in 4 days unless further comments are made. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Mar 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-for-staleness guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

6 participants