Open AlessioVallero opened 2 years ago
Hi @AlessioVallero 👋 thanks for raising this issue.
This is just a warning that can be ignored if you're okay with owners having the ability to update the id
field. The problem is simply that the id field is acting as two important mechanisms here. It is both the unique identifier for the record and the field that determines ownership. So, the value of id
in this case is probably the user's cognito sub::username
. Please correct me if I'm wrong, but that's usually how the owner
auth rule works.
Now, if you want to get rid of the warning because you don't want the owner of a Coordinator
record to be able to update the id
field, thus potentially re-assigning ownership, you can protect the id
with a field level auth rule granting them only create
and read
permissions instead. They should still be able to update the record, just not the id
. The other fields inherit the model level auth rule.
type Coordinator @model @auth(rules: [{ allow: owner, ownerField: "id" }]) {
id: ID!
@auth(
rules: [{ allow: owner, ownerField: "id", operations: [create, read] }]
)
something: String
}
I should note that when using field level auth rules, you have to either apply field-level authorization rules to all required fields where all rules have read access ["id"], make those fields nullable, or disable subscriptions for "Coordinator" (setting level to off or public).
Let me know if that helps!
Hi @AlessioVallero 👋 thanks for raising this issue.
This is just a warning that can be ignored if you're okay with owners having the ability to update the
id
field. The problem is simply that the id field is acting as two important mechanisms here. It is both the unique identifier for the record and the field that determines ownership. So, the value ofid
in this case is probably the user's cognitosub::username
. Please correct me if I'm wrong, but that's usually how theowner
auth rule works.Now, if you want to get rid of the warning because you don't want the owner of a
Coordinator
record to be able to update theid
field, thus potentially re-assigning ownership, you can protect theid
with a field level auth rule granting them onlycreate
andread
permissions instead. They should still be able to update the record, just not theid
. The other fields inherit the model level auth rule.type Coordinator @model @auth(rules: [{ allow: owner, ownerField: "id" }]) { id: ID! @auth( rules: [{ allow: owner, ownerField: "id", operations: [create, read] }] ) something: String }
I should note that when using field level auth rules, you have to either apply field-level authorization rules to all required fields where all rules have read access ["id"], make those fields nullable, or disable subscriptions for "Coordinator" (setting level to off or public).
Let me know if that helps!
Thank you @chrisbonifacio, that helps and I appreciate your quick response I guess my only question is the following: using the field-level authorization exactly as you just shared, I'm unable to perform an updateCoordinator({ id: <the_id>, something: "Hello world"})
. The point is that id
is needed in order to invoke updateCoordinator
. How can I still invoke the function without getting an access denied from using the id
?
Oh, I see, the id
is a required part of the UpdateCoordinatorInput so makes sense. So, I think there are two options - either you ignore the warning as it's just pointing out a potentially unwanted permission (allowing users to re-assign ownership). This might be the only option if your schema is already in production. OR - if your schema isn't in production yet - you'd have to handle ownership differently by using a field other than id
.
Do you need the id
field to act as both the identifier and the owner field? If not, you could create a separate owner field that is protected as I described and doesn't need to be included in your input variables. But we'd be doing all this to simply avoid the warning, which shouldn't really affect your ability to perform updates on a record.
Hey Chris—appreciate the quick response as well. I think it's worth pointing out that an update
field-level permission is inherently nonsensical on a primary key field (as id
is in this case, which yes, you correctly deduced we use to store the user's Cognito sub). That is, insofar as the primary key field of the mutation input specifies which record we want to update, it's not possible to use that same field in the mutation to specify a different value, since a field can only have one value (instead one must delete and recreate the record). In short, ignoring auth rules completely, it's not possible to reassign ownership of a model if the owner field is also the primary key because it's not possible to update the primary key of a model.
For that reason, I'd still suggest that this particular arrangement is safe, and thus the warning shouldn't fire.
(As an aside, I definitely appreciate the Amplify team going the extra step to help devs identify nonobvious security risks like unintentional ownership reassignability! While it may not be correct in this instance, it's been super helpful for locking down our other models.)
Hi @0x24a537r9, What you're describing here seems sound, and should be a minor update to this warning method https://github.com/aws-amplify/amplify-category-api/blob/main/packages/amplify-graphql-auth-transformer/src/utils/warnings.ts#L32
For the comment you'd made on that related PR, I'd anticipated that if your primaryKey
and ownerField
collided you were getting this issue around making the id required for updates, etc, but I think I misunderstood slightly. It sounds like the issue only arises when when you add the field level auth though.
My recommendation in the docs was focused around separating your PK and the owner info, potentially adding a secondary index to query by owner if necessary, e.g.
type User @model @auth(rules:[{ allow: owner, ownerField: "owner"}]) {
owner: String @index(name: "byOwner", queryField: "userByOwner")
additionalAttributesBecauseCognitoWontAllowItNatively: String
}
Before opening, please confirm:
JavaScript Framework
React Native
Amplify APIs
GraphQL API
Amplify Categories
auth
Environment information
Describe the bug
Since I installed Amplify version 10.0.0, when running
amplify api gql-compile
, I've seen the following warning:In our model, a
Coordinator
has a primary key of typeid: ID!
that we use when running the autogeneratedupdateCoordinator
function to update other fields. Can you clarify why anupdateCoordinator
, which needs theid
to identify the record to update and that does not, in fact, mutate theid
, still shows the warning? I cannot remove the permission toupdate
otherwise I lose the possibility to update.Expected behavior
A primary key field should be expected to be used to perform
update
mutations on a model and it shouldn't show the warning.Reproduction steps
npm install -g @aws-amplify/cli@10.2.1
amplify init
amplify api gql-compile
and you should see the warningCode Snippet
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response