Issue using an IAM role with PHP SDK - php

I am using this script to populate DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LoadDataPHP.html
I'm getting this error using the AWS SDK:
PHP Fatal error: Uncaught exception
'Aws\Exception\CredentialsException' with message 'Cannot read
credentials from /root/.aws/credentials' in
/var/www/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:263
According to https://docs.aws.amazon.com/aws-sdk-php/v2/guide/credentials.html
If you do not explicitly provide credentials to the client object and no environment variable credentials are available, the SDK attempts to retrieve instance profile credentials from an Amazon EC2 instance metadata server. These credentials are available only when running on Amazon EC2 instances that have been configured with an IAM role.
I have an IAM role attached to my instance with full power user access. I have confirmed the role is working fine via the AWS CLI, which can access DynamoDB without any credential configuration.
Any suggestions as to what I could be doing wrong? I am under the impression (and interpret that credentials document to say) that I don't need to configure any credentials, hence the use of the IAM role.

I just wanted to expand a bit on this for anyone else that may end up in this situation.
If you use an IAM role on a EC2 instance as your method of credentials
Then don't use the profile line when creating a client. If you do specify profile in your client it tells the SDK to override any form of credentials you set in the client with a profile from the credentials ini file.
Mentioned (but buried a bit) in the PHP SDK V3 documentation here:
https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#profile
Example Code
$client = new SqsClient([
'profile' => 'default', // <--- Don't use this line if you're using IAM Roles for credentials
'region' => 'us-west-2',
'version' => '2012-11-05'
]);
Misleading Documentation
The PHP SDK documentation recommends using IAM roles above all other credentials for EC2 instances. That's fine and makes total sense. The misleading part to new comers is for example this scenario;
Say someone new to the SDK reads the Basic SDK Usage in the getting started section.
Sets up a S3 client for testing as per the docs.
Once they have working S3 code, the developer decides to skip to the code examples section to setup a client for a different AWS service.
The problem here is that all of the code examples (with the exception of the S3 examples) contain the profile setting that breaks the IAM role credential method.
The code examples should at least have a reference to what profile does.

This line in the code:
'profile' => 'default',
is what was causing my issue. If you are using an IAM role you do not require the profile line, and removing it will fix the "Cannot read credentials" error.

Related

Connection refused for URI https://www.googleapis.com/oauth2/v4/token

I am new to GoogleAPIs and Laravel, I run a PHP web application on Laravel 8 in a virtual Linux environment. Socialite and Drive API was working fine and out of sudden it doesn't work anymore and always return connection refused error after long period of loading as follows:
GuzzleHttp\Exception\ConnectException
Connection refused for URI https://www.googleapis.com/oauth2/v4/token
I had tried to create a new credential with new refresh token and checked all the network settings, and always clear config cache and restart apache for all troubleshoots I have tested, yet the error still exists.
I would appreciate it much if anyone could enlighten me on what are the aspects I shall look into it.
There are multiple issues in this question.
First and foremost, you are sending your secret to a third party. This means that they are able to do any API calls as you (using your name and quotas). Even if they claim that they won't, they can. Please remove any secret you may have and create new ones.
As for the OAuth 2.0, you seem to be using an old URL. You should probably take a look into the official documentation for:
Using OAuth 2.0 to Access Google APIs for a basic explanation.
Using OAuth 2.0 for Web Server Applications for making a web and getting permissions to get/modify a user's data (can be yourself).
Using OAuth 2.0 for Server to Server Applications for using a service account to execute as one of the users on your organization, without the need of manually giving permission.
Also notice that there are PHP libraries officially supported by Google to make your life way easier. See the Drive API's PHP Quickstart.

Symfony 4 & Amazon S3 - AWS credentials not working

I have a Symfony 4 project that is deployed to the Digital Ocean Ubuntu server.
In order to store files, I am using Amazon S3 bucket.
I've used aws/aws-sdk-php library to interact with the Amazon S3 bucket.
I've created the global credentials file at ~/.aws/credentials and managed to make it work.
The problem is that it doesn't work on the server.
I copied the credentials file to the server's ~/.aws/ directory, but I am getting this error.
Error retrieving credentials from the instance profile metadata server. (Client error: `GET http://169.254.169.254/latest/meta-data/iam/security-credentials/` resulted in a `404 Not Found` response: not found)
I did some research on this error - it seems that the php server isn't finding the credentials file.
How do I fix this?
All AWS SDKs search for credentials from various sources in a specific order of priority. You can see this order in the boto3 documentation.
Typically, if the SDK is unable to find any credentials from any of the sources in which it searches, then it reports an error retrieving credentials from the final credential provider in its search list, and that's usually (and perhaps always) STS credentials from the instance metadata service.
In your case, you're not even running on AWS so the instance metadata service is not relevant and the error message you see is a red herring.
Here is what I suspect is happening: you are trying to supply credentials via a ~/.aws/credentials file but the AWS PHP SDK is not finding credentials there. So, one of the following may be happening:
your PHP application is running as a different Linux user and hence its home directory is not the same as the one you placed the .aws/credentials file in
your ~/.aws/credentials file is invalid in some way or has zero credentials in it (unlikely, I would say)
My vote is on #1.

Using an IAM service role for credentials in AWS services with PHP

I have a PHP application running on elastic-beanstalk that uses some of AWS services, like S3, RDS and SES.
I’m currently doing exactly what they don’t recommend, which is to hard code my credentials when I initialize a client for any of those services.
Code looks like below:
$s3 = new S3Client([
'region' => 'us-west-2',
'version' => 'latest',
'credentials' => [
'key' => ‘**********’,
'secret' => ‘******************’,
],
]);
I’m trying to move away from this and there’s plenty of AWS documentation on how to proceed but almost no examples that I could find.
I’m considering using an IAM service role that has all the right policies attached to it.
The steps are:
In the elastic beanstalk instance, the service role associated with that instance is aws-elastic-beanstalk-role
I attached all necessary policies to that service role for all the different services that I use. That was done from the management console.
Now how would I refer to the credentials in the client initialization like above? I honestly could not find an example on how to do it. I'm using AWS SDK for PHP version 3.0.
Thanks for any pointers.
Just remove the credentials field from your s3 client parameters.
The Details
If you do not explicitly provide credential values, the AWS SDK will go through the default credential providers chain to try and find the credentials.
It looks for credentials in this order:
Environment Variables
Profile or Config files on the file system
Assumed Roles (via EC2 instance profiles, Lambda roles, etc)
Assuming you don't have any environment variables or profiles configured, the SDK will use the role attached to your EC2 instance to sign requests with.

Possible to Sign In as a Cognito User Pool user using AWS SDK for PHP version 2?

I'm trying to write some code in our PHP application that currently uses the AWS SDK for PHP version 2.8.31 to essentially sign in a user that's in a Cognito User Pool so that we can then use that user's identity to call AWS API Lambda methods. The API Gateway will use Cognito as the authorizer.
The problem I'm having is that all the examples I'm finding online for getting this done are using version 3 of the PHP SDK that has the CognitoIdentityProviderClient class that provides the adminInitiateAuth method that gets the Access Token that you need to call the API Gateway with.
Is there a way to do this with the v2 of the AWS SDK for PHP (https://docs.aws.amazon.com/aws-sdk-php/v2/guide/)?
The CognitoIdentityClient seems like it might be the way, but the only relevant methods I see are getId and then getCredentialsForIdentity, but these still don't get me the Access Token I need to pass to the API Gateway. I can also see GetOpenIdToken and GetOpenIdTokenForDeveloperIdentity but the 'IdentityProviderName' parameter that they are asking for doesn't seem to support Cognito User Pool as the provider?
I'm just hoping that someone out there knows a enough about these methods to let me know if this is even possible with the V2 of the SDK.

S3 S3EncryptionClient AWS SDK for PHP: Error retrieving credentials from the instance profile metadata server

For my connection I am using Use the AWS shared credentials file default profile. I have .aws/credentials setup containing aws_access_key_id aws_secret_access_key. This works fine for localhost to S3 connectivity using S3Client.
However, I want to do client side encryption/decryption using S3EncryptionClient and here is where the problems start. Using PHP 3.6 and aws-sdk-php 3.5. I had to manually install Crypto directories since for whatever reason composer would not get them even though as far as I understand support was added in v3.38.
putObject following Amazon S3 Client-Side Encryption with the AWS SDK for PHP Version 3 example fails with "Error retrieving credentials from the instance profile metadata server". I am using the same user, key, secret in both cases when using S3Client or when using S3EncryptionClient. I assume KmsMaterialsProvider does not require 'credentials' => $provider to be specified, but I have tried that as well.
Edit:
Tried the same in IAM Policy Simulator. Perhaps policy is not setup correctly. But not quite sure what is required. Tried a bunch of different variations without any success. Keep getting "denied Implicitly denied (no matching statements)." for actions such as: Encrypt, Decrypt even though policy has these actions. Is the problem that I am doing this from my local machine? But then I would have thought it would fail the same way for non encrypted write/reads.
Figured this out, in case anyone runs into the same issue as it looks like at least a few people did without an answer. Creating KmsClient on dev environment (localhost) needed to specify 'credentials' => $provider, even if already specified for S3EncryptionClient . Also make sure that permission policy is setup for the key and KMS service.

Categories