-
Notifications
You must be signed in to change notification settings - Fork 822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lambda Function GraphQL Authentication issues #10141
Comments
I'm facing the exact same issue. The only way I can get my amplify cli generated functions to get authorized is by setting the models publicly available, which is obviously not what I'm looking to do. |
The cloud formation template seems to display the correct access permissions: {
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "<api_name>GraphQLAPIIdOutput"
},
"/types/Query/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "<api_name>GraphQLAPIIdOutput"
},
"/types/Mutation/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "<api_name>GraphQLAPIIdOutput"
},
"/types/Subscription/*"
]
]
}
]
}, The workaround explained in the issue #6933 does not work for me, at least not while mocking the function. The "appsync": {
"generateGraphQLPermissions": true
} |
Adding that I get this following error message when running Error message:
Additional info: I have the following auth rules set on my API through amplify cli. Cognito user pools (default), IAM, Api key Not sure is this error message related to this issue, but to me it seems like it is. |
Hi @Lorenzohidalgo after setting the |
Hi @edwardfoyle, the flag I've tryed the following without any success:
I would also like to add that the granted permissions to access other functions are correctly working. |
@edwardfoyle any update on this? It's somewhat of a big stopper for us. |
@edwardfoyle just to confirm, I've updated to Amplify CLI v8.0.0 and the issue still persists after pushing the function again. I've also checked the function in the lambda GUI and it seems to recognize the permissions correctly: Not sure where to continue checking/testing UPDATE: The previous functions that were correctly working (and authorized with IAM) stopped working when I first pushed the new function. |
@edwardfoyle after more investigations and tests I've reached the following conclusions:
Please confirm if this is the intended behavior. |
Same here! Tried a lot of variations... Confirm what @Lorenzohidalgo describes. Before updating to Transformer 2 everything worked fine - was able to query inside AppSyncs Console with my IAM. Now, CANNOT query inside AppSyncs Console with my IAM [and calling from functions with IAM gives "message": "Not Authorized to access create*** on type *** " ]. This is a very blocking issue!!! @edwardfoyle @sundersc any suggestions? :) |
@fomson to be able to query inside the AppSync Console with IAM you need to follow the steps mentioned in this section of the docs. |
Thank you! Will try now. By any chance, has this ability to query inside the console solved the problem with Lambda authentication for you? [This is the main issue, really. All may Lamndas get denied accessing any resolvers...] |
@fomson if you create the functions as indicated in the docs (giving them access to your current API resources), they should have the necessary privileges to work. The issue (at least in my case) is that mocking the function with the amplify cli or testing it via the Lambda GUI will result in authentication issues. Once deployed they will have the needed permissions. You can test it by invoking the deployed functions from another "test" function. |
@Lorenzohidalgo local mocking will use the AWS credentials available on your local machine when executing the function. You'll need to grant this user/role access to the resources if you want to test those SDK calls locally. However, executing the function in the console uses the same execution role as invoking the lambda in any other way so I would expect the permissions to be set correctly in that case |
@Lorenzohidalgo thank you, still [was] not working... It feels something went very wrong after migrating to this Transformer v2... @edwardfoyle seems as this #10130 and this aws-amplify/amplify-category-api#100 (@danrivett) and this aws-amplify/amplify-category-api#544 and this aws/aws-appsync-community#214 are very related to what I've been experiencing. I tried adding to cli.json
Not helpful... The issue is that my Lambda resolver gets "message": "Not Authorized to access create on type " when calling Amplify-generated resolvers from within itself. [So, I am able to set/allow permissions for my custom Lambda resolver but get issues when this custom resolver tries calling Amplify-generated resolver...] Very weird behaviour, as it seems that my Lambda has permissions to Mutations [create is a mutation]. For now, I rolled back to Transformer v1, as this migration nonsense is very blocking [so far I spent seven days ducking with it]. |
@fomson @Lorenzohidalgo - Have you tried this workaround? This makes the resolver to allow access to all the IAM roles on an account. |
I haven't for two reasons:
When my customer revolver gets called, in its Event I have
So, supposedly, the condition in the VTL template for Amplify-generated resolver should be met, but it is not... Do you know how I can log Am I meant to have value for Please have a look at this aws/aws-appsync-community#214 This is the problem we are dealing with. |
Hey @Lorenzohidalgo 👋 re-reading your original post, I noticed the example shown is copied from our docs site which includes an if/else statement that is a bit confusing for the use case: if (apiKey) {
req.headers["x-api-key"] = apiKey;
} else {
const signer = new AWS.Signers.V4(req, "appsync", true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
} Does your API also have API Key as an auth mechanism? If so, it is likely this truthy check is attempting to authorize requests using the API key rather than signing the request for IAM auth. |
The point is that with IAM, there is an issue. I use no apiKey. |
#10141 (comment) just tested, apiKey is not defined [at least for me], so the conditional works well, the signer gets assigned and addAuthorization() is called. The search for answers continues... Transformer v2 [or migrating to it] causes problems with GraphQL... |
@josefaidt same as @fomson here. removed that part because it should (and is) always trying to access via IAM. |
Hey @Lorenzohidalgo and @fomson I've spent some time on this with quite a few Lambda's using IAM auth to call AppSync and did notice one instance where I was getting unauthorized where the permissions were available, and after a few minutes it seemed to relieve itself -- potentially due to some permission propagation? Using the following schema and Lambda code I am able to call the AppSync API using IAM auth: enum Status {
ACTIVE
INACTIVE
}
enum PaymentInterval {
MONTHLY
QUARTERLY
YEARLY
}
type Membership
@model
@auth(
rules: [
{ allow: owner, ownerField: "id", operations: [create, read] }
{ allow: private, provider: iam, operations: [update, delete] }
]
) {
id: ID!
status: Status @default(value: "INACTIVE")
paymentInterval: PaymentInterval
} // amplify/backend/function/updatemembership/src/index.js
import crypto from '@aws-crypto/sha256-js'
import { defaultProvider } from '@aws-sdk/credential-provider-node'
import { SignatureV4 } from '@aws-sdk/signature-v4'
import { HttpRequest } from '@aws-sdk/protocol-http'
import { default as fetch, Request } from 'node-fetch'
const { Sha256 } = crypto
const AWS_REGION = process.env.AWS_REGION || 'us-east-1'
const MUTATION_UPDATE_MEMBERSHIP = /* GraphQL */ `
mutation MUTATION_UPDATE_MEMBERSHIP($input: UpdateMembershipInput!) {
updateMembership(input: $input) {
id
status
paymentInterval
}
}
`
/**
* @type {import('@types/aws-lambda').APIGatewayProxyHandler}
*/
export const handler = async (event) => {
console.log(`EVENT: ${JSON.stringify(event)}`)
const { id, status, interval } = event.queryStringParameters
const variables = {
input: {
id,
status,
paymentInterval: interval,
},
}
const endpoint = new URL(process.env.API_9966_GRAPHQLAPIENDPOINTOUTPUT)
const signer = new SignatureV4({
credentials: defaultProvider(),
region: AWS_REGION,
service: 'appsync',
sha256: Sha256,
})
const requestToBeSigned = new HttpRequest({
method: 'POST',
headers: {
host: endpoint.host,
},
hostname: endpoint.host,
body: JSON.stringify({ query: MUTATION_UPDATE_MEMBERSHIP, variables }),
path: endpoint.pathname,
})
const signed = await signer.sign(requestToBeSigned)
const request = new Request(endpoint, signed)
let statusCode = 200
let body
let response
try {
response = await fetch(request)
body = await response.json()
if (body.errors) statusCode = 400
} catch (error) {
console.log(error)
statusCode = 500
body = {
errors: [
{
message: error.message,
},
],
}
}
return {
statusCode,
body: JSON.stringify(body),
}
} And our {
"permissions": {
"api": {
"9966": [
"Mutation"
]
}
},
"lambdaLayers": []
} Finally, the function's CloudFormation template should also include the policy document for adding these permissions: "AmplifyResourcesPolicy": {
"DependsOn": [
"LambdaExecutionRole"
],
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "amplify-lambda-execution-policy",
"Roles": [
{
"Ref": "LambdaExecutionRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "api9966GraphQLAPIIdOutput"
},
"/types/Mutation/*"
]
]
}
]
}
]
}
}
} Can you confirm your functions have the CloudFormation block shown above and the necessary permissions? If so, can you try the sample snippet for calling AppSync with IAM? |
@josefaidt there is no file called |
Let me just offer another file name where permissions are mentioned: "FUNCTION_NAME-cloudformation-template.json"... @josefaidt What your are suggesting seems to be not the problem, please see this #10141 (comment) The issue posted by @Lorenzohidalgo is around "message":"Not Authorized to access getUsers on type Query" AND his "cloud formation template seems to display the correct access permissions..." for type Query... |
Hey @Lorenzohidalgo the This will authenticate using Cognito @auth(rules: [{ allow: private }]) This will authenticate using IAM @auth(rules: [{ allow: private, provider: iam }]) |
Hi @josefaidt , Sorry for the confusion, the file I've not seen any difference in the functions behavior between: @auth(rules: [{ allow: private }]) and @auth(rules: [{ allow: private }, { allow: private, provider: iam }]) Just to clarify, as mentioned in one of my last comments the issue does only affect mocking and testing the functions.
|
Hey @Lorenzohidalgo apologies for my confusion! Does the note here provide additional insight as to how to grant access to the API when mocking?
Essentially we'll want to mirror the permissions generated for our function to the IAM user used by Amplify CLI when mocking |
I'm seeing something similar, not sure if it;s related though. The lambda function is called by graphQL just fine. But when the lambda tries to talk to GrapqhQL it is getting an error. What I've worked out is that in my local autogenerated VTL the function is listed in adminRoles, but it isn't in App Sync itself. So the VTL isn't in sync. I've tried a couple of things but can't work out how to resync the VTL files. |
I ended up adding a dummy field to a table and pushing to get the VTL back in sync |
@johnf This is an interesting note. To clarify, what you were seeing locally upon running |
Hey @johnf great callout and we were able to reproduce that issue per this comment aws-amplify/amplify-category-api#679. @Lorenzohidalgo and @fomson can you check the linked issue here and see if the notes here provide additional insight? In short, granting access to an already-created API with no current, pending changes will not push the VTL resolver update allowing the function access. As a workaround we can make a small/empty change to our GraphQL schema to trigger an update to the API resource and push the changes. |
hey @josefaidt, I reviewed the comment and it seems to apply/be the source issue. I just faced the issue:
Updating the function to remove and reapply the permissions did not work, but adding a blank line in the graphql schema and deploying again did the trick for me. Thanks a lot for the tip @johnf !! |
Tried the workaround but didn't work as well sadly. Is there a workaround that works? :) |
Hey @Lorenzohidalgo glad to hear you're back up and running 🙌 @jeremyrajan what sort of issues are you running into? |
Adding pending-close... label in favor of tracking aws-amplify/amplify-category-api#679 |
@josefaidt Why is this being closed if a clear solution hasn't been found, has it? |
Hey @fomson apologies for not also adding a comment, but I've closed in favor of tracking the bug described in aws-amplify/amplify-category-api#679. As a workaround, we can add a small comment or space to our schema.graphql file to trigger an update for our API resource and push. |
Hi I experienced similar issue, for me it was because I didn't add IAM auth mode for my API (graphql) I only added API_KEY and COGNITO_USER_POOL, but not IAM for my API. Some context on how did I get the problem:
Once suggestion, in |
Hang on Hang on,.. Can someone please explain why "Cognito, API, and now IAM. And if I do not have IAM users, instead I have IAM(sso) users how does that work. Please guys tell how these are meant to be used and tell how to set them up. Documentation on these topics is killing us. |
Same issue here, I am not able to perform AppSync calls from lambda functions and it was working perfectly fine before... the documentation is not providing any clear solution... |
+1 for having this working before and now i am getting |
@rafaelfaria What worked for us, it was to insert a custom VTL script at the top the of the generated mutation using amplify override... push it remote... then remove it pipeline function we added... and push again... but it's not a viable solution to suggest if you never used amplify override. |
Before opening, please confirm:
How did you install the Amplify CLI?
No response
If applicable, what version of Node.js are you using?
No response
Amplify CLI Version
7.6.26
What operating system are you using?
Windows (amplify cli on WSL)
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
Auth:
DynamoDB:
Amplify Categories
function, api
Amplify Commands
add
Describe the bug
I've created a new function using the latest version of the CLI and granted access to the API resources as stated in the docs.
The generated function resources seem to miss Authorization to access AppSync schema, since any type of access attempt ends up in the following response:
I've double-checked and the CLI recognizes/shows that the generated function has the required
Resource access permissions
. Existing functions created following the same exact steps (with previous CLI versions) are working correctly.Expected behavior
The function should have access to the resources we specified during the creation process.
Reproduction steps
amplify add function
Used code to generate calls to Appsync:
GraphQL schema(s)
Log output
Additional information
functions created with previous cli versions following the same steps still work properly. Some of them where created before the GraphQl migration.
The text was updated successfully, but these errors were encountered: