Feature Request: Update After @auth Validation

With respect, this is the most ignorant statement and shows you guys have not read any of my nor @amaster’s posts, nor do you actually understand the use cases of the average developer.

Here are the problems with this statement:

Lambdas

  1. Lambdas require using an external function in javascript / typescript
  2. Executing lambdas are not “easy” and take a lot of time to write code that should be built in to graphql for security.
  3. I can’t even use lambdas in a lot of cases. You guys do not offer a pre-mutation lambda. The post-mutation lambda “web-hook” that you do use is only viable for things like cascade delete and deep mutations (another feature that should be used in graphql, not lambdas).
  4. The post-mutation option that you offer does not have access to the changed data, so I cannot use a post-mutation to correct mutations I do not want to allow.
  5. Your argument for not having a pre-mutation is that it slows down the graphql. However, that is exactly what @custom muations do! They run before, which is what I need and should be included!
  6. For any real security, I have to use a @custom mutation. That means in order to have any real security for EVERY SINGLE mutation (add, delete, update), I have to disable usage on the adds, and create a custom mutation, not for each Type, but for each mutation type for each Type. Insane amounts of code.
  7. If I have to write a custom mutation for every single real security mutation and type, why do we even have graphql for? I am seriously better off using DQL on my own server. Please read that statement again, if you want us to use lambdas for everything, why do we even have graphql?
  8. Arguing with @MichelDiz about the usefulness of backend security is ridiculous, although he is the only person who even responds to my posts. You guys don’t seem to be actively developing graphql, which is a problem and will force your customers to find a better product.
  9. Every single one of your competitors gives you real security options outside of external nodejs functions: Firestore, Supabase, nhost, mongodb atlas, fauna, neo4j aura, neptune, mariadb, hasura cloud, tigergraph cloud, nebula graph, harperdb, couchbase… etc… etc… The list goes on and on. They each have their downfalls as well, but security is not one of them.

Use Cases

  • There are two specific use-cases here regarding the user, and another one I spoke about above in your documentation. You guys admitted this is a known security hole.

The Real Use Case and Why this is really important

Right now we can prevent certain certain types of thing from being added, but not changed later. When you add this feature, as I have spoken about in several other posts (including this one), it opens up a plethora of new features as I said at the beginning of this post (that again I assume no one is reading):

  • required fields
  • not null fields
  • field restrictions
  • value restrictions
  • min, max restraints
  • enum restructions
  • regex restrictions
  • this list goes on and on and on…

This opens the door for security rules. They are needed!

IN SUM

  • We are stuck with your graphql. Get rid of it and just be a cloud hosting platform, or start actively developing it.
  • Lambdas are NOT EASY and you guys expect us to fix every security problem with them while actively not giving us any pre-mutation lambdas. This forces us to have to write 3 @custom mutations for every single type to have any sort of backend security, rendering graphql pointless.
  • Every single one of your competitors has security outside of lambdas functions unless they are just cloud hosting and not a full blown platform.
  • I personally would have several more projects with you guys making you more money etc. as well as at least 5 other people I have seen on these forms saying this is a deal breaker. I don’t want to waste my time with something that is not actively repairing its biggest problems, GraphQL. You will lose several clients if you don’t both:
    • Actively work on fixing the many limitations with GraphQL (starting with security and basic database features like cascade delete and branching out to features like Nested Fields)
    • Let your members know you’re actively working on fixing the many limitations with GraphQL. Are you guys? There is no evidence of this except for old empty promises. I love your product, but this is the truth.

What are you guys? A database as a service, or a full blown platform? The way GraphQL works on your platform with no field security, foreign key constraints, error messages, nested filters, and no sign of improvement, you are just a DBaaS. If that is your goal, then all power to you, get rid of GraphQL.

So yes, please fix this problem. It will give us basic front end security without having to write a custom mutation for every single field for every single type of mutation. Right now, that is ridiculous and the only way to secure your product.

That is my use case.

J

4 Likes

I am the customer Dgraph has lost.

I was heavily invested in prototyping a Dgraph based GraphQL stack for my company to evaluate, but all the issues, and need to write untestable lambdas has led me to abandon dgraph and adopt the Neo4j GRAND stack.

It’s very disappointing given the marketing Dgraph has as being the only graph database with native GraphQL support when the Neo stack is far more fully fleshed out, without the security issues.

Perhaps more disappointing is the lack of traction that these user reported issues are getting with the core team, or worse, dismissive responses.

2 Likes

@jdgamble555 Looks like something the team said has brushed you the wrong way. I apologize for that.

We internally discussed this change you’re proposing. Your experience report is lacking in examples, so we pieced together roughly you’re asking. @aman-bansal has already offered to jump on a call to better understand this issue. But that hasn’t happened. So, this is my understanding so far.

My understanding is that you want the ACL to run a check after the update as well. This would prohibit say, someone changing the ownership of a task to someone else. While this might solve your problem, this would create a new problem for another user, who does want to transfer the ownership. They would now suddenly not be able to change ownership.

There might be a different solution , which is either achievable via lambdas, as @aman-bansal mentioned. Or, via creating some “immutable” fields – so that the ownership doesn’t change at all. We can help figure those out. We’ve been consistently working on improving how lambdas operate, so users have a lot of flexibility in how they do things.

Essentially you’re proposing a solution – which goes against the ethos of Experience Reports. The proposed solution that you have, it’s unclear to us how it solves this problem generally – or, why say a different solution won’t work. Best is to explain the problem well, and show why the alternative solution is not great.

1 Like

Hey @rcbevans ,

I’m curious why you chose GRAND stack over Dgraph Cloud? What are you able to do with GRAND stack, that you can’t do with Dgraph. Happy to jump on a call to understand it better, or of course, you can expand here.

One way to solve this would be to do a pre-update and a post-update auth rules. We can re-purpose the current update rule, which would run these two internally. This can then be generically applied to various problems, and provide flexibility.

Does that sound like something that would solve your problem, @jdgamble555 ?

2 Likes

@mrjn - Thank you for taking the time to look into this.

Yes, that is the same solution that has been proposed at the beginning of this post… just having a post-update rule separately. I can understand how there could be breaking changes otherwise. Creating this post-update auth rule would definitely fix this problem.

However if you guys want to point to lambdas to solve every single security problem this would not cover, you need to also create pre-hooks as you originally said you were. The only other way to solve problems is to use @custom mutation, which renders the original GraphQL Type pointless. This would pretty much cover all bases, as security is a must.

Again, thank you for looking into this.


Finally, and perhaps most importantly, I think I can speak for all of your forum users by asking that you update your 2021 Product Roadmap so we understand what you guys are actually working on. We understand staff and time are limited, and we understand you can’t read every post. We don’t understand when there is absolutely no communication about the future of Dgraph (at least on the forums). No one wants to invest time in something that may not be a good product in the future. I also suspect it will make @MichelDiz’s job easier. This is by far, the most frustrating problem we have.

Thanks!

J

2 Likes

Hey @jdgamble555 ,

Really appreciate the positive tone of your message. Even though we’re stretched thin on multiple fronts, we do really care about our community. And it honestly hurts to see when a user, like yourself, is upset.

We’re bringing in a really solid product person in a month, who can better prioritize these things – so the product roadmap, the decision making around these requests would be better handled than what they’re today.

For this request, I think the team can put this together in a week or so. So, they’ll reach out to have this in your hands soon.

Again, apologize for the initial experience! You’d see something come out soon to solve this problem.

4 Likes

Yes! This pre-update and post-update rules are what have been needed for the last year.

Here is this simplified.

Use case: I need to allow a 1) user to update his own profile, but 2) there is a role level field that I do not want to allow a non admin user to set themselves as an admin nor 3) allow a non user to change their own username. But 4) allow an admin to update all users without restroctions

This would need a combination of RBAC and ABAC rules.

type User @auth(
  update: { or: [
    { rule: "query ($USER: String!) { queryUser(filter: { username: { eq: $USER } }) { username } }" }
    { rule: "{$ROLE: { eq: \"ADMIN\" }}" }
  ] }
) {
  username: String! @id
  role: UserRole!
}
enum UserRole {
  USER
  ADMIN
}

This update rule handles #1 and #4 but not #2 or #3

For #2 and #3 we need update auth rules that check the new data from the mutation.

type User @auth(
  update: { or: [
    { rule: "query ($USER: String!) { queryUser(filter: { username: { eq: $USER } }) { username } }" }
    { rule: "{$ROLE: { eq: \"ADMIN\" }}" }
  ] }
  updateAfter: { or: [
    { rule: "query ($USER: String!) { queryUser(filter: { username: { eq: $USER } role: { eq: USER } }) { username } }" }
    { rule: "{$ROLE: { eq: \"ADMIN\" }}" }
  ] }
) {
  username: String! @id
  role: UserRole! @search
}
enum UserRole {
  USER
  ADMIN
}
2 Likes
  updateAfter: { or: [
    { rule: """
      query ($USER: String!) {
        queryUser(filter: {
          username: { eq: $USER }, 
          { not: { has: role } }
        }) {
          username
        }
      }"""
    },
    { rule: "{$ROLE: { eq: \"ADMIN\" }}" }
  ] }

I think you could also just use { not: { has: role } } as a field restriction for field level auth restrictions. I assume this would work like add, which does not query current values (since there are none), even though technically you would probably have a value for role in the database.

That way no one could change values you don’t want them to.

This also wouldn’t interfere with the validation for no null values, since you will never really have a null value in the db.

J

Hi @mrjn

Firstly, Dgraph cloud was never an option due to lack of SOC 2 compliance. Neo4j offers AWS Cloudformation templates making it cheaper to stand up an instance in our own cloud.

Secondly, there are a lot of gaps in the Dgraph GraphQL functionality, such as issues with auth rules such as update after auth which make it a no-go for mutations out of the box, and other limitations such as lack of system generated timestamps for creation/update.

For all the issues I ran into the Dgraph team response has been to use lambdas, but there is currently no story for how to effectively develop, or debug lambdas. It’s therefore easier to instead develop a distinct front-end to the database, completely negating the benefit of Dgraph offering GraphQL in the first place.

Neo4j GraphQL library allows me to develop a node based GraphQL front-end which allows me to dip in and out of Cypher where needed, have full control over auth including built in filtering, binding, and ACLs whilst keeping a minimal number of calls to the database to resolve the required fields for the response.

Unfortunately, Cypher is also a defacto standard graph query language meaning there is vastly more content available to learn from. This matter is exacerbated by the thin content available in the DQL documentation.

I do see Dgraph as a very promising product, particularly for webscale multi-tenant scenarios and one day I can see myself revisting Dgraph, but for now the limitations/cost of adoption are just too high for me to be able to justify to my team.

5 Likes

@jdgamble555 i have started working on post update auth validation. I think things are going in good direction and I should be able to give you early access in next week or so. Anyways I will keep this thread updated.
If all goes good, it will be part of next release i.e. v21.09.1 :slight_smile: .

4 Likes

Thank you, @jdgamble555 for putting so much time into your pleas for better GraphQL support here. You do a great job of articulating not only the many reasons why those features (especially related to auth) are desperately needed, but also the frustration that comes with constantly being told by Dgraph, “just do it with DQL or lambdas”, or “you simple request for a basic feature offered by competitors isn’t reasonable”. Many of us feel it and I’m glad you were able to put it so eloquently.

2 Likes

Thanks @aman-bansal. I am looking forward to it!

One of the great uses of this thing for me will be field validation as I spoke of above. It will solve so many problems you guys don’t even realize.

It seems neo4j uses something called bind for their after-update validation. Every other graphql implementation I found pretty much has internal mechanisms for these checks outside of graphql.

You guys have to remember that Dgraph does not have any internal contraint testing like Cypher and SQL can do.


Please do not let this be the last GraphQL feature you guys program for a while.

While this is the biggest one (arguably tied with nested filters), there are a few core graphql features that you will have to have. I am not talking about needs for some, but needs for MOST.

For Your Reading Pleasure and Reference…

Recently Finished

You have already started coding…

Extremely Important!!!

Must Haves

Eventually

  • Error Codes / Messages in GraphQL
  • 2021 Roadmap - not sure I know what is up-to-date on here and what is not

Which are these SQL Equivalents

  • Many-to-Many Joins
  • NOW() Timestamps
  • Foreign Key - DELETE CASCADE / UPDATE CASCADE
  • SQL Triggers - Before AND After
  • AUTO_INCREMENT=X
  • SQL Composite Key
  • SQL Contraints - CHECK, NOT NULL, UNIQUE, DEFAULT
  • SELECT DISTINCT

You can see a pattern of what was forgetten in GraphQL, because other Databases handle these problems internally, unlike Dgraph.

Other GraphQL Implementions to Get Ideas From

Plenty more like Contentful, but these 3 are the most widely used…

I think that is it. These are regular features in other databases that solve MANY problems, not just for a few.

@mrjn - If you truly want to compete with PostgreSQL This is how you do it.

@amaster507 - Let me know if I forgot something.

@aman-bansal - Please read through these so you understand what is truly missing in Dgraph GraphQL

I am not trying to make a general feature list, but GraphQL is also the Middleware for everything in Dgraph, this list is everything, and can be done in 6 months and be done with it.

That’s all she wrote.

J

4 Likes

I’d like to add to this list.
Full interface support

It’s really a pain currently that this is not working.

Also all the lambda improvements which would finally make it usable in production:

And last but not least: Please get rid of the polling mechanism for subscriptions and implement an event driven subscription system instead!

1 Like

@aman-bansal - Any progress on this? Even if it is going to be another 10 weeks, that would be fine. I think it is just more important that you guys communicate what you’re working on until this person starts in I guess a few weeks…

Please let us know where everything stands and on 21.09 (21.10 now?).

Thanks,

J

2 Likes

@aman-bansal - Are you guys still working on this or 21.09?

@MichelDiz Could you ask the team to please give us an update? The lack of communication and updates on here is ridiculous!

J

3 Likes

@MichelDiz +1 For please having a chat with the team. It’s really an unpleasant experience since latest 21.03. release and it’s getting more annoying day to day.

1 Like

Hey guys, I was on leave for past 2 weeks thats why couldn’t respond. I am working on this feature and it will be available on next major release not 2109.

With respect to 2109 we have been continuously working on making it stable. 2109 contains major changes in terms of roaring bitmaps and this introduces some bugs which are hard to generate but could lead to data corruption. We are doing some rigourous testing and we wanted to be 100% sure that it wont lead to that state thats why this much delay. We are really sorry about that. I am hopeful that by the end of this month, we will have the GA public release for 2109.

5 Likes

@aman-bansal - Since you guys are taking a big longer than expected for 21.09, do you think you could go ahead and add this update-after feature to it? There are no GraphQL features in 21.09 (I consider the null thing a bug fix), and this feature alone would go along way to appease your users.

It is so powerful it opens so many doors to so many things, and should be quite easy to implement.

Thanks!

J

1 Like

Are you still working on this!!? If it is not going to be in the next minor release, when could we expect this? When is the next major release, 2023?

This is such a big deal as it leaves a huge security hole. There are no limits to what a user can put in the database. This effects securing fields, securing timestamps, securing roles, and preventing a user from updating other people’s records!

This is not complex like nested filters, and should be relatively easy to implement.

@mrjn @aman-bansal - Basic Communication guys please.

J

1 Like