4 ms·
A couple ways: One you implement validation functions [1] on user databases to control what kind of data can be inserted into couch. These functions can only b
by Volundr 7y ago
A couple ways:
One you implement validation functions [1] on user databases to control what kind of data can be inserted into couch. These functions can only be changed by database admins, not users, so can act as a security mechanism controlling what goes in.
As mentioned by others you can also implement a proxy. This doesn't have to interfere with sync functionality, you just have to make sure you proxy all the endpoints in the replication protocol [2]. Envoy [3] is one such proxy that essentially applies document level permissions to a CouchDB database without interfering with sync.
If the goal is just to limit document size, or throttle clients trying to hammer the API, this doesn't even have to be a custom proxy, and reverse proxy with the needed control knobs (such as NGINX) will do. You can of course combine this with validation functions, using validations to ensure the everything that comes in is the right "shape" and using NGINX and it's ilk to apply throttling and sane request limits.
At scale there's a decent chance you want a proxy in front of your Couch instance anyway, since Couch is truly multi-master, meaning you probably want to balance your clients across all your nodes anyway.
[1] https://docs.couchdb.org/en/stable/ddocs/ddocs.html#validate-document-update-functions https://docs.couchdb.org/en/stable/ddocs/ddocs.html#validate...
[2] https://docs.couchdb.org/en/stable/replication/protocol.html# https://docs.couchdb.org/en/stable/replication/protocol.html...
[3] https://github.com/cloudant-labs/envoy https://github.com/cloudant-labs/envoy
- yatsyk 7y agoThank you for pointing at validation, I'll check it. It's not completely clear what is it possible to limit not only particular document but database, or how to handle conflict if document changed on pouch, but rejected on couchdb server. I'm not sure about current time but previously it was a problem that couchdb file grow until some limit on filesystem and couchdb just crashed. Start of the envoy readme: it's not battle tested or supported in any way. Also it doesn't do any validation apart from limiting permissions for different users. It's easier to reimplement couchdb than to create smart proxy that will estimate is this query expensive or not. I'm not saying about rate-limiting proxy or load-balancing to different backends which could be implemented on nginx or something else.
- Volundr 7y agoI'm not clear what you mean by limiting "not only particular document but database". As far as a document changing in pouch and rejected on the server, that's one of two scenarios. 1) The client you wrote is bugged and generated bad data. This scenarios can occur just as easily using Postgres and an application server. What does your app server do if a client tries to send bad data? (Answer: Whatever you told it to do. Most likely throwing a 500 when your databases refuses the incoming data.) As for what will happen when pouch syncs to couch the server will let everything else sync, but not the bad document. The return value from the API call will tell you what documents didn't sync. 2) Someone is intentionally trying to shove bad data into your database. In this case it's worked as advertised and rejected the bad data. What do you care if a malicious client breaks? What kind of "expensive" query are you envisioning? Mango queries don't support joins, and only simple equality filters, so in general the worst thing someone could do is send a query that doesn't use an index, but why are you letting the client query the server in the first place? Just have the client sync and query client side. Or don't allow access the the _find endpoint and restrict them to the map/reduce view you handwrote. If you must let them send arbitrary queries (which to me implies a relatively trusted user, but let's pretend their not), then run the query with a limit of 1 or 0, and examine the execution stats to see if they are using an index, and check their query to see if their limit is reasonable. But at this point you've now entered into a scenario that's going to be very difficult with a custom API too.
- yatsyk 7y ago> I’m not clear what you mean by limiting "not only particular document but database". I’ve limited document size to 10mb and ratelimited updates to 10 per second. Client starts to update document with random data 10 requests per second. As far as I understand couch stores all versions at least some time. This means that this one client could fill space on my server 100mb/s. There is no such issues with postgress, and no one allow clients execute raw queries on database without any application server. Document only 10mb but database is huge. > What kind of "expensive" query are you envisioning? I have never used couch, so I don’t know what could be expensive. May be some lookup without index or something like this. Sorry for my ignorance, is it true that if I limit couch only to replication it will not be any not indexed lookups? Looks like implement secure system with couch is very hard but I can’t find any best practices, mostly only authentication and basic validation.