> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pensionsportal.ie/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limiting and Abuse Prevention

> How PensionsPortal.ie defends against brute force, credential stuffing, and API abuse.

PensionsPortal.ie applies rate limiting and abuse controls at multiple layers: Cloudflare's edge, Vercel's platform, and application-level input validation.

## Cloudflare Rate Limiting (Primary Layer)

Cloudflare WAF provides the primary rate limiting layer, applied before requests reach the application:

* **DDoS protection** — automatic mitigation for volumetric and application-layer attacks
* **Bot management** — Cloudflare's bot score filters automated traffic and credential stuffing attempts
* **Rate limiting rules** — configurable per-path and per-IP rate limits, with particular focus on authentication endpoints (`/api/auth/signin`, `/api/auth/forgot-password`)
* **IP reputation** — requests from known malicious IP ranges are blocked at the edge

<Note>
  Cloudflare rate limiting rules are managed via the Cloudflare dashboard (Zone → Security → WAF → Rate Limiting). See [Cloudflare WAF and Zero Trust](/security/cloudflare-waf-and-zero-trust) for full configuration details.
</Note>

## Authentication Endpoint Protection

The login and password reset endpoints are the highest-risk targets for credential attacks:

| Endpoint                         | Cloudflare Rate Limit       | Notes                                 |
| -------------------------------- | --------------------------- | ------------------------------------- |
| `POST /api/auth/signin`          | 5 attempts / IP / minute    | Brute force protection                |
| `POST /api/auth/forgot-password` | 3 requests / IP / 5 minutes | Prevents email enumeration via volume |
| `POST /api/auth/reset-password`  | 3 attempts / token          | Token is single-use                   |

## Application-Layer Controls

### Password Reset Tokens

Password reset tokens (table: `password_resets`) are:

* Single-use — consumed on first use
* Time-limited — expire after a short window (e.g., 1 hour)
* Cryptographically random — not guessable

### Input Validation

All API routes validate input using TypeScript type checking and explicit field validation before processing. Invalid requests return `400 Bad Request` with a sanitised error message — no internal details are exposed.

### Error Message Sanitisation

Authentication failure messages are deliberately generic:

* "Invalid email or password" — does not distinguish between unknown email and wrong password (prevents email enumeration)
* Database errors return a generic service unavailable message — connection strings are never exposed

The security test suite (`src/tests/api/security.test.ts`) verifies this behaviour with automated regression tests.

## Vercel Platform Controls

Vercel provides platform-level protection:

* **Edge function limits** — request timeouts prevent slow-loris attacks
* **Function invocation limits** — Vercel's usage limits provide a backstop against extreme abuse scenarios
* **Serverless scaling** — auto-scaling reduces the effectiveness of volumetric attacks

## AI Endpoint Protection

The AI chat endpoint (`POST /api/ai/chat`) requires authentication. Unauthenticated requests are rejected before the AI provider is called, preventing cost-inflating abuse.

## RAG Ingest Endpoint

The `POST /api/rag/ingest` endpoint (corpus ingestion) is protected by a bearer token (`RAG_INGEST_SECRET`), restricting access to authorised operators only. It is not accessible from the application UI.

## Monitoring and Alerting

Rate limit events and blocked requests are visible in:

* **Cloudflare Analytics** — edge-level block events, bot score distribution
* **Sentry** — application-level error spikes that may indicate abuse patterns

See [Monitoring and Alerting](/security/monitoring-and-alerting) for alert configuration.
