I'm trying to figure out how can you protect at field level a one-to-many @connection
with @auth
against mutations that shouldn't be allowed. (ie: deny a specific user to run a mutation that will end-up inserting posts as another user.)
Starting with the example for protecting a mutation at the field level: https://aws-amplify.github.io/docs/cli/graphql#field-level-authorization
I tried doing something like this:
type User @model @auth(rules: [{ allow: owner, ownerField: "id" }]) {
id: ID!
posts: [Post]
@connection(name: "UserPosts")
@auth(rules: [{ allow: owner, ownerField: "id" }])
}
type Post @model {
title: String!
user: User!
@connection(name: "UserPosts")
@auth(rules: [{ allow: owner, ownerField: "userPostId" }])
}
Then say there already is a user with an id of regular-user-id
Apparently my auth rules don't stop another user, say with id of: malicious-user-id
to run this mutation:
mutation {
createPost(input:{
title:"Oh this is BAD!"
postUserId: "regular-user-id"
}) {
title
}
}
Running a simple query to make sure this really happened:
query {
getUser(id:"regular-user-id"){
posts{
items
{
title
}
}
}
}
=>
{
"data": {
"getUser": {
"posts": {
"items": [
{
"title": "Regular User title"
},
{
"title": "Oh this is BAD!"
},
]
}
}
}
}
I tried various ways to figure this one out and couldn't find any documentation about bi-directional field level authentication. I'm fairly new to AppSync so I think I must be not getting something, but then this is such common use-case scenario that I'm really surprised there isn't more documentation about it.
Some help would be really appreciated.
To protect the Mutation.createPost
mutation such that only the owner of the Post as designated via the postUserId
may access it you add an @auth directive to the Post object definition:
type Post @model @auth(rules: [{ allow: owner, ownerField: "postUserId" }]) {
title: String!
# This will use a field 'postUserId' by default.
user: User!
@connection(name: "UserPosts")
}
With this setup, a mutation:
mutation {
createPost(input:{
title:"Oh this is BAD!"
postUserId: "regular-user-id"
}) {
title
}
}
will fail if the logged in user is not "regular-user-id".
This answer may help fill things in as well https://github.com/aws-amplify/amplify-cli/issues/1507#issuecomment-513042021.