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"
}
]
}
Related
I am trying to use an existing API gateway which is present in accountA. I am having some EC2 instances which are having some scripts to invoke the API gateway present. These instances may/may not reside in the same AWS account as the one where my API gateway is present (Let's call the other account as accountB).
For the authentication part currently, there's only AWS_IAM authentication implemented at the API gateway level. The EC2 instances (in both the accounts) are having IAM roles attached which are having IAM permissions to invoke the API.
The permission for the same looks as:
{
"Sid": "InvokeAPI",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*"
}
When I try to invoke the API from the instances which are in accountA, it is working as expected. However, when I try to invoke the API from my instances in accountB, the gateway returns a 403 error with the following message:
User: arn:aws:sts::accountB:assumed-role/invoke_api_iam_role/i-xxxxxxxxx is not authorized to access this resource
I tried to look at API gateway resource policies and tried to whitelist the accountB's EC2 IAM role in accountA API Gateway's resource policy and still, I'm getting the same error.
Current resource policy implemented at the API gateway kinda looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountB:role/invoke_api_iam_role"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:accountA:myAPIID/*"
}
]
}
For signing the requests to the API gateway through the awsv4 signature, I use aws-requests-auth
Please help to resolve this issue.
So as it turns out, everything above is correct and you need to deploy the API to a particular stage for applying the resource policy against it.
I'm trying to learn about resource policies and permissions in general in AWS.
The idea that started as something easy, an API Gateway denying access to everything but other resources in the same VPC ended as a nightmare.
What I want: My API allowing traffic/calls only to resources on the same VPC.
So I created 2 subnets and an open Security Group (all traffic inbound and outbound just for testing purposes)
I created an API Gateway with integrating to a Lambda function and another lambda function and deploy them to that VPC.
The API Gateway has one resource /hi and allows just GET.
When you hit that path it proxies to Lambda which returns a simple message: Hi.
The other lambda (which is on the same VPC) makes a call to the API and returns an error or the response.
Until now, everything works well. The lambda function hits API Gateway which poxies to lambda and return Hi.
But, as I said, I want to play with permissions. So I decided to lock down the calls to API Gateway to the VPC where both reside.
So I added this resource policy to API Gateway:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:account-id:api-id/*/*/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "vpc-id"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:account-id:api-id/*/*/*"
}
]
}
Then I went to the lambda (not the one that is part of the service, if not the one that invokes API Gateway) and add the Managed Policy
AWSLambdaVPCAccessExecutionRole
Also an inline policy allowing execute-api:Invoke on the resource arn:aws:execute-api:us-east-1:account-id:api-id///*
When I run again the lambda function (which was working previously with both, my API Gateway and dummy apis like https://jsonplaceholder.typicode.com/) I receive the following error:
INFO json {
Message: 'User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:account-id:api-id/dev/GET/hi with an explicit deny'
}
If I removed the resource policy in API Gateway, it works again... As soon as I add it, it retrieves the same error.
Does anyone know why this happens?
I'm turning crazy. I will appreciate help.
Edition: Trying an IAM role and resource policy
I also tried to use a role.
For this, in the API I set the following resource policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-id:role/my-role-for-API-Gateway"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:account-id:api-id/*/*/*"
}
]
}
Then, I attached that role to my lambda function (the one that should be able to invoke the API).
Important: That lambda is not part of the service. It is a separate Lambda that should be able to call API Gateway which will proxy the request to the lambda that it is part of the service.
I attached the following policies to that role.
AWSLambdaVPCAccessExecutionRole (because I also tried within the same VPC)
AmazonAPIGatewayInvokeFullAccess (open permission just to be sure I was not missing anything)
Inline policy allowing the invocation of the API by resource ARN: arn:aws:execute-api:us-east-1:account-id:api-id///*
I even tried giving AdministratorAccess to that role just to exhaust possibilities.
I test through API Gateway console, and I receive the proper console.
When I test through Lambda console, I receive the following error:
INFO json {
Message: 'User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:account-id:api-id/dev/GET/hi'
}
So the question for this block would be: how a lambda could invoke an API Gateway which is restricting access to a specific role which the lambda has?
Part of the issue is that aws:SourceVpc condition can be only used for private API. From docs:
aws:SourceVpc - This key can be used only for private APIs.
Since you are using regional API, your StringNotEquals will not work, and you are getting explicit deny.
If you want to use aws:SourceVpc, you have to modify your api to be private API. But if its only learning experience for resource-based policies, the simplest way to learn them would be with bucket policies.
I want to give some AWS account ids access to call the api gateway that is in my account. What is the best way to do this?
I think there is a way to add resource policy that gives that AWS account access. Is that a good way to do that? I am talking about a production kind of service?
Also, does all the resouces of AWS account will get access to API gateway?
For each API Gateway endpoint we can change the Authorization option from None to AWS_IAM:
Then we can configure access to the API from the Resource Policy section of the API Gateway. From the Resource Policy page, click on the "AWS Account Whitelist" button to get a policy template, excerpted below:
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::{{otherAWSAccountID}}:root",
"arn:aws:iam::{{otherAWSAccountID}}:user/{{otherAWSUserName}}",
"arn:aws:iam::{{otherAWSAccountID}}:role/{{otherAWSRoleName}}"
]
},
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/{{stageNameOrWildcard*}}/{{httpVerbOrWildcard*}}/{{resourcePathOrWildcard*}}"
]
}
As an alternative (or in addition) to IAM authorization, we can control usage with API Keys, which enables the ability to rate limit (throttle) API calls and to set quotas.
More info:
https://aws.amazon.com/blogs/compute/control-access-to-your-apis-using-amazon-api-gateway-resource-policies/
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html
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"
}
]
}
The AWS IAM Policy Docs for AWS (shown here) indicate that the following policy gives full access for a role to hit the API Gateway
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:*"
],
"Resource": [
"*"
]
}
]
}
When simulating that policy with API Gateway as the target, the policy denies access. This seems like a direct contradiction to the provided documentation.
Amazon's permissions model divides API Gateway permissions into two services:
Amazon API Gateway - Permissions for clients, currently the only action is execute-api:invoke.
Manage - API Gateway - Admin permissions for configuring the API Gateway, which has CRUD actions fitting the apigateway:* spec.
The policy you have applies to the Manage API Gateway service, the simulation should work if you select that.
This same separation is visible in the regular IAM policy wizard, where "Manage - API Gateway" sorts to the bottom of the service list where you can't see it.