Getting security credentials from ec2 role is not allowing java client access - amazon-web-services

I've launched an ec2 instance with a role. The role has the following policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]}
and the role is trusted by ec2.amazonaws.com
On the instance I'm then getting the access key and secret key from a java program by calling
curl http://169.254.169.254/2012-01-12/meta-data/iam/security-credentials/myrole/
I'm then trying to use those credentials to make sns requests.
I'm getting
<ErrorResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<Error>
<Type>Sender</Type>
<Code>InvalidClientTokenId</Code>
<Message>The security token included in the request is invalid</Message>
When I hardcode the credentials with my own keys, the request goes through as expected.

Solved this by using the AWS SDK. The SDK does credential lookup from the role automatically. Alternatively, I could of continued using the old API, if I did an AssumeRole Call
From a faqs page in the documentation that explained it
Q: How do I assume an IAM role?
You assume an IAM role by calling the AWS Security Token Service (STS) AssumeRole APIs (i.e., AssumeRole, AssumeRoleWithWebIdentity, and AssumeRoleWithSAML). These APIs return a set of temporary security credentials that applications can then use to sign requests to AWS service APIs.

Related

How should I permission my AWS Lambdas to be able to query OpenSearch?

I have an AWS OpenSearch cluster configured with an IAM master user role. I have an AWS Lambda which I want to be able to query both OpenSearch and other AWS services like DynamoDB. I don't want to modify the OpenSearch master user role to be able to access other AWS services - it should have zero permissions.
My current solution is letting my Lambda call assumeRole to assume the master user role before querying OpenSearch. Is this the approved way to do it? Seems like it would be more efficient not to have to do the assume role step. And it has the downside that the Lambda then has full access to OpenSearch - I would prefer to give it more granular permissions, e.g. only es:ESHttpGet.
This AWS documentation https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html seems to imply that you can set a resource-based access policy on domain setup which grants permissions to specific users. But I tried creating a maximally permissive policy and I still can't access the domain except as the master role. Am I misunderstanding the docs?
The permissive access policy I tried to use:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:eu-west-1:REDACTED:domain/*/*"
}
]
}
I'm implementing something like that at the moment and it's not quite finished, but I am using API Gateway and a Lambda authoriser function to allow basic authentication. You could try that. The policy I have is almost the same as yours except after domain I have the name of the domain, not a star. I also have vpcs for security locked down to a cidr range.

Lambda http trigger

I created a lambda function in AWS.
I want to trigger it by a API Gateway/http call.
after creating the http trigger i can see the following:
but when I try to use a GET/POST calls to this address I receive "internal server error".
I checked the logs and I see the following:
The IAM role configured on the integration or API Gateway doesn't have permissions to call the integration. Check the permissions and try again.
What should I do? which permission I need?
Quoting from the docs here
When an API is integrated with an AWS service (for example, AWS
Lambda) in the back end, API Gateway must also have permissions to
access integrated AWS resources (for example, invoking a Lambda
function) on behalf of the API caller. To grant these permissions,
create an IAM role of the AWS service for API Gateway type. When you
create this role in the IAM Management console, this resulting role
contains the following IAM trust policy that declares API Gateway as a
trusted entity permitted to assume the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

AWS S3 - Assign limited permission to bucket & create IAM who can access that bucket only

I'm developing a mobile application & i want to upload/get/delete a file in AWS S3 bucket.
But I'm very concern about the security problem.
S3 Bucket: It should not be public and only authorize IAM user can access who have the permission to access my bucket.
So, need help to configure permission of my S3 bucket & create an IAM user.
That is not how you authorize access for mobile applications. Yes, you can create IAM user, generate access key and secret access key, store those keys in the application code and configure right permissions for the IAM user. Then you don't even need to configure bucket policy. By default, bucket is private and only IAM users in your account with appropriate permissions are able to access it. If you allow IAM user to access specific S3 bucket then you would need to configure explicit deny on bucket policy to override it.
But the above approach is against every security good practice. What you really want to do is to create IAM role that allows access to the bucket and assume that role from within the application. You can set up Cognito + web federation (or some other web federation provider) for your users and ask STS service to generate short lived credentials using sts:assumeRoleWithWebIdentity command.
As for the IAM permissions, you will need to allow s3:PutObject, s3:GetObject and s3:DeleteObject so the policy can look something like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "<arn-of-your-bucket>"
}
]
}
You can be even more granular and allow Cognito users to access only "their" folder inside of a bucket if you need to.
As for the role, you just need to attach the above policy to it and configure trust relationship between the role and web identity provider (as mentioned above, this can be Cognito or any OpenID provider).

Issue binding API Gateway to DynamoDB

I'm trying to create a simple ApiGateway on top of a DynamoDB to add a endpoint for users to access the data trough this.
Integration type AWS Service
AWS Region eu-west-1
AWS Service DynamoDB
AWS Subdomain
HTTP method GET
Action ListResources
Execution role [iam arn]
Credentials cache Do not add caller credentials to cache key
Content Handling Passthrough
When I click the test Button i get :
Execution failed due to configuration error: API Gateway does not have permission to assume the provided role
Checked here and there but have no clue on the problem. I tried changing the permissions of the IAM user and gave him all Dynamo and APIGateway rights, but no change.
It seems the issue is linked to the fact that I used a IAM user instead of an IAM Role. I'll leave that here, maybe that will help.
First, update the execution role to use a role rather than an IAM user. Then, ensure that the role has permissions for all of the DynamoDB operations and resources that you want to access. Finally, grant API Gateway permissions to assume that role by adding an IAM trust policy as shown below.
From section "API Gateway Permissions Model for Invoking an API" on documentation page here
When an API is integrated with an AWS service (for example, AWS Lambda) in the back end, API Gateway must also have permissions to access integrated AWS resources (for example, invoking a Lambda function) on behalf of the API caller. To grant these permissions, create an IAM role of the Amazon API Gateway type. This role contains the following IAM trust policy that declares API Gateway as a trusted entity that is permitted to assume the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

How to secure IAM access key with MFA?

I know it is possible to enhance the security by putting another layer (virtual/hardware) MFA over password. Can I secure the access key by MFA.
The problem I am trying to solve is that I would some time commit my access key into github accidentally. so I need a MFA thing for that,
Yes, you can do this by adding a condition to your IAM policies that requires a recent MFA authentication. For example,
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["ec2:*"],
"Resource": ["*"],
"Condition": {"NumericLessThan": {"aws:MultiFactorAuthAge": "3600"}}
}]
}
Allows access to the ec2 Apis if you have authenticated with an MFA in the past hour. There are more examples in the docs.
This requires that you call the GetSessionToken api with your credentials and the MFA code and then use the returned temporary credentials for your actual api calls.
If your code is running on EC2 then you should instead use IAM roles - this sets up credentials available on the instance that are rotated every few hours.