6 ms·
I'm surprised that there's no mention about the interplay of authorization and data fetching in the post. This is one of the things that seems to be a little b
by tango12 6y ago
I'm surprised that there's no mention about the interplay of authorization and data fetching in the post.
This is one of the things that seems to be a little bit nuanced (surprisingly?) because it's not just about creating the right query to fetch data optimally, but it is also about making sure that it's handling data with the right authorization context of the current end-user.
This becomes especially tedious when you're fetching objects and lists of objects and the "resolvers" to fetch those objects need to mix in authorization rules in each resolver.
Hasura[1] tackles this by providing a model level authorization layer (similar to Postgres RLS, but at the Hasura/application layer) which makes GraphQL to SQL feasible even for apps. It's not just about a translation layer. Postgraphile does this using Postgres RLS.
Those are the key benefits that make Hasura useful for data-fetching in practice. Over the last few years we've been working with users with billions of records per table, especially in enterprise environments. And it's great to see how smooth things have been.
Especially as the number of tables and models explode, having a declarative system to specify authorization at a model level and then get a guarantee that an effective SQL query will get created is a nice thing to have. It allows our users to deal with higher level concepts, model data, setup authorization, make queries, look at query plans (which now show full SQL queries), add indexes, test, add to an allow-list, done.
[1] - https://hasura.io https://hasura.io
(I'm from Hasura)
- billme 6y agoDoes Hasura have any stack recommendations? For example, here’s one user’s stack: https://news.ycombinator.com/item?id=22787313 https://news.ycombinator.com/item?id=22787313
- dahdum 6y agoMaybe not publicly, but they have really great documentation and examples for using Auth0, Apollo, and React. Made getting started way easier for me.
- chrisweekly 6y agoThank you! Terrific, helpful comment. Bookmarked.
- kasbah 6y agoWhat I didn't find out while trialing Hasura is if it's possible to declare your GraphQL API using code rather than the Hasura web GUI. I eventually gave up on it because I figured I couldn't store the configuration I was making as code in a git repo. Your comment makes me think I was maybe wrong about that? Could you confirm and/or link to some docs about this aspect?
- tango12 6y agoEverything in Hasura is configured declaratively. The web GUI is essentially just updating that configuration. There are a few options: 1. You use the GUI and then export/import the metadata 2. You can use the GUI and as you do, the GUI will keep incrementally updating the metadata configuration file and even create database migrations for you in your folder on your machine, kind of like an IDE 3. You can stop using the UI altogether, and just write the configuration by hand Docs: https://hasura.io/docs/1.0/graphql/manual/migrations/index.html https://hasura.io/docs/1.0/graphql/manual/migrations/index.h... Also, feel free to ask around on our discord if you need help: https://discord.gg/hasura https://discord.gg/hasura
- adav 6y agoThis approach means one’s own deployments of Hasura can’t be immutable?
- tango12 6y agoThere's a docker image that can take a configuration file as input. https://hasura.io/docs/1.0/graphql/manual/migrations/advanced/auto-apply-migrations.html https://hasura.io/docs/1.0/graphql/manual/migrations/advance... You can choose to bring in that configuration via a Kubernetes configmaps type thing, or by baking a new image for a release (like you would have done with your source code say).
- adav 6y agoYep, that’s what I’ve been doing for my experiments with Hasura so far :) It just feels a little “off-piste”.
- aidos 6y agoInitially I was confused about the permissions in data approach, as it becomes harder to declaratively audit the current set of applied permissions. I’m not a massive fan of migrations in yaml generally (I do miss alembic) but it does the job. It occurs to me though that everything in data means you can do migrations atomically, including all the permissions changes. Internally we have a little tool that dumps the current state of the permissions into a txt file that we commit in the repo. This makes it easier to get a snapshot of the permissions as well as compare what’s changed. The Hasura internal tables are pretty self explanatory so it only took an hour or so to knock up. Ps, love hasura. I suspect we’ll end up running it in front of all our data layers eventually. If there was an easily hackable admin front end that sits over graphql I’d be interested in hearing about it. Leaning towards Forrest admin at the moment, but I’m still not 100% sold.
- dmitryminkovsky 6y agoThe Hasura authorization system is fantastic! It's definitely the icing on the Hasura cake.
- xuorig_ 6y ago> This becomes especially tedious when you're fetching objects and lists of objects and the "resolvers" to fetch those objects need to mix in authorization rules in each resolver. That largely depends on your existing architecture. Some of us have authorizations services, others have a separate database to store policies and others have authorization rules deep into their existing code base. However, as I mention in the post, Hasura is great if you make the decision to use it early for a project, but it's not a luxury everyone has, and not a decision everyone will want to make even starting a new project. > because it's not just about creating the right query to fetch data optimally, but it is also about making sure that it's handling data with the right authorization context of the current end-user. You're absolutely right that its tricky. (A good example of this is Facebook building a viewer-aware entity layer for some of these reasons). Hasura makes this great as well, but again, many are not in a position so "simply use Hasura". That's why I quickly mention that the post will focus on existing/mature/complex codebases.
- tango12 6y agoThanks, this helps! (Also, hi Marc!) Even though authorization systems or database policies exist outside the "data" database, quite often that information is used during the data fetch right? Let's say the user has certain properties and then those properties of the user and attributes of the data are used to define a constraint which is usually applied as the data fetch query is made. For example, our goal at Hasura is to allow developers to bring values from external systems as well in their rules, so that the authorization rule doesn't exclusively depend on values coming in from the same database. This is what makes Hasura useful on existing systems (alongside your existing complex codebase), especially when you're looking for extremely high read performance or subscriptions for example. I do want to emphasize that Hasura is far more valuable (in a business sense) for our users on existing systems that for new systems! I'd love to hear examples from your experience about the ratio of authz where it could be declarative vs where it was necessarily imperative in code. The "values" in the constraint specification can come from anywhwere, the viewer entity, another database, but the constraint is declarative. What's it been like at GraphLQ API for github? Specifically, do you have a sense for how complex the authorization for the data models is beyond "declarative" properties of the data and the viewer itself?
- namelosw 6y agoNice to see guys from Hasura here! The product is pretty slick. I scratch my head on this problem for quite a while. I would love things like database-to-GraphQL or even Datalog solutions. But eventually, I found I still need to add another web endpoint on top of it to fix all the authorization logic, making things equally verbose like typical Web applications, defeating the purpose of using database-to-GraphQL solutions. Having RBAC is Okayish for a lot of applications, but also not feasible for others. Usually ABAC or more expressive authorization rules are needed. Do you have any thoughts on more expressive/powerful ways to tackle this issue?
- sixdimensional 6y agoI do - and I have some good experience on this issue. I think at a minimum you need authentication, authorization, access controls (some of which are security filters), and of course auditing. You need to support RBAC, and also ABAC, roles/security groups, and then the access controls too. The solution to row/cell level security (RLS) in most databases comes through projection and predicate-based filters and/or data obfuscation/masking/encryption. These are a form of access controls, and these access controls, in terms of (oversimplified) read/write controls on top of permission objects that are security filters. These security filters may use attributes from a role, user or be defined within a permission object themselves and then granted to roles, users and/or groups of users. One simple example - if the ultimate interface to other systems is running a SQL query on a remote system, then RLS would add a condition to the WHERE clause of the query that filtered the rows returned based on an attribute. To get to cell-level protection (e.g. row/column) in a relational result, you need projection limitations (e.g. filtering the columns returned in a SELECT or obfuscating the data in those rows returned using data masking). The most advanced solutions encrypt the data in such a way as you can still use the data to join, but cannot see the source values due to the security filtering layer. Hasura seems to be going down the path (I worked for a company that did the same) of integrating "data access firewall" type features into their product. It makes a lot of sense - as it is an interface layer, a lot of additional security can be baked in that goes above and beyond that of the actual DBMS behind it. This is especially needed in federated situations where you have heterogeneous platforms that differ in their security capabilities (as is the case with GraphQL and Hasura, trying to span multiple data sources). You can even add security rules like.. preventing cross joins, preventing long running queries - basically you can address just about every concern DBAs have about letting people run queries directly against a DB.
- criddell 6y ago> Hasura tackles this by providing a model level authorization layer Why does Hasura need to know about the authorization model? Graphql.org's best practices guide[1] says authorization should be in the business layer and should be a single source of truth. In other words, GraphQL responses should be going through the same authorization module as REST or RPC responses. [1] https://graphql.org/learn/thinking-in-graphs/#business-logic-layer https://graphql.org/learn/thinking-in-graphs/#business-logic...
- btown 6y agoHasura is designed to implement the entirety of the Business Logic Layer - it provides an interface directly on top of Postgres. Certainly this isn't appropriate for certain applications, though https://hasura.io/blog/custom-business-logic/ https://hasura.io/blog/custom-business-logic/ makes it very versatile. But for many line-of-business applications it's ideal.
- amaranth 6y agoThat only works if your API access is all or nothing. The existing authorization tooling will just see everything as requests to `/graphql`. If you want per-query or even per-field permissions you need to do something inside the GraphQL layer.