amplify-category-api
amplify-category-api copied to clipboard
Groups authorization groupsField create protection not working with multiple rules
How did you install the Amplify CLI?
No response
If applicable, what version of Node.js are you using?
No response
Amplify CLI Version
12.0.1
What operating system are you using?
Pop Os
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
no
Describe the bug
So I'm not sure if this is intentional or not. If I have only { allow: groups, groupsField: "group" } on my @model, as expected I can only create items with the group I am member of. Same goes if my model only has {allow: groups, groupsField: "orgBusinessId", groupClaim: "orgBusinessAdmin"}, I can only create items if the groupClaim matches groupsField.
But if I have them both, there seems to be trouble. Lets say I am logged in with a user that is in a Cognito group "group-a". With the example model below, I am able to create a Vehicle with group: "group-a", orgBusinessId: "literally anything" . And same goes the other way too, if I have a groupClaim "businessAdmin: business-a", I can create a Vehicle with that businessId and any group I want. Is this how it should be? I am on Transformer v1.
@model
@auth(
rules: [
{ allow: private, provider: iam }
{ allow: groups, groupsField: "group" }
{ allow: groups, groupsField: "organizationId", groupClaim: "orgAdmin" }
{
allow: groups
groupsField: "orgBusinessId"
groupClaim: "orgBusinessAdmin"
}
{ allow: public, operations: [read] }
]
) {
id: ID!
group: String
organizationId: ID
orgBusinessId: ID
}
I see that with this field level @auth rule I can prevent the group value of an existing record being changed, even with the correct orgBusinessAdmin groupClaim. I can still create record with any group though.
group: String
@auth(
rules: [
{ allow: groups, groupsField: "group" }
{ allow: private, operations: [read] }
{ allow: public, operations: [read] }
]
)
Expected behavior
I expect not to be able to create a Model with group that I am not part of, when that given groupsField is set with @auth rule.
Reproduction steps
- Use the provided example schema
- Create an user with group "group-a"
- See how you are able to create a Vehicle with group: "group-a" and an arbitrary orgBusinessId.
Project Identifier
3c5cae686b22c72a9c59640b51e0f075
Log output
# Put your logs below this line
Additional information
No response
Before submitting, please confirm:
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- [X] I have removed any sensitive information from my code snippets and submission.
Another thing I observed with the example model (let's say its Vehicle) from the original post is that I can update a Vehicle that belongs into my group, to have any group:
I am logged in with a Cognito user that has a custom claim orgAdmin: '29c96e92-a1f0-417a-a957-a5f2a8fbae1c', and does not belong to any group.
Trying to create a Vehicle with organizationId I don't belong to returns Unauthorized, as expected
mutation MyMutation {
createVehicle(input: {name: "New Vehicle", organizationId: "doesnotexist"}) {
id
}
}
{
"data": {
"createVehicle": null
},
"errors": [
{
"path": [
"createVehicle"
],
"data": null,
"errorType": "Unauthorized",
"errorInfo": null,
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "Not Authorized to access createVehicle on type Vehicle"
}
]
}
Now when I create a Vehicle with appropriate organizationId, I can update it whatever organizationId I want?
mutation MyMutation {
createVehicle(input: {name: "New Vehicle", organizationId: "29c96e92-a1f0-417a-a957-a5f2a8fbae1c"}) {
id
}
}
{
"data": {
"createVehicle": {
"id": "59cec61c-dd51-4bd4-a688-2037d7ceef2c"
}
}
}
mutation MyMutation {
updateVehicle(input: {id: "59cec61c-dd51-4bd4-a688-2037d7ceef2c", organizationId: "doesnotexist"}) {
id
group
organizationId
}
}
{
"data": {
"updateVehicle": {
"id": "59cec61c-dd51-4bd4-a688-2037d7ceef2c",
"group": null,
"organizationId": "doesnotexist"
}
}
}
And now when I try to update the same Vehicle, I cant as expected. However I do not get Unauthorized, but DynamoDB:ConditionalCheckFailedException
mutation MyMutation {
updateVehicle(input: {id: "59cec61c-dd51-4bd4-a688-2037d7ceef2c"}) {
id
group
organizationId
}
}
{
"data": {
"updateVehicle": null
},
"errors": [
{
"path": [
"updateVehicle"
],
"data": null,
"errorType": "DynamoDB:ConditionalCheckFailedException",
"errorInfo": null,
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: ET2SSKHLHPAT88MRRLL277A9IBVV4KQNSO5AEMVJF66Q9ASUAAJG)"
}
]
}
I verified that the same behaviour exist, if I am logged with a user that belongs to group and has no custom claims. I can update a Vehicle that belongs into my group, to be into any other group. Which surely should not happen?
Hi @parvusville, the behavior you're seeing is expected. The @auth rules on a model are treated as a set of OR conditions, so if the state of the user identity matches any of the allowed Auth states, they will be allowed to do that operation. If you want to be more restrictive about which fields get updated based on specific Auth rule, you need to define them on field level.
Hello @phani-srikar , thanks for the information. As mentioned in my post though, having a field level rule did not prevent me from setting any value to that field on creation, even if the rule is not met. So that does not really work