Closed johnf closed 8 months ago
hello @johnf, Thank you for reporting this. I was able to replicate the behavior in my amplify application.
Note: On creating a Lambda function and giving access to the API in advanced options the vtl gets updated with the following snippet.
#if( $util.authType() == "IAM Authorization" )
#set( $adminRoles = ["customauhtfunc7aed174a-dev"] )
#foreach( $adminRole in $adminRoles )
#if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
#return($util.toJson({}))
#end
#end
#if( !$isAuthorized )
#if( $ctx.identity.userArn == $ctx.stash.authRole )
#set( $isAuthorized = true )
#end
#end
#end
on performing a amplify push
the CLI only recognizes the function following.
in order to mitigate the issue, adding a empty line in the AppSync schema and pushing it uploads the VTL. I was able to successfully perform queries using my Lambda function.
Additionally, I wanted to mention the docs for AppSync queries using IAM auth have been updated at https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js/#iam-authorization with newer example.
Marking this as bug.
Alternatively, you can run:
amplify push --force api
Which will rebuild and push the VTL resolvers, without having to make any changes (e.g. blank space) to the schema to trigger a change.
force push didn't work for me. only changes to the schema
I'll add to this to keep some record of the trouble shooting I've been doing. Changing the schema as suggested @ykethan was one solution. Another problem I have found that is related to the VTL resolvers not getting updated properly was caused by the mock api resolvers preventing changes to the API schema from updating the deployed resolvers. Deleting these allowed the remote VTL resolvers to update and allowed my lambda to perform queries/mutations.
This is such an annoying bug, when developing I keep forgetting about it. Making minor changes to the schema just force the resolvers to update is not a good work around.
Alternatively, you can run:
amplify push --force api
Which will rebuild and push the VTL resolvers, without having to make any changes (e.g. blank space) to the schema to trigger a change.
This does not fix the issue for me.
Perhaps this issue should be called out in the Amplify documents since it has been open for over a year without resolution. I just spent several hours pulling my hair out trying to make IAM authorization work with my previously created Lambda functions and having no idea why it wasn't working. After adding a comment to the schema.graphql file and doing an amplify push the problem they immediately started working.
Any updates on fixing this? Just had to do the same empty line trick to our schema.graphql and everything started working as expected.. Definitely an odd workaround.
I had this issue also. It was really frustrating to find out it was just another amplify bug...
here is my experience. I was getting this body.error.message, adding to this thread (if not relevant I can remove!):
body: { data: { listLogins: null }, errors: [ { path: [Array], data: null, errorType: 'Unauthorized', errorInfo: null, locations: [Array], message: 'Not Authorized to access listLogins on type Query' } ] }
The process I took. I stood up a whole new App from amplify init. Installing backend (except my problematic function): API(Cognito, IAM), Auth(userpools, groups), adding only the PostConfirmTrigger (Add-to-Group function) Then setup my GraphQL tables, Added : @auth(rules: [{allow: private, provider: iam},... I ran > amplify api gql-compile and > amplify codegen I ran > amplify push --force api Added my custom PostAuth trigger (custom function) Updated my custom PostAuth trigger (with api access) added the SDK v3, used the node-fetch library, and pretty much duplicated the guide code: https://docs.amplify.aws/guides/functions/graphql-from-lambda/q/platform/js/#iam-authorization
The guide code was pretty good, but it still gave me the same error. After a complete re-build from blank app and following all guides step by step to still have the same error was super frustrating.
Last ditch effort: I needed to remove a table from the schema.graphql ran >amplify push --force api made sure it processed the mutations and queries again
And it worked! But I do not know what was the piece that worked. Nor what is going to happen when I add my next @Auth IAM table.
What's the recommended fix for this? Everything was working fine and now its not etc...
## [Start] Field Authorization Steps. **
#set( $isAuthorized = false )
#if( $util.authType() == "IAM Authorization" )
#foreach( $adminRole in $ctx.stash.adminRoles )
#if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
#return($context.source.sendEmail)
#end
#end
#if( !$isAuthorized )
#if( ($ctx.identity.userArn == $ctx.stash.authRole) || ($ctx.identity.cognitoIdentityPoolId == $ctx.stash.identityPoolId && $ctx.identity.cognitoIdentityAuthType == "authenticated") )
#set( $isAuthorized = true )
#end
#end
#end
#if( $util.authType() == "User Pool Authorization" )
#set( $isAuthorized = true )
#end
#if( !$isAuthorized )
$util.unauthorized()
#end
$util.toJson({"version":"2018-05-29","payload":{}})
## [End] Field Authorization Steps. **
This is what my Mutation.sendEmail.auth.req.vtl
mutation resolve looks like in the broken state. Do I need to add a custom-roles.json
file and add these lambda roles manually?
It looks like the FunctionDirectiveStack.json
file is not updating the context stash as with the generated resolvers. What's weird is that I'm sure this has been working. Not matter what I do, I cannot get the custom mutation resolvers to respect the IAM role auth rules...
E.g custom mutation with @auth rules
type Mutation {
editConnectedAccount(input: EditConnectedAccountInput!): ConnectedAccount
@function(name: "manageConnectedAccounts-${env}")
@auth(rules: [{ allow: private }, { allow: private, provider: iam }])
I'm on the latest version of the amplify cli. This looks like a massive oversight to me.
It looks like the
FunctionDirectiveStack.json
file is not updating the context stash as with the generated resolvers. What's weird is that I'm sure this has been working. Not matter what I do, I cannot get the custom mutation resolvers to respect the IAM role auth rules...E.g custom mutation with @auth rules
type Mutation { editConnectedAccount(input: EditConnectedAccountInput!): ConnectedAccount @function(name: "manageConnectedAccounts-${env}") @auth(rules: [{ allow: private }, { allow: private, provider: iam }])
I'm on the latest version of the amplify cli. This looks like a massive oversight to me.
Did you modify the schema.graphql file and do an amplify push? Just add a comment or modify a comment, save and then push. That action seems to update the IAM permissions, whether set in a custom-roles.json file or added through amplify add/update function.
So I've rolled back to 12.3.0
and the inline adminRoles are successfully being written to the auth resolvers...
@josefaidt - Hey! Can you take a look at this bug since this has broken in the latest release. Custom queries / mutations are not correctly having their RequestMappingTemplates updated in the FunctionDirectiveStack.json files. The adminRoles used to be inlined and have since been moved to VTL mapping.
Also, adding a test to make sure all VTL resolvers have the correct adminRoles added would be great to prevent this happening going forward.
It looks like the
FunctionDirectiveStack.json
file is not updating the context stash as with the generated resolvers. What's weird is that I'm sure this has been working. Not matter what I do, I cannot get the custom mutation resolvers to respect the IAM role auth rules... E.g custom mutation with @auth rulestype Mutation { editConnectedAccount(input: EditConnectedAccountInput!): ConnectedAccount @function(name: "manageConnectedAccounts-${env}") @auth(rules: [{ allow: private }, { allow: private, provider: iam }])
I'm on the latest version of the amplify cli. This looks like a massive oversight to me.
Did you modify the schema.graphql file and do an amplify push? Just add a comment or modify a comment, save and then push. That action seems to update the IAM permissions, whether set in a custom-roles.json file or added through amplify add/update function.
Yes I had done that multiple times with and without the force flag. This is a bug since moving the adminRoles out of the VTL resolvers source code.
+1 for having this working and now i keep getting Not Authorized to access MY_GRAPHQL_CUSTOM_FUNCTION on type Mutation
Is there a amplify CLI command that just re-pushes/rebuilds everything? I'd rather do that than deal with blank lines
amplify push --force api
I believe will do that @johndebord
I remember fiddling with this quite a bit and finally it occurred to me that actions like a force doesn't works because the problem is that the app sync resolvers that are updating don't get applied to the endpoint without a schema change. Because the resolver to app sync endpoint is a little disjointed
I encounter this issue approximately once a week.
In the latest occurrence, I implemented a flow where I create a user in a Cognito Pool, and subsequently, albeit not immediately, create a user in another database. After a period, when I perform a comparison between the Cognito Pool user and the database user, it fails. The error isn't immediately apparent, leading me to investigate various potential causes. However, the root cause turned out to be this particular issue, which I find myself running into frequently.
Any progress or clarification on this? It'd be valuable to have something documented here about the ins-and-outs of this situation by an experienced team member.
Here are the updated docs: https://docs.amplify.aws/react/build-a-backend/graphqlapi/customize-authorization-rules/#grant-lambda-function-access-to-graphql-api
Once you grant a function access to the GraphQL API, it is required to redeploy the API to apply the permissions. To do so, run the command
amplify api gql-compile --force
before deployment viaamplify push
.
For those curious this is the codepath triggered via the force:
BTW, good on y'all to provide a workaround and this fix is the luls
Before opening, please confirm:
How did you install the Amplify CLI?
yarn
If applicable, what version of Node.js are you using?
v16.15.0
Amplify CLI Version
8.2.0
What operating system are you using?
Ubuntu
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
No
Amplify Categories
function, api
Amplify Commands
add, push
Describe the bug
The VTL is updated locally but not remotely to give the function access.
You can see this during the pus in that there is "No Change" to the API Modifying the schema and then pushing fixes it.
See below for detailed steps to reproduce and you can follow along at
See below for detailed steps to reproduce and you can follow along at https://github.com/johnf/amplify-api-lambda-perms-bug
To me it looks like the permission change on the function isn't triggering that the API also needs to be updated.
Expected behavior
Permissions are correctly applied to appsync
Reproduction steps
See https://github.com/johnf/amplify-api-lambda-perms-bug#readme
GraphQL schema(s)
Log output
Additional information
No response