How to authorise a role to perform "execute-api:Invoke"? - amazon-web-services

I'm attempting to move a suite of end-to-end tests so that they are fully contained within AWS. I've done this through code build and gotten everything running up to the point of running the tests, which invoke an API to reset the database before every test run. I keep running into this error message when the first test attempts to run.
StatusCodeError: 403 - "{\"Message\":\"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:eu-west-2:*:*"}"
At first, I thought the error was being caused by a lack of permissions on the role that was being used to build everything. I tried adding the correct permissions to IAM Role being used, eventual making them more open than I would like.
"Effect": "Allow",
"Action": [
"execute-api:Invoke",
"execute-api:ManageConnections"
],
"Resource": "arn:aws:execute-api:*:*:*"
Obviously didn't fix things but I did notice that the access advisor shows that the particular policy isn't being accessed.
Next, I went into the resource policy in API Gateway to see if there was something there. I removed some Ip Address conditions that were set up to restrict access to the office's Ip Addresses.
I've look inside of WAF and Shield and can't see anything that would be related to invoking the API. At this point I am at a lost on where my next investigation should start.
Edit
Here's the responce I'm getting back.
"requestId": "********-82f8-11e9-a732-0b550cf3fcd6",
"ip": "*.*.*.*",
"caller": "-",
"user": "-",
"requestTime": "30/May/2019:16:32:50 +0000",
"httpMethod": "GET",
"resourcePath": "/*/ref-data/{proxy+}", "status": "403", "protocol": "HTTP/1.1", "responseLength": "185"

Below are the steps you need to perform.
For API method - Make Auth = IAM
For API resource policy make sure you allow traffic coming from selected IAM role for specific/all methods
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::###############:role/###########"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-southeast-1:###########:/#########/*/POST/####/####/"
}
]
}
Make sure same IAM role is attached to entities from where this API is being called e.g. EC2 - if your code resides on EC2
Make sure your API calls are not plain curl calls, they are aws sigv4 signed
Hope this works!

In this case it turned out the major blocker was the API gateway IP Restrictions set in the policy were getting in the way. I did not realise that changes made didn't take affect until (re)deployment. Once I did that with updated IP restrictions the API endpoint could be invoked.

Your role's policy which allows execute-api:Invoke appears to be correct, but the error message you provided says User: anonymous is not authorized to perform.... If you're expecting your role to be attempting this action, then something is wrong because your attempting the action with a user named anonymous.
The role that you use to build your stack isn't necessarily the role that is used to execute functions on that stack. I recommend you double check all of your IAM entities throughout and clearly identify and understand what each one is attempting to do. Make sure that whatever is invoking your function is actually the role you want with the correct policy attached.
Hope this helps!

Related

Adding wildcard cert to Lightsail instance fails (IAM issue)

I'm following this guide (Method 1, step 5) in order to configure Let's Encrypt wildcard certification to my domain, which is controlled by Lightsail DNS.
Making sure all the previous steps have been successfully completed, I am still facing in issue with the fifth-step, where generating the certifications apparently lacks authorization. I made the user to AWS IAM service, as was guided, with a custom permission rule that should suffice, according to the docs:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lightsail:DeleteDomainEntry",
"lightsail:CreateDomainEntry"
],
"Resource": "<Lightsail DNS zone ARN>"
}
]
}
The error message I get bounced with reads as follows:
Message_: User: arn:aws:iam::MY_USER_ID:user/Certbot is not authorized to perform: lightsail:CreateDomainEntry on resource: arn:aws:lightsail:us-east-1:MY_USER_ID:* because no identity-based policy allows the lightsail:CreateDomainEntry action
Note: I have tried to use the full arn path pointing to my domain directly, but decided to give the wildcard selection a go - no luck there, though.
I also tried to simulate these user roles within IAM, but the actions are denied there as well (Implicitly denied, no matching statements).
Any idea why this is, and what could I do to make this pass? Didn't manage to find any answers related to this issue neither, so now I'm here. I have tried this process with a different IAM user, with full administrative privilidges, and no issues what so ever. But as this is very risky and not ideal at all, I would like to get this to work with the so called "minimum privlidges".
Any help is greatly appreciated!

AWS IAM Policy applying restrictions to managed instances -- invalid ARN?

I'm facing some very weird issues when it comes to policies and managed instances. For example, one of my users is getting this error:
User: arn:aws:iam::708332864XX:user/XXXX is not authorized to perform: ssm:StartSession on resource: arn:aws:ssm:us-east-2:708332864XX:managed-instance/mi-055c2be5596fXXXXX
However, when looking at the policies, I don't have the ability to select a managed-instance as a resource:
If I try to just simply replace instance with managed-instance, then it says the ARN is invalid:
How would I give a user ssm:StartSession permission on managed instances then in this case? The following policy does nothing:
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ssm:TerminateSession",
"ssm:StartSession"
],
"Resource": [
"arn:aws:ssm:us-east-2:708332864587:managed-instance/*"
]
}
Apparently this doesn't do anything:
Notice how the managed instance ARN is for the arn:aws:ssm namespace:
arn:aws:ssm:us-east-2:708332864XX:managed-instance/mi-055c2be5596fXXXXX
You are trying to add permission for the arn:aws:ec2 namespace, which is why it isn't working.
TLDR; I would suggest to use the instance ARN instead. I would also verify that your role have access to all documents or at least to SSM-SessionManagerRunShell.
The long explanation:
If you read about StartSession in https://docs.aws.amazon.com/service-authorization/latest/reference/list_awssystemsmanager.html you can learn that
for StartSession you have in the Resrouce column three different Resource types
Actions
Description
Access Level
Resource
StartSession
Grants permission to initiate a connection to a specified target for a Session Manager session
write
document instance task
Each of them has a different ARN structure:
document - arn:${Partition}:ssm:${Region}:${Account}:document/${DocumentName}
instance - arn:${Partition}:ec2:${Region}:${Account}:instance/${InstanceId}
task - arn:${Partition}:ecs:${Region}:${Account}:task/${TaskId}
You can put any other ARNs in the rule, but they will have no effect. But in one they or other the user need access to all the required resources.
For example (mentioned in the other answer as well): In your question you have
aws:arn:ec2:.....:managed-instance with quote: "If I try to just simply replace instance with managed-instance, then it says the ARN is invalid". Yes, because it is. You cannot just combine the parts of ARNs randomly. Valid ARNs are only the documented ones: https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html
When you describe your "managed instance" you should see in it an id of an EC2 instance. This is the only instance which does exist. The ssm "managed instance" is a structure which stores only the ssm-related data for that particular EC2 instance.
`
If you read the example policy in the AWS documentation for StartSession you see there:
https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html
So you you need to figure out how to get the ec2 instance id from the managed instance id like for example with
https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-instance-information.html
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:region:987654321098:instance/i-02573cafcfEXAMPLE",
"arn:aws:ssm:region:account-id:document/SSM-SessionManagerRunShell"
],
"Condition": {
"BoolIfExists": {
"ssm:SessionDocumentAccessCheck": "true"
}
}
},
--cut--
Keep in mind that in AWS you may not be able to limit access per resource level for all services. That's especially for newer services. Or you may not be able to do it easily. For example you can create a lambda function which will start your ec2 instance and will create a policy for it (I don't say that you should do it that way, but it is possible).
Sometimes you can use conditions or you can use PassRole/AssumeRole mechanism to allow access to the resource by a mechanism which is outside of the IAM service. You may need to be creative and/or sometimes compromise.

AWS GraphQL Appsync - unable to assume role

I'm running a tech stack of react -> graphQL -> appsync -> lambda -> go
When I run my graphQL query from the client I recieve this error back:
Unable to assume role arn:aws:iam::<SOMENUMBER>:role/service-role/MyRoleForMyLambda.
In fact this was all running fine until I accidentally changed the function ARN and roles on my Datasource to other ones. I changed them back but now Appsync seems to be unable to find the role and function ARN. I tried creating a completely new Datasource but I have the same issue. Often the function ARN and/or roles don't appear in the dropdown and I enter them manually. Sometimes it lets me save without errors - other times when attempting to save the Datasource I get the helpful error message "Error". Sometimes after saving when I go to look at them again the function ARN field is blank unless I click on the 'not in drop down' link.
I don't think the problem is with my role itself as it appears that appsync can't even assume the role to start with. I've read about trust policies as a solution but I don't know where to put them.
Any help much appreciated.
In your IAM console, you need to add the Appsync service as a trusted entity to the role you are trying to assume
Click edit trust relationship and enter the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

AWS service-role unauthorized, until opened in the console and saved

I'm trying to set up a codeBuild project through the nodejs AWS-SDK. I'm able to create a new IAM role with policies attached, but when I use it in the .createProject() it gives me an error:
CodeBuild is not authorized to perform: sts:AssumeRole on arn:aws:iam::[account]:role/service-role/[role-name]
The weird thing is that, when I open the trusted relationships JSON of the role and save it (without any changes) it suddenly works.
the AssumeRole JSON file:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I'm using a federated user. I don't know if that makes a difference (the process of requesting a regular account takes a few days, so I haven't tried that yet).
I tried to copy the before and after save to see what was going on, but when I store it in a file it has the exact same bytes. I'm really confused, I've been trying to fix this for almost half a day now.
I figured out what the problem was. Apparently, when you create a role and immediately start using it you'll get a "not authorized" error. But you also get this when the role doesn't even exist.
I added a manual wait of 10 seconds, not it works.
The SDK has a function for this called "waitfor", which can be used on roles and policies.

Elastic Beanstalk deployment stuck on updating config settings

I've been testing my continuous deployment setup, trying to get to a minimal set of IAM permissions that will allow my CI IAM group to deploy to my "staging" Elastic Beanstalk environment.
On my latest test, my deployment got stuck. The last event in the console is:
Updating environment staging's configuration settings.
Luckily, the deployment will time out after 30 minutes, so the environment can be deployed to again.
It seems to be a permissions issue, because if I grant s3:* on all resources, the deployment works. It seems that when calling UpdateEnvironment, Elastic Beanstalk does something to S3, but I can't figure out what.
I have tried the following policy to give EB full access to its resource bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/_runtime/_embedded_extensions/APP",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/_runtime/_embedded_extensions/APP/*",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/environments/ENV_ID",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/environments/ENV_ID/*"
]
}
]
}
Where REGION, ACCOUNT, APP, and ENV_ID are my AWS region, account number, application name, and environment ID, respectively.
Does anyone have a clue which S3 action and resource EB is trying to access?
Shared this on your blog already, but this might have a broader audience so here it goes:
Following up on this, the ElastiBeanstalk team has provided me with the following answer regarding the S3 permissions:
"[...]Seeing the requirement below, would a slightly locked down version work? I've attached a policy to this case which will grant s3:GetObject on buckets starting with elasticbeanstalk. This is essentially to allow access to all elasticbeanstalk buckets, including the ones that we own. The only thing you'll need to do with our bucket is a GetObject, so this should be enough to do everything you need."
So it seems like ElasticBeanstalk is accessing buckets out of anyone's realm in order to work properly (which is kind of bad, but that's just the way it is).
Coming from this, the following policy will be sufficient for getting things to work with S3:
{
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>",
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>/",
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>/*"
],
"Effect": "Allow"
},
{
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::elasticbeanstalk*",
"Effect": "Allow"
}
Obviously, you need to wrap this into a proper policy statement that IAM understands. All your previous assumptions about IAM policies have proven right though so I'm guessing this shouldn't be an issue.