Skip to content

cliff-de-tech/Gatekeeper

Repository files navigation

Gatekeeper – API Protection Service

Production-grade rate limiting, abuse detection, and Redis-backed counters as Express middleware.


✨ Features

Capability Description
Sliding / Fixed Window Choose per-policy rate-limit algorithms
IP / User / IP+User Scopes Apply limits independently to different principals
Redis-backed counters Atomic increments, TTL-managed windows, horizontally scalable
Fail-open / Fail-closed Configurable enforcement when Redis is unavailable
Metrics & Logging Pino-compatible structured logging
Configurable Policies JSON-based declarative policy definitions

🏗️ Architecture Overview

             ┌──────────────────────┐
             │     Client (IP)      │
             └──────────┬───────────┘
                        │
                        ▼
           ┌────────────────────────┐
           │   Express / API Layer  │
           └────────────┬───────────┘
                        │
        ┌───────────────▼───────────────┐
        │        Gatekeeper Middleware   │
        │   • extract IP / User          │
        │   • iterate policies           │
        │   • check counters (Redis)     │
        └───────────────┬───────────────┘
                        │
        ┌───────────────▼───────────────┐
        │      RedisRateLimiter          │
        │   • fixedWindow: INCR + TTL    │
        │   • slidingWindow: ZSET        │
        └───────────────┬───────────────┘
                        │
                  ┌─────▼─────┐
                  │   Redis   │
                  └───────────┘

Rate-Limit Algorithms

  1. Fixed Window – Simple INCR counter per window; cheap but allows minor burst at window boundaries.
  2. Sliding Window – Uses a Sorted Set (ZSET) to record timestamps. Removes entries older than window start, then counts.

Fail-open vs. Fail-closed

Mode Behavior when Redis is down
fail-open (default) Request is allowed through; logs error
fail-closed Immediately responds with 503

📦 Installation

npm install            # or yarn install
npm run build          # compiles TypeScript
npm test               # runs Jest test suite

🚀 Quick Start

import express from 'express';
import { Gatekeeper } from 'gatekeeper';

const app = express();

const gatekeeper = new Gatekeeper({
  policies: [
    {
      id: 'ip-basic',
      algorithm: 'sliding-window',
      limit: 100,
      windowSeconds: 60,
      scope: 'ip',
    },
    {
      id: 'user-tight',
      algorithm: 'fixed-window',
      limit: 20,
      windowSeconds: 60,
      scope: 'user',
    },
  ],
  identifyUser: (req) => req.headers['x-user-id'] as string | undefined,
});

app.use(gatekeeper.middleware());

app.get('/data', (_req, res) => res.json({ data: 'protected' }));
app.listen(3000);

🛠️ Configuration

GatekeeperOptions

Property Type Description
policies RateLimitPolicy[] Array of rate-limit policies
redisUrl string Redis connection string (default redis://localhost:6379)
redisClient ioredis (optional) Bring-your-own Redis client
redisPrefix string Key prefix (default gatekeeper)
mode 'fail-open' | 'fail-closed' Behavior when Redis fails
logger GatekeeperLogger Pino-compatible logger
identifyUser (req: Request) => string | undefined Extract user ID from request

RateLimitPolicy

Property Type Description
id string Unique identifier
algorithm 'fixed-window' | 'sliding-window' Algorithm
limit number Max requests in window
windowSeconds number Window length
scope 'ip' | 'user' | 'ip-user' Key scope
keyPrefix string (optional) Custom Redis key prefix
penaltySeconds number (reserved)
description string Human-readable description

🐳 Docker Deployment

docker-compose up --build

The example app will be available at http://localhost:3000.


🧪 Tests

npm test

Tests use ioredis-mock to avoid needing a real Redis instance.


📂 Project Structure

Gatekeeper/
├── src/
│   ├── counter.ts      # Fixed & Sliding window logic
│   ├── gatekeeper.ts   # Middleware class
│   ├── redis.ts        # Redis client factory
│   ├── types.ts        # TypeScript interfaces
│   └── index.ts        # Public exports
├── examples/
│   └── express-app.ts  # Integration demo
├── tests/
│   └── gatekeeper.test.ts
├── Dockerfile
├── docker-compose.yml
├── package.json
├── tsconfig.json
└── README.md

🔐 Security Considerations

  1. IP spoofing: Trust X-Forwarded-For only behind a trusted proxy.
  2. Redis hardening: Use ACLs and TLS in production.
  3. Key entropy: Salting keys can prevent attackers from predicting patterns.

📝 License

MIT

About

Gatekeeper — API Rate Limiting & Abuse Detection Engine

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published