PostgREST / postgrest

REST API for any Postgres database
https://postgrest.org
MIT License
22.65k stars 1k forks source link

Replace hs-jose with jose-jwt #3598

Closed wolfgangwalther closed 1 week ago

wolfgangwalther commented 1 week ago

hs-jose depends heavily on Template Haskell, but jose-jwt does not - one more step towards cross-compiling.

The new jose-jwt does not do more than the basic JWT verification for us - i.e. it checks the key and signature, but does not check exp, aud, iat and nbf values. Thus, we have to do those ourself. I added some tests to confirm the previous behavior first, then made sure the refactor returns the same kind of error messages. Some of those could certainly be improved, because they have only been showing hs-jose's JWTError types. Not here, though.

One "problem" remains: Two tests regarding the JWT cache were failing after this, because... parsing JWTs just became too fast. Thus the assumption assert (first_dur - second_dur) > 0.3 just didn't hold anymore. I tried rewriting those tests to use relative numbers, but now I have a different test failing: test_server_timing_jwt_should_not_decrease_when_caching_disabled. I could just revert the change to that test and call it a day... but I'd like to first discuss how much sense this test actually makes.


Some test results from postgrest-loadtest. Straight away on main it has a throughput of 551 req/s for me. Of course, that doesn't say much, because the loadtest does not use any JWT anyway. So I added a very basic token, with empty payload, to all loadtests and then ran the loadtest again with and without cache on both main and this branch.

branch without cache with cache
main 535 req/s 552 req/s
replace-jose 545 req/s 552 req/s

Clearly JWT parsing performance has improved. Note that this is for the most minimal JWT you can assume, so no payload/claims at all. Performance for bigger JWT is probably dominated by performance of JSON parsing, not sure though.

wolfgangwalther commented 1 week ago

One thing that jose-jwt also supports: JWE, so encrypted tokens. We currently only do JWS, so signed tokens. Could be an extensions for the future.