@aman-bansal - I know you guys have been busy with v21.12, but I just want to make sure it is still being worked on, and there are some new things I realized you need to consider:
- The update-after-auth directive needs to validate the complete data set of data from what the database WOULD look like after the update – it should not just validate the incoming data like add does.
a. That means it should be a compilation of the current data merged with the update data.
b. This also means the field-level auth capability and input validation will not work in certain situations, which means we need to rethink that as well. - This also means it could be a hell of a lot more complicated if it were to work how an update-after directive should work.
I can give two major examples of what this will solve:
- I should not be able to change the user who owns a posts (as there is no way to stop that in an update)
- I can own the post, but I shouldn’t be able to change the owner to someone else
- I should not be able to change the role of a user
- I can own my User node, but I shouldn’t be able to change my own role to Admin
- Right now, it is possible to do role based authorization by creating an intermediary root node - see here for an example, so this is important
What it does NOT solve
- Input Validation
- Field Restriction
I still need input validation as a separate feature, but more importantly I need field restriction. Let’s say I want to prevent the user from updating the timestamp, because this will be done automatically by DGraph…
Example 1:
{ not: { has: updatedAt } }
This will not work as expected. If updatedAt
already exists in the database, this rule will fail even if updatedAt
is not in the input.
Example 2:
If I have a schema:
type Post {
name: String!
...
likes: [User]
}
My @auth directive can stop unauthorized users from updating my Post
, and update-after-auth will prevent me from assigning the post to some random user, but what if I want any user to be able to like
the post? There is no way to ONLY allow likes
to be able to be updated, even with update-after-auth as it should work. This is VERY COMMON need, which renders the mutations pointless.
Possible Solutions
-
@auth directive on actual field (add, update, update-after, query, delete)
- @auth on individual field
- how to add query auth over one field
- how do I protect certain fields
- (no official field level auth feature request, but on old roadmap)
- Disable everyone from updating the field (maybe a @disable directive)
- Readonly / computed field directive
- skip field generation
- (no official @disable feature request I could find)
- Have an update-after-before and an update-after-after lol
- Have an @auth mechanism to compare current values with updated values
- @amaster507 has a post somewhere about this, couldn’t find it
- Lambda Pre-hooks
- Just use the input values before they merge with current values in database
- this is what I was talking about above, but not sure if that is how it SHOULD work
Summary
As we can see @auth and Input Validation can overlap, but they’re really two separate features.
-
Field Authorization (depends on user / role / group)
a. By Field Value – we already have this with add and update rules, just not update-after rule — solves the owner and role problem, just based on the final database record
b. By Field Name – this is really field restriction. We will be able to stop certain values from being added, but not certain fields from being edited at all. -
Field Validation (same for everyone)
a. By Field Value - Regex, Min, Max
b. By Field Name – hasOnly, hasAll, @disable directive, query for everyone, perhaps similar to firebase rules
Conclusion
We really need three different features in this order of importance:
- Update After Rule
- Field Level Auth Rule (for Field Restriction) — add, update, update-after, delete, query
- Field Validation — This is more or a data integrity issue than a security issue, so NOT as important as #1 and #2…
That being said, if we base the update-after rule on the input values, and not the completed data set, it sort of solved all 3 problems… but is that how it should work?
Either way, in order for us users to avoid extraneous lambda maintenance, and make the current state of DGraph GraphQL usable for a real app, we definitely need #1 (update-after-rule) and #2 (field-level-auth), hands down. Field Validation should be added one-day when the major missing features are in DGraph Cloud.
Please let me know your thoughts and current status of this…
Thank you!
J