Lambda e API Gateway sullo stesso VPC risultante in User: anonymous non è autorizzato a eseguire: execute-api: Invoke on resource
Sto cercando di conoscere le politiche e le autorizzazioni delle risorse in generale in AWS. L'idea che era iniziata come qualcosa di semplice, un gateway API che negava l'accesso a tutto tranne che ad altre risorse nello stesso VPC si è conclusa come un incubo.
Cosa voglio: la mia API che consenta il traffico / le chiamate solo alle risorse sullo stesso VPC.
Quindi ho creato 2 sottoreti e un gruppo di sicurezza aperto (tutto il traffico in entrata e in uscita solo a scopo di test)
Ho creato un gateway API con l'integrazione di una funzione Lambda e un'altra funzione lambda e li ho distribuiti a quel VPC.
Il gateway API ha una risorsa / hi e consente solo GET. Quando si colpisce quel percorso, viene inviato tramite proxy a Lambda che restituisce un semplice messaggio: Ciao.
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?
Risposte
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.