Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to limit schema introspection #323

Closed
vladshcherbin opened this issue Apr 25, 2017 · 16 comments
Closed

Add possibility to limit schema introspection #323

vladshcherbin opened this issue Apr 25, 2017 · 16 comments

Comments

@vladshcherbin
Copy link
Contributor

Similar as graphql/graphql-js#113

In the discussion above, there is a link, how this is done in graphql-ruby. It is also confirmed that GitHub uses this functionality.

It would be awesome to have this too.

@helfer
Copy link
Contributor

helfer commented Apr 26, 2017

@vladshcherbin interesting. Can you be a bit more specific about what you would want to achieve with this and what some example code/schema would look like?

@vladshcherbin
Copy link
Contributor Author

vladshcherbin commented Apr 26, 2017

@helfer Currently, we pass a schema with all types, fields, etc. We often need to restrict, what data a user can request, depending on the user privileges. There are different ways of doing this -
for example we can check for privileges in resolvers and return null for restricted fields.

But even in this case a user can see, what fields/types can be requested by another users. Another use-case is when there is a test feature with it's own types/mutations that we don't want to expose to other users.

In graphql-ruby there is a page that describes, how it's possible to limit (filter) the schema.

I didn't find any info about this in the docs (or missed). Maybe there is a way, how to limit it with graphql-tools or graphql-server?

@smolinari
Copy link

@vladshcherbin - is the decision on who should see things black and white? I mean, the schema that shouldn't be seen by some people is always the same or rather for the same reasons? Can you note the reasons (for instance, I know of the flagging of new features, which are still under testing). And who are these types of users? Can you be more specific in your use case?

Scott

@vladshcherbin
Copy link
Contributor Author

vladshcherbin commented Apr 27, 2017

@smolinari my use-case is main/admin functionality.

Currently, I have one schema, that is used for both main/admin parts of the app. There are types, mutations and fields in types that I don't want to expose. So, I have to create two schemas or restrict current schema. I would like to take the second path.

So, if I'm a regular user, I can see in schema only:

posts { }
updateCurrentUser { }

While if I'm an authenticated user, I can see more:

posts { }
users { }
topSecretStuff { }
createPost { }
updateUser { }
...etc

@smolinari
Copy link

smolinari commented Apr 27, 2017

Would it be too much to ask to have a different roots for the admin functionality? So, two different API endpoints?

Theoretically, no normal user should be viewing the admin area, at all. It is pretty much black and white. And, the only current way I know of is to separate the APIs completely. Trying to bake in the access into the schema is just going to be a hair pulling experience over time, especially if you try to include schema viewing restrictions. And, security is always up to everyone to make sure the right filters (or whatever the solution may be) are added. Actually, you'd have to blackout the whole schema to only "allow" the rest for public viewing. Geez what headache that would be.

At best, the only thing that might be needed is to have a flagging system for new features, which are maybe still under testing and shouldn't be made public. But, the answer for that is also a different and closed off API. So, theoretically, you'd need "only" 4 APIs. Two admins, one for testing, one for normal operations and two public APIs, but one of the public APIs is also only for admins, devs, and beta testers.

Scott

@vladshcherbin
Copy link
Contributor Author

vladshcherbin commented Apr 27, 2017

@smolinari I thought about making separate endpoints for schemas but I don't think it's a good idea. Main/admin schemas can have the same type (User for example), but with different fields - you now have to define the same User type twice. When the schema gets bigger and you split it into files, this gets even worse.

Graphql-ruby uses only and except for this. So, I would like to define schema once (with everything inside) and cut it for a regular user using only. I think it's easier to maintain one schema than 2, 4 or more.

@smolinari
Copy link

smolinari commented Apr 27, 2017

Yeah, I understand. But, and this is something the team here needs to think about, the GraphQL schema should actually be modeled after the business model/logic. In other words, your business logic layer should be governing the schema generation (and it should be automated). The schema should not become the business logic itself and that is what is happening here and with other authorization suggestions.

I think this is a real issue overall. Everyone is concentrating so much on GraphQL schema, as if it is the "one source of truth", whereas, the business level logic is the true "one source of truth" for any application. The GraphQL "generation" should be hooked up to that and only represent a gateway into the business logic. We are sort of putting the cart in front of the horse. I know we aren't that far yet, but, IMHO, that is what a proper GraphQL server should do. Currently, we only have an API, not a full server.

In other words, when there are full server solutions, then everyone is going to be saying, "Geez, why can't I just generate my schema automatically?" (edit) along with all the different kinds of rules people might come up with for generating their required schema.

Scott

@helfer
Copy link
Contributor

helfer commented Apr 27, 2017

@smolinari I think you make some interesting points, but I find that you are often talking in very abstract terms and without much specificity, which makes me question whether you have actually successfully built what you are arguing for. Most people here (myself included), are interested in solving practical problems in the first place, and we like to see concrete examples of battle-tested solutions. I know from experience that it's very easy to imagine a perfect solution, because our minds are too small to think of the practical limitations and see the contradictions in our own thoughts.

Do you have an open source example that you could show us, which uses the architecture you consider ideal, and has solved authorization etc. in a very clean way? That would really help the discussion along.

TLDR: I'd like to bring this discussion down from a philosophical debate to a practical show-and-tell, which I think will be much more useful to the people reading this now and in the future.

@smolinari
Copy link

@helfer - you are right. It is all hypothetical. However, shouldn't all design decisions be made through a hypothetical discussion of ideas, before it is put to code? That is how you save time and money. It's just agreeing on what ideas are the best ones that is difficult. 😉

I am also basing my opinion on what now 2 people from Facebook have said. That the creation of Facebook's GraphQL resolvers/ schema is automated.

Of course, one could do some POC work, and if I get the time, I'd love to. But, you must also agree, getting a schema/ resolver automation done, even as a POC, is a good bit of work. 😄

Scott

@excitement-engineer
Copy link
Contributor

@vladshcherbin I am running into the same issue as you! I would like a way to restrict the introspection for an API that contains both a main and admin part. The current solution is to maintain two different schemas. However, maintaining two schemas comes with a major maintenance cost because any changes usually means updating two parts of the API. In addition, it also means testing two schemas which creates a lot of overhead. Furthermore, it also creates some issue on the client because the app needs to be made compatible with two different schemas which complicates things.

It would be awesome if everything could be reduced to a single API making life so much easier!

@helfer
Copy link
Contributor

helfer commented May 3, 2017

@excitement-engineer If you just want to disable introspection outright, you can use the disable-introspection validation rule. For most production apps that's actually a very reasonable thing to do.

@excitement-engineer
Copy link
Contributor

Thanks so much @helfer, that looks really promising! I will give it a try:) Thank you for helping me, I really appreciate it:)

@helfer helfer closed this as completed Jun 28, 2017
@vladshcherbin
Copy link
Contributor Author

@helfer why was it closed, is there a solution?

@helfer
Copy link
Contributor

helfer commented Jun 28, 2017

@vladshcherbin you can use disable-introspection.

Also, I take the liberty to close issues without commenting when there has been no activity for a few weeks.

@vladshcherbin
Copy link
Contributor Author

@helfer thanks, will try it.

I have some opened issues in apollo repos, but the lack of inactivity doesn't mean that I don't want to find an answer. The other people can also find this issue later.

It would be really helpful if you add a small message before closing, even if you close it due to inactivity. Thank you! 😉

@cj
Copy link

cj commented Oct 12, 2018

@vladshcherbin Did you ever find a good solution that implements http://graphql-ruby.org/authorization/visibility?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants