Aug 26 - Enhance security 3
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Pytest (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled

This commit is contained in:
2026-08-26 13:54:48 -04:00
parent 6c1bef73c8
commit cc216b0d98
16 changed files with 11056 additions and 43 deletions
+18 -8
View File
@@ -23,14 +23,24 @@
# X-Frame-Options and nosniff from every JS and CSS asset.
# ── Rate limiting zones ────────────────────────────────────────────────────────
# NOTE the units: these are per MINUTE (r/m), not per second. api_limit is
# therefore 1 req/s sustained for the whole API, with burst=20 absorbing spikes.
# A vault page load fires several /api/* calls, so tightening these further will
# surface as 429s to normal users.
# auth_limit: 10 req/min per IP for auth endpoints (login, register, MFA verify)
# api_limit: 60 req/min per IP for all other API endpoints
limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m;
# MIND THE UNITS — r/s and r/m are easy to confuse, and getting it wrong is
# invisible until users start seeing 429s.
#
# api_limit was 60r/m, i.e. 1 req/s sustained for the ENTIRE API. A single vault
# page load fires several /api/* calls (vault, folders, sharing inbox, me), and
# any active session drains the burst bucket quickly, so normal use produced
# spurious 429s. Now 10r/s, which is generous for a human and still bounds
# scripted abuse.
#
# auth_limit stays deliberately tight — it is the brute-force surface. 20r/m
# with burst=5 is well above what a human retyping a password needs, and
# Flask-Limiter (Redis-backed, 10/min on /login) remains the primary guard;
# this zone exists to shed load before it reaches Gunicorn.
#
# auth_limit: 20 req/MINUTE per IP — login, register, MFA verify
# api_limit: 10 req/SECOND per IP — everything else
limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=20r/m;
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
server_name pwkeeper.ngodanguyen.tech passkeeper.ngodanguyen.tech;