DEV Community

Thesius Code
Thesius Code

Posted on • Originally published at datanest-stores.pages.dev

API Security Framework

API Security Framework

A production-ready security framework for hardening REST and GraphQL APIs against the most common attack vectors. This toolkit provides battle-tested authentication middleware, intelligent rate limiting, strict input validation, CORS policy generators, and automated security testing scripts — everything you need to ship APIs that withstand real-world attacks without bolting on security as an afterthought.

Key Features

  • JWT Authentication Middleware — Token generation, validation, refresh rotation, and blacklisting with configurable expiry and algorithm selection (HS256, RS256, ES256).
  • Adaptive Rate Limiting — Sliding window rate limiter with per-endpoint, per-user, and per-IP granularity. Includes burst detection and automatic throttle escalation.
  • Input Validation Engine — Schema-based request validation for JSON payloads, query parameters, path variables, and headers. Catches injection attempts, oversized payloads, and type mismatches.
  • CORS Policy Generator — Generates strict, environment-aware CORS configurations. Separate policies for dev, staging, and production with origin whitelisting.
  • GraphQL Security Layer — Query depth limiting, complexity analysis, introspection disabling for production, and field-level authorization checks.
  • Automated Security Scanner — Python scripts that test your API endpoints for OWASP API Top 10 vulnerabilities, generating actionable HTML reports.
  • Request Signing & HMAC Verification — Middleware for verifying request integrity using HMAC-SHA256 signatures, preventing tampering in transit.

Quick Start

# Extract and review the framework
unzip api-security-framework.zip
cd api-security-framework/

# Review the configuration template
cp config.example.yaml config.yaml

# Run the security scanner against your API
python3 scripts/security_scan.py --target https://api.example.com/v1/ --output report.html
Enter fullscreen mode Exit fullscreen mode

Minimal Authentication Setup

import hmac
import hashlib
import json
import time
import base64
from typing import Optional

class APIAuthenticator:
    """Lightweight JWT-style token handler using stdlib only."""

    def __init__(self, secret_key: str, expiry_seconds: int = 3600):
        self.secret_key = secret_key.encode()
        self.expiry_seconds = expiry_seconds
        self._blacklist: set[str] = set()

    def generate_token(self, user_id: str, roles: list[str]) -> str:
        header = base64.urlsafe_b64encode(json.dumps({"alg": "HS256"}).encode()).decode()
        payload_data = {
            "sub": user_id,
            "roles": roles,
            "iat": int(time.time()),
            "exp": int(time.time()) + self.expiry_seconds,
        }
        payload = base64.urlsafe_b64encode(json.dumps(payload_data).encode()).decode()
        signature = hmac.new(self.secret_key, f"{header}.{payload}".encode(), hashlib.sha256).hexdigest()
        return f"{header}.{payload}.{signature}"

    def validate_token(self, token: str) -> Optional[dict]:
        try:
            header, payload, signature = token.split(".")
            expected_sig = hmac.new(self.secret_key, f"{header}.{payload}".encode(), hashlib.sha256).hexdigest()
            if not hmac.compare_digest(signature, expected_sig):
                return None
            if token in self._blacklist:
                return None
            data = json.loads(base64.urlsafe_b64decode(payload))
            if data["exp"] < int(time.time()):
                return None
            return data
        except (ValueError, KeyError):
            return None
Enter fullscreen mode Exit fullscreen mode

Architecture / How It Works

Client Request
    │
    ▼
┌─────────────────┐
│  Rate Limiter    │──► 429 Too Many Requests
└────────┬────────┘
         ▼
┌─────────────────┐
│  CORS Validator  │──► 403 Forbidden (bad origin)
└────────┬────────┘
         ▼
┌─────────────────┐
│  Auth Middleware  │──► 401 Unauthorized
└────────┬────────┘
         ▼
┌─────────────────┐
│  Input Validator │──► 422 Validation Error
└────────┬────────┘
         ▼
┌─────────────────┐
│  Your API Logic  │──► 200 OK
└─────────────────┘
Enter fullscreen mode Exit fullscreen mode

Each layer is independent and composable. You can use the rate limiter alone, pair authentication with input validation, or deploy the full pipeline.

Usage Examples

CORS Policy Configuration

cors:
  production:
    allowed_origins:
      - "https://app.example.com"
      - "https://admin.example.com"
    allowed_methods: ["GET", "POST", "PUT", "DELETE"]
    allowed_headers: ["Authorization", "Content-Type", "X-Request-ID"]
    expose_headers: ["X-RateLimit-Remaining", "X-RateLimit-Reset"]
    max_age: 86400
    allow_credentials: true

  development:
    allowed_origins: ["http://localhost:3000", "http://localhost:5173"]
    allowed_methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
    allowed_headers: ["*"]
    max_age: 0
    allow_credentials: true
Enter fullscreen mode Exit fullscreen mode

Configuration

Parameter Default Description
rate_limit.max_requests 100 Max requests per window per client
rate_limit.window_seconds 60 Sliding window duration
auth.algorithm HS256 Token signing algorithm
auth.token_expiry 3600 Token TTL in seconds
auth.refresh_expiry 604800 Refresh token TTL (7 days)
cors.max_age 86400 Preflight cache duration
validation.max_payload_bytes 1048576 Maximum request body size (1MB)
graphql.max_depth 10 Maximum query nesting depth
graphql.max_complexity 1000 Maximum query complexity score

Best Practices

  1. Always validate on the server — Client-side validation is UX; server-side validation is security.
  2. Use constant-time comparison for tokens and signatures (hmac.compare_digest, not ==).
  3. Rotate secrets regularly — Automate key rotation and support multiple active signing keys during transitions.
  4. Log security events separately — Authentication failures, rate limit hits, and validation errors should go to a dedicated security log.
  5. Set strict Content-Type headers — Reject requests without proper Content-Type to prevent MIME confusion attacks.
  6. Version your API — Security policies can differ per version; don't break existing clients when tightening rules.

Troubleshooting

Problem Cause Fix
CORS errors in browser Origin not in allowlist Add your frontend domain to cors.allowed_origins
429 responses during testing Rate limiter too aggressive Increase max_requests or add test IPs to bypass list
Token validation fails after deploy Clock skew between servers Use NTP sync; add 30s leeway to expiry checks
GraphQL introspection leaking schema Introspection enabled in prod Set graphql.introspection: false in production config

This is 1 of 9 resources in the Security Engineer Pro toolkit. Get the complete [API Security Framework] with all files, templates, and documentation for $39.

Get the Full Kit →

Or grab the entire Security Engineer Pro bundle (9 products) for $119 — save 30%.

Get the Complete Bundle →


Related Articles

Top comments (0)