Skip to content

Enforce IP blocks on the request path (wire isIPBlocked into middleware) #352

Description

@mcull

Follow-up from P0-11 (#337). Claude-doable.

P0-11 made isIPBlocked() real (DB-backed) and wired event logging + the admin block/unblock UI. But nothing calls isIPBlocked on the request path, so blocking an IP in the admin dashboard records the block without actually denying that IP any traffic.

Action

  • Call isIPBlocked in middleware.ts (or a shared guard) early in the request lifecycle; return 403 for active, unexpired blocks.
  • Cache the lookup in Redis (short TTL, e.g. 30–60s) so this isn't a per-request DB hit — @upstash/redis is already wired (P0-3). Invalidate/refresh on blockIP/unblockIP.
  • Decide scope: enforce on all routes vs. API/auth only (static assets and the admin unblock route must not be self-blockable).
  • Log an IP_BLOCKED/UNAUTHORIZED_ACCESS security event when a blocked request is denied (loop closes with the dashboards).

Why P1 not P0: the admin tooling and persistence ship in #337; this is the enforcement half. Not a launch blocker on its own, but the block button is misleading until it lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High prioritysecuritySecurity issuews:infraInfrastructure, security, deploy, observability

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions