Back to Portfolio

Security-Aware Internal API

Internal API designed under hostile-input assumptions: least privilege, scoped authorization, abuse-aware rate limiting, and forensic-grade logging.

Tests

32 passed

Coverage

Adversarial

Abuse Model

Escalating

Logging

Forensic

Why This Exists

Most internal APIs fail because of false trust assumptions:

  • "Internal traffic is safe"
  • "OAuth token = trusted caller"
  • "Validation is for edge services"

This project explicitly rejects those assumptions. Internal callers are treated as potentially compromised, tokens as capabilities (not identities), and malformed input as intentional.

Threat Model

Threat Example
Compromised service Stolen token from logs / memory
Privilege confusion Service A uses token with broader scope than intended
Input abuse Overlong payloads, type confusion, parser edge cases
Automation abuse Retry storms, probing edge conditions
Log poisoning Malicious input attempting log injection

Security Guarantees

Authorization

  • Every protected route enforces an explicit scope requirement
  • No implicit privilege inheritance (e.g., admin:users does not imply read:users)

Validation

  • Request parsing is strict: unknown fields rejected, no silent coercion
  • Field constraints (length/type/enums) enforced at the boundary
  • ASCII-only checks where applicable (blocks homoglyph abuse)

Abuse Handling

  • Rate limits enforced per-token with route-level configuration
  • Malformed requests trigger escalating penalties and eventual blocking
  • Behavior recovery exists (penalties decay over time)

Forensic Logging

  • Security events are structured and sanitized for forensic use
  • Token hash logged (never raw token)
  • Abuse classification: BENIGN, MALFORMED, PROBING, ESCALATION_ATTEMPT

Architecture

Caller → Auth (JWT/scope) → Validation (strict) → Route guard → Rate limiter → Handler
                                   ↘────────────── Security logger (structured) ─────↙

Adversarial Test Corpus

The project includes purpose-built test data to validate security guarantees:

File Contents
benign_requests.json Valid requests for baseline behavior
malformed_requests.json Type confusion, oversized payloads, unicode edge cases
privilege_escalation_attempts.json Missing scope, cross-resource access attempts
rate_limit_abuse.json Retry storms, malformed-input penalty scenarios

What This Signals

  • Assume Breach, Not Perfection: Tests prove that internal ≠ trusted, tokens ≠ identity, and malformed input ≠ accident.
  • Capability-Based Security: Scope model explicitly rejects "admin implies read/write everything."
  • Abuse as First-Class Signal: Escalating penalty logic treats malformed inputs as stronger abuse signal than high volume.
  • Prove Claims with Tests: Adversarial corpus validates resistance to privilege escalation, not just assertions.

Known Limitations

  • In-Process Rate Limiting: Not shared across replicas. Production would use Redis or another shared backend.
  • No Centralized Policy Engine: Authorization is enforced via code-level route dependencies, not OPA.
  • No Anomaly Detection: Rule-based abuse classification only (intentionally out of scope).