right. supbase is actually postgres + postgrest + gotrue (for auth), and, as you know, you can self-host it via docker.
what’s wild, though, is there is no account lockout. you can brute force your way in, and there is nothing to stop you.
the same is true for pocketbase. i have not looked at soul, yet.
supabase does have a hook that could be used to write something, but it’s only available for teams accounts, which cost $500/month. i’ve been talking to them for a couple of weeks about writing a brute-force-limit and submitting a PR, but the mechanism for hooking in is still not defined.
Fail2Ban can help with that! I found a filter design proposal but it needs tweaks to actually function. A little light reading and I’m sure you’ll be better off than “let them keep trying.”
Bun has SQLite built in and now connects to PostgreSQL out of the box too ( and MySQL/MariaDB is coming soon ).
If you’re looking to implement a json-rpc api over http Bun is definitely worth considering.
If you’re unfamiliar with Bun it’s similar to Node JS ( and it’s compatible with many node modules ) but has quite a lot more built in. There are other nice features too, like web workers genuinely running in another thread and TypeScript being usable directly without having to be compiled first.
update: after a really bizarre argument with one of their techs about why you should or shouldn’t lock users out (like, dude, thanks for the advice. i disagree. STFU, already), and a bit of help from one of their other techs, then submitting a bug report, and a PR, i was able to write my way around this, using ephemeral users.
Ephemeral users, for the masochistic
Server:
create your own auth flow, which is straightforward enough (username/password/hash/salt lookup, in this case, track failures and successes, apply rules for when to lock someone out).
you’ll wind up writing a short edge function, as the endpoint for your custom auth flow. this keeps baddies from breaking your instance with a packet flood.
if you have decided that someone is ok to let pass, create a temporary (ephemeral) user in supabase. like many things in supabase, this is just done with SQL and PLSQL. easy. i didn’t know a thing about plsql before i started, but i was able to get up to speed very quickly.
return the ephemeral user info to the auth flow.
App:
uses their (regular) user credentials to hit your edge function and get authenticated
receives the ephemeral user credentials in the return message
follows the normal supabase auth flow, using the ephemeral user credentials. they’re in.
uses the supabase API for whatever language the app is written in.
if the session expires/JWT gets rejected, first try the refresh token, and if that does not work, go back to step 1, because:
Server:
systems that use JWT’s, like supabase, do not expire refresh tokens. that means that any expired user session can use a refresh token, once, to get back in (and get another refresh token). cron is your friend:
set a delete-session timer (depending on rules/logic). note that this will have the effect of invalidating the refresh token, but not the session.
set a delete-ephemeral user timer (depending on rules/logic). this has the effect of forcing the login process to start from the beginning.