feat: JWT cache implementation based on sieve algorithm (#4084)
Changes: 1. Refactoring and some cleanup of JWT handling code: * Instead of caching AuthResult cache decoded claims (which signature was verified). Validating claims and determining role is done after cache lookup * Cleaned up API so that usage of it is simplified: lookupJwtCache cache key >>= parseClaims configJwtAud time * Handling of JwtCacheState initialization and updates of configuration is encapsulated in Auth.JwtCache module 2. Generic high performance (hopefully) scalable, dynamically resizeable cache implementation based on stm, stm-hamt and sieve algorithm. It also integrates with PostgREST measurements infrastructure providing usage stats (ie. hit ratio, evictions count)
This commit is contained in:
+11
-11
@@ -152,7 +152,7 @@ def test_jwt_errors(defaultenv):
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ def test_jwt_errors(defaultenv):
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "false",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
}
|
||||
|
||||
@@ -1446,7 +1446,7 @@ def test_jwt_cache_server_timing(defaultenv):
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
"PGRST_DB_CONFIG": "false",
|
||||
}
|
||||
@@ -1482,7 +1482,7 @@ def test_jwt_cache_without_server_timing(defaultenv):
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "false",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
"PGRST_DB_CONFIG": "false",
|
||||
}
|
||||
@@ -1503,7 +1503,7 @@ def test_jwt_cache_without_exp_claim(defaultenv):
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
"PGRST_DB_CONFIG": "false",
|
||||
}
|
||||
@@ -1772,7 +1772,7 @@ def test_jwt_cache_purges_expired_entries(defaultenv):
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
"PGRST_DB_CONFIG": "false",
|
||||
}
|
||||
@@ -1838,10 +1838,10 @@ def test_log_pool_req_observation(level, defaultenv):
|
||||
postgrest.session.get("/authors_only", headers=headers)
|
||||
|
||||
if level == "debug":
|
||||
output = postgrest.read_stdout(nlines=4)
|
||||
assert pool_req in output[0]
|
||||
assert pool_req_fullfill in output[3]
|
||||
assert len(output) == 4
|
||||
output = postgrest.read_stdout(nlines=5)
|
||||
assert pool_req in output[1]
|
||||
assert pool_req_fullfill in output[4]
|
||||
assert len(output) == 5
|
||||
elif level == "info":
|
||||
output = postgrest.read_stdout(nlines=4)
|
||||
assert len(output) == 1
|
||||
@@ -1882,7 +1882,7 @@ def test_invalidate_jwt_cache_when_secret_changes(tmp_path, defaultenv):
|
||||
**defaultenv,
|
||||
"PGRST_JWT_SECRET": f"@{external_secret_file}",
|
||||
"PGRST_DB_CHANNEL_ENABLED": "true",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400", # enable cache
|
||||
"PGRST_JWT_CACHE_MAX_ENTRIES": "86400", # enable cache
|
||||
"PGRST_DB_ANON_ROLE": "postgrest_test_anonymous", # required for NOTIFY
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user