Is this still in development? I would like this to be in the auth directive itself and not stuck in a JS Hook. Right now I can prevent a user from adding content as another user with the add rules, but the user can add data as their own and then update it to belong to a different user. This is a security whole as we do not want to allow users updating data and removing them as the author and assigning somebody else to make it appear that the other user is the original author.
This will be possible once we introduce JS Hooks. But we may need to decide if we want to add this in auth directly. Let me have a discussion with the team and update you if we plan to do it in the upcoming release.
I just started learning about DGraph, and I was delighted to see how auth rules work here, finally something that works in the same simple but powerful mental framework that I always imagined (and which was hard to implement with basic CRUD hooks other solutions offer). But then I came across this exact issue when reading the docs - it seems this defeats a large portion of the otherwise amazing functionality of auth rules in DGraph! I can’t believe that this is still not implemented… are there any plans to get it some time soon? And what are the least cumbersome workarounds…? I hate duplicate code and multiple sources of truth not only is it annoying and inconvenient, it can also lead to security holes unnecessarily easily…
I’m not sure how cumbersome this might seem to you, but you could implement event sourcing to treat the database like an accounting ledger: an event is committed that updates application state; application state cannot be directly mutated. Instead of updating data, you add a new event to update the state.
Example in the accounting sense: You realize you recorded the wrong amount of money transferred from one account to another. Instead of updating the record to correct the error, you add a new record moving a portion back to the source account so that the net transfer is correct. No record was updated. No record was deleted.
In the application sense using a Todos application: Create an event (an actual node in the db) called addTodo with all the data you need. If you want to update the todo, create another event called updateTodo with the updated data. If you want to delete a todo, create a new event called deleteTodo, probably only indicating the ID of the Todo. Now you have a timeline/audit log for everything that has ever happened to that Todo. In practice, you would prohibit update and delete mutations on events.
How would you implement the state? Two ways: 1) Use lambda functions to write/update the state nodes, disable all mutations on state nodes, and allow users to query both events and state nodes. The state nodes would appear like the database without event sourcing, but the events could be queried to help users understand how the state came to be; the event store is the source of truth from which the entire state could be rebuilt simply by replaying all the events in chronological order. 2) The front-end builds the state on-the-fly from the events.
Event sourcing provides excellent security in the sense of data integrity while also solving this update problem: In an event sourced application nothing is ever updated. One noteworthy consequence of this is that event sourced databases consume more disk space, but disk space is pretty cheap these days.