aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 79 forks source link

After upgrading from v12.0.3 to v12.1.1 of amplify-cli, amplify api gql-compile is impossible due to field-level authorization error #1592

Open tf-suzukito opened 1 year ago

tf-suzukito commented 1 year ago

How did you install the Amplify CLI?

yarn

If applicable, what version of Node.js are you using?

v16.19.0

Amplify CLI Version

v12.1.1

What operating system are you using?

Linux

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

No manual changes made

Describe the bug

After upgrading the version of the amplify-cli from v12.0.3 to v12.1.1, the command amplify api gql-compile cannot be executed due to a field-level authorization error. Please see the attached file for details.

2023-06-20_16h26_57

Upon investigation, the version of amplify-category-api has changed from 5.3.0 to 5.4.1.

Comparing changes between v12.0.3 and v12.1.1 packages/amplify-cli/package.json 2023-06-20_16h38_05

We have confirmed that error messages are defined in the following file. amplify-category-api/packages/amplify-graphql-auth-transformer/src /graphql-auth-transformer.ts

Checking the Change Log, we could not find any update information regarding amplify-category-api.

Is this a bug with the upgrade of amplify-cli? Would you please check and investigate the cause?

Expected behavior

Can execute the command amplify api gql-compile, as in v12.0.3.

Reproduction steps

  1. Execute the command: amplify upgrade
  2. Execute the command: amplify api gql-compile

Project Identifier

No response

Log output

No response

Additional information

No response

Before submitting, please confirm:

AnilMaktala commented 1 year ago

Hi @tf-suzukito 👋, Thanks for raising this issue. We are working on reproducing the issue. Could you please run below command and send us the report amplify diagnose --send-report and share with us the project identifier? please refer here

hisham commented 1 year ago

+1. Also running into this issue. It was introduced in 12.1.0. Reverting to 12.0.3 resolves it.

I just ran diagnose and my project identifier is 3def1a2bd59d61900f734d59f169a578

tf-suzukito commented 1 year ago

Hi @AnilMaktala san, thank you for quick response 🙏 I tried to do amplify diagnose --send-report but faced error.

$ amplify diagnose --send-report

Learn more at https://docs.amplify.aws/cli/reference/diagnose/

✅ Report saved: /tmp/.../report-1687307463391.zip

⠹ Sending zip
DiagnoseReportUploadError
✖ Sending zip

2023-06-21_09h31_55

Should I downgrade to amplify version v12.0.3 and then run it?

AnilMaktala commented 1 year ago

Hi @tf-suzukito, Thank you for bringing this issue to our attention. By following the steps provided in the description, we were able to reproduce the issue successfully. As a result, we have flagged this as a bug for our team to investigate and assess further. @hisham, Thank you for sharing the report.

schema:

type Employee
  @model
  @auth(rules: [{ allow: private, operations: [read] }, { allow: owner }]) {
  name: String
  email: String
  ssn: String! @auth(rules: [{ allow: owner }])
}
  1. Execute the command: amplify upgrade
  2. Execute the command: amplify api gql-compile
image
AaronZyLee commented 1 year ago

@tf-suzukito Hi the error is expected if you are adding the field level auth to a non-nullable field due to the subscription concern. We recently apply a more restricted rule due to that concern. Take the repro schema as example

type Employee
  @model
  @auth(rules: [{ allow: private, operations: [read] }, { allow: owner }]) {
  name: String
  email: String
  ssn: String! @auth(rules: [{ allow: owner }])
}

This will throw the same error because the private role does not have read access to the required field ssn. If the error is not thrown, it will result in a bad state where the private role will subscribe to the ssn of other owners.

So the field level auth for the non-nullable fields is more restricted than the nullable ones because of the subscription. There are two workaround which is either make that field nullable or turn off the subscription for the model. I would not recommend adding { allow: private, operations: [read] } to the ssn field since it should not be your intention and there is no need to apply field level auth in this case

Solution#1

type Employee
  @model
  @auth(rules: [{ allow: private, operations: [read] }, { allow: owner }]) {
  name: String
  email: String
  ssn: String @auth(rules: [{ allow: owner }]) # nullable field
}

Solution#2

type Employee
  @model(subscriptions:null) #turn off subscription
  @auth(rules: [{ allow: private, operations: [read] }, { allow: owner }]) {
  name: String
  email: String
  ssn: String! @auth(rules: [{ allow: owner }])
}
hisham commented 1 year ago

Hi @AaronZyLee - my model already has subscriptions: null and I'm still getting the error.

My model is essentially:

type EmployeeVacationRecord
  @model(mutations: { create: "createEmployee", update: "updateEmployee", subscriptions: null }
  @auth(
    rules: [
      {
        allow: owner
        identityClaim: "custom:employee_id"
        ownerField: "employeeId"
        operations: [create, read]
      } # Needed to allow employees to view their own records
      { allow: groups, groups: ["Manager"], operations: [create, read] }
      { allow: private, provider: iam, operations: [create, update, read] }
    ]
  ) { 
   id: ID!
   employeeID: Float!     @auth(
      rules: [
        { allow: owner, identityClaim: "custom:employeeId", ownerField: "employeeId" } #needed so logged in employee can only set this to themselves
        { allow: groups, groups: ["Manager"] }
        { allow: private, provider: iam }
      ]
    )
    @index(
      name: "ByEmployeeId"
      queryField: "employeeVacationRecordByEmployeeId"
      sortKeyFields: ["createdAt"]
    )
    createdBy: Float!
    @auth(
      rules: [
        {
          allow: owner
          identityClaim: "custom:employee_id"
          ownerField: "createdBy"
          operations: [create, update]
        }
        { allow: groups, groups: ["Manager"], operations: [read] }
        { allow: private, provider: iam }
      ]
    ) # To make sure user can only set this to themselves
}

The error I get is: "🛑 When using field-level authorization rules you need to add rules to all of the model's required fields with at least read permissions. Found model "EmployeeVacationRecord" with required fields ["createdBy"] missing field-level authorization rules."

hisham commented 1 year ago

Hi there - any update on this, ETA, or workaround? We have purposely not updated to 12.1.1 because of this issue, but I don't want to now fall behind on amplify cli updates (current version 12.4.0). If you're not able to fix in time, I'm going to have to find a workaround...

tf-suzukito commented 1 year ago

Hi there. And thank you for reaction, @hisham san. 🙏

Same above opinion. Is there any progress on this issue? I know there are other high priority issues, so I can't speak for myself, but the fact that it is treated as an ERROR instead of a WARNING makes it difficult to update it in any way. I know that the AWS team is discussing this issue, and we would be very happy to hear from you if there are any progress.