I am having trouble calling an AppSync GraphQL query via a AWS Lambda function. I have been using the code in this article, specifically the latter part that uses IAM permissions: https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js#signing-a-request-from-lambda
const https = require("https"); const AWS = require("aws-sdk"); const urlParse = require("url").URL; const appsyncUrl = process.env.API_MYAPP_GRAPHQLAPIENDPOINTOUTPUT; const region = process.env.REGION; const endpoint = new urlParse(appsyncUrl).hostname.toString(); const graphqlQuery = require("./query.js").query; exports.handler = async (event) => { const req = new AWS.HttpRequest(appsyncUrl, region); req.method = "POST"; req.path = "/graphql"; req.headers.host = endpoint; req.headers["Content-Type"] = "application/json"; req.body = JSON.stringify({ query: graphqlQuery, operationName: "list", }); const signer = new AWS.Signers.V4(req, "appsync", true); signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate()); const data = await new Promise((resolve, reject) => { const httpRequest = https.request({...req, host: endpoint }, (result) => { result.on("data", (data) => { resolve(JSON.parse(data.toString())); }); }); httpRequest.write(req.body); httpRequest.end(); }); return { statusCode: 200, body: data, }; };
I am using the Amplify CLI. I used the CLI to create the function and ensure it is given access to the GraphQL API.
The specific error I get in the Lambda is:
{
"statusCode": 200,
"body": {
"errors": [
{
"errorType": "UnauthorizedException",
"message": "Permission denied"
}
]
}
}
GraphQL is set-up to use Cognito user pool as authentication and I've added IAM as a secondary authentication mechanism via the Amplify CLI. The AWS GraphQL console shows that I have Cognito as my primary authentication mechanism and IAM as secondary.
The Lambda function appears to be permissioned okay as it shows 4 resources (create, update, delete, read) corresponding to the API and Allow: appsync:GraphQL as the Action.
If I run the function locally using amplify mock function myfunction
then it executes fine and the result of the GraphQL query is returned correctly.
I can also run the same query successfully via the AppSync UI when I choose IAM as the authentication mechanism.
The table I am accessing is defined in my schema.graphql as:
type Business
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["Admin"] }
{ allow: private, provider: iam }
]
) {
id: ID!
owner: String!
name: String!
emailSuffix: String!
shortCode: String!
}
I have removed the Auth from the model and that doesn't make a difference.
I've deleted the function and re-created it in case the permissions had somehow got messed up.
So I don't think it is the code, seems to be a permissions error. I'm at a loss as to where the issue could be
UPDATE I have amended the permissions policy inside IAM Manager for the amplify-lambda-execution policy and that appears to have fixed the issue.
The permissions policy initially added by Amplify was of the form:
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/create/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/read/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/edit/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/delete/*
amending this to:
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/*/fields/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID
allows the lambda function to execute and successfully execute the GraphQL query on my table. So it appears to be a problem with the permissions that Amplify adds to the function. Manually overwriting these isn't a great solution.
The problem started after installed - amplify cli "4.45.2". The old code for autogenerated permissions in the lambda cloudformation template looked like this.
{
"Effect": "Allow",
"Action": [
"appsync:Create*",
"appsync:StartSchemaCreation",
"appsync:GraphQL",
"appsync:Get*",
"appsync:List*",
"appsync:Update*",
"appsync:Delete*"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/*"
]
]
}
]
}
But after I moved to amplify cli "4.45.2" and give lambda permissions for appsync. It generated:
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/create/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/read/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/update/*"
]
]
}
]
}
enter code here
And I got error "permission denied" when trying to reach appsync from lambda.
I think the new cli has some bug when generating appsync permissions for lambda.
I manually moved back on the old generated code in the lambda cloudformation file and it worked.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.