If you have a standard CRUD API service that exposes endpoints for reading and writing effectively all the tables in your DB (presumably with varying levels of API-layer auth on each such action), then what is the difference between securing and then exposing that API service layer, and securing and then exposing the DBMS backing that API service layer?

(Where by "securing the DBMS" I mean the same thing as I do by "securing the API": issuing each authorized client their own access credentials; giving each such auth role proper ACLs to every resource; and using quotas and resource-encapsulation to prevent client accounts from DoSing the system as a whole.)

---

Or, let me put that another way. Consider http://postgrest.org/ — it's an automatic RESTful API gateway for PostgreSQL. Essentially, PostgREST is nothing more than a wire-protocol translator. Rather than standing as a separate daemon on the network, it could just be built into the DBMS itself—i.e. your DBMS could speak REST just as well as it can speak SQL. (And some DBMSes do speak REST. Mongo, CouchDB, ElasticSearch, etc.)

If you expose the "REST API of the DBMS" to the world, rather than the SQL API of the DBMS, this doesn't change the DBMS's security story. You'd still be exposing your DBMS, and leaving it vulnerable unless you explicitly take steps to secure it for public access.

Which implies, I think, that if you have a public API layer—authed or not—that can be reduced down to the "CRUD of every table the connected role can touch" API that PostgREST exposes, then you're already exposing your DBMS to the world. You're obfuscating the DBMS's wire protocol, but you're not changing its security story: you still have a data store that can be talked to (and attacked) by arbitrary clients. They just have to translate their attacks to REST/GraphQL/whatever instead of SQL. But the queries will still end up at the DBMS, and the attack surface of such queries is still pretty much identical to the attack surface you get by speaking SQL directly to the DBMS (insofar as what you care about in your DBMS is your data and the ability to query it.)

---

One more thought:

There is a difference between "public access" and "shared access."

• Shared access is what an "open but authenticated" API layer gives you: you can freely sign up to get your own set of API credentials, and then use them to make queries.

• Public access is what an unauthenticated API layer gives you: anyone can just submit a query at random without introducing themselves, and there's no way other than heuristics to limit a user from DoSing you just by using a million IPs to issue one concurrent query apiece.

DBMSes were, and are, designed for shared access. They have all the security features you need to secure them for shared access.

DBMSes don't give much thought to public access. They are perfectly fine at delivering the security story you'd expect of a "guest" role, but they don't have the same decades of engineering put into things like IP rate-limiting, grey-listing, etc. that web servers do. So the security story is good, but the DDoSing story is less so.

Thankfully, though, most such DDoS-protection logic doesn't live in web servers, but in load balancers. Some load balancers are just for HTTP, but TCP load balancers like HAProxy can configured protect your DBMS against DDoS attacks just fine, just as well as they can protect a web-app.