| Having a JWT or whatever authn is irrelevant. The problem is an insufficient authz model. Exposing databases through APIs is not the problem. Exposing relations without authorization is. Under these frameworks, you can add an innocuous relationship between two models that entirely compromises security without even touching the API code. Not only that, but the graph of relations and their associated ACLs is complex. Every time you add a relation, you need to create a graph of your data model and ensure that it's safe. There are far, far more surface area to make a critical error, allowing attackers to exfiltrate large volumes of your data. I've written these bugs in similar modeled systems (there were GQL like systems before GQL). I've fixed these bugs. I've caught these bugs in code review. These bugs are orders of magnitude less likely to happen with a simpler authz model where you don't need to lock down every relation, just the table itself. This is why the GraphQL creators themselves encourage users to put authz at the business layer. 2 out of three examples above literally have no framework authz support. Postgraphile requires setting up row level security policies, meaning you have no control over what layer of code you want authz policies to live; they must be in the database. Even if you are ok with that sacrifice, you still have to find ways to manage this in version control and test, for which there is scarce tooling. Hasura seems to do the right thing here, provided you opt into it. It's not clear if it allows you to easily version control or test your ACLs. > And that's all assuming the GraphQL server has a public IP, which is far from a certainty (just like REST). Security doesn't stop at your VPN. At several hundred engineers, organizations begin implementing internal controls. In fact, my example was an employee comp manager :|. |
I might go ahead and argue that RLS in the database is exactly where security on the data model should go. Past a certain size, many databases have more than one app talking to it. This means N servers that must adhere to the same authorization rules. Hopefully at least they're written in the same language.
Not all restrictions are data-oriented though, and on that note, I agree that the restrictions should live above the database using some schema-stitching or federation.
Version control is a matter of saving the schema changes through migrations and optionally DDL audits through event triggers. I would argue that testing/tooling as you seem to be imagining it is a moot point though. I find it much easier to define table, column, and row restrictions at the DB level and let those constraints bubble up. If a table is unavailable to a set of roles/groups, better to say so in the database so that no query at any higher level could accidentally allow access when it shouldn't have. Row-level security policies don't care if someone is executing a simple `SELECT * FROM example` or a 100-line monster. That row in isolation or as part of a gargantuan query reading/writing through a view or three doesn't matter. The reason Postgraphile relies on PostgreSQL itself for authorization is precisely because PostgreSQL does such a good job of it.
You are correct that simple GUI tools are lacking in this regard, but I'm not sure the use cases I've come across for it fit a GUI tool. For a data platform in a large aerospace company the method of allowing/restricting access was dependent on tagging (both AND and OR). Combine it with some temporal query support, and the RLS policies were essentially code, not just declarative. Then the GUI was the web manager UI (custom). Worked quite well. And while that data platform had some bugs we had to work out as all software does, we never had a problem with the data-level security. We even found some bugs at the app and UI layers precisely because some developers overlooked some corner cases.
App-level integration tests appeared more than sufficient to flush out any problems (or verify correct behavior) in the data-layer security.
Data-level restrictions and query auditing (below the level of an app or server) become even MORE relevant as employee size grows, not less.