System: TrackIt Project-Aware Load Balancer & Reverse Proxy
Evaluator: Senior Cloud Infrastructure, Distributed Systems & Security Engineering
Status: Comprehensive Pre-Production Assessment
Target Environment: Multi-tenant Public Cloud (Google Cloud Run / Kubernetes / AWS ECS)
Date: October 2026
This audit evaluates the production readiness of the TrackIt Load Balancer codebase. TrackIt is designed as a project-aware reverse proxy and dynamic load balancer built on Next.js 15 App Router, TypeScript, Prisma 7, and PostgreSQL (Supabase).
While the core reverse proxy routing logic, server selection strategies, and database Row Level Security (RLS) hardening establish a strong foundational skeleton, the system in its current state contains severe vulnerabilities and architectural bottlenecks that make it unsafe for production deployment.
| Category | Score | Primary Reason |
|---|---|---|
| Security | 3 / 10 | Zero authentication on Admin API / Server Actions; SSRF via backend URL registration; client IP spoofing; missing security headers. |
| Scalability | 4 / 10 | Synchronous PostgreSQL writes on every proxy request; in-memory body buffering (arrayBuffer) risking OOM crashes; process-local state prevents horizontal scaling. |
| Reliability | 4 / 10 | Blind retry of non-idempotent HTTP methods (POST, PATCH, DELETE) risking double mutations/charges; retry storms under failure. |
| Session Architecture | 2 / 10 | IP_HASH silently falls back to ROUND_ROBIN; no distributed sticky session mechanism; stateful sessions break across container replicas. |
| Rate Limiting | 0 / 10 | Completely absent. Dependencies like express-rate-limit exist in package.json but are never imported or executed in Next.js routes. |
| Observability | 4 / 10 | High-overhead database logging; lack of Prometheus / OpenTelemetry metrics; no distributed tracing across upstream hops. |
| Deployment | 4 / 10 | Docker container runs as root; CMD ["npm", "start"] breaks Unix SIGTERM signal propagation; hardcoded localhost:3000 Server Action origins. |
| OVERALL | 3.0 / 10 | NOT PRODUCTION READY. Critical P0 vulnerabilities must be resolved before routing real client traffic. |
┌─────────────────────────────────┐
│ External Client │
└────────────────┬────────────────┘
│
▼
HTTP/HTTPS Request to /api/...
│
▼
┌──────────────────────────────────────────────┐
│ middleware.ts │
│ • Sets x-request-id │
│ • NO Rate Limiting │
│ • NO Authentication │
│ • NO Security Headers / CORS │
└──────────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ app/api/[...path]/route.ts │
│ • ensureFreshCacheForProxy() (DB sync /10s) │
│ • resolveProject(firstSegment) │
│ • Buffers request.arrayBuffer() in RAM │
└──────────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ services/cache/CacheService │
│ • In-Memory Map Lookups (Process-Local) │
│ • Active Connection Tracking │
│ • NO Redis (Isolated per container replica) │
└──────────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ services/load-balancer/LoadBalancer │
│ └── RetryService.executeWithRetry() │
│ ├── ServerSelector (Strategy) │
│ └── RequestForwarder (Axios) │
└──────────────┬───────────────────────────────┘
│
┌──────────────────────┴──────────────────────┐
│ │
▼ (Forward Request) ▼ (On Error / Success)
┌─────────────────────┐ ┌─────────────────────┐
│ Upstream Backend │ │ PostgreSQL Database │
│ (Target Server) │ │ (Supabase + RLS) │
└─────────────────────┘ │ │
│ • Synchronous write │
│ to request_logs │
│ per request! │
└─────────────────────┘
- Edge Entry (
middleware.ts:L4-L16): The incoming request hits Next.js middleware. It generates a UUIDx-request-idand passes through. No rate-limiting, IP verification, or security checks occur. - Proxy Handler (
app/api/[...path]/route.ts:L42-L147):- Executes
ensureFreshCacheForProxy(). If10shave elapsed since the last refresh, it triggers an async database pull for all projects, servers, and settings. - Evaluates path segment 0 as the project slug. If missing or disabled, returns
404or403. - If path is root
/api/{projectSlug}, triggers synchronous active network health checks against every enabled server in the pool (Promise.all(servers.map(checkServer))). - If downstream path exists, calls
await request.arrayBuffer(), buffering the entire request body into the Node.js process heap.
- Executes
- Routing Decision (
services/load-balancer/ServerSelector.ts:L9-L30):- Queries
CacheServicein RAM. - Evaluates the project's configured algorithm. Note: If
IP_HASHis configured, line 22 silently falls back toRoundRobinStrategy.
- Queries
- Forwarding & Retries (
services/load-balancer/RetryService.ts:L36-L153):- Dispatches via
RequestForwarderusingaxios. - If upstream throws a connection error or returns
502,503, or504,RetryServicecatches the exception and immediately attempts the next backend server, regardless of whether the HTTP method isPOST,PUT,PATCH, orDELETE.
- Dispatches via
- Synchronous Persistence (
services/load-balancer/RetryService.ts:L155-L170):- Invokes
loggingService.createLog()which performs a direct PostgreSQLINSERTintopublic.request_logson every single request.
- Invokes
- Location:
app/api/admin/projects/route.ts#L7-L56,actions/server.actions.ts#L33-L340,actions/project.actions.ts#L1-L100,actions/settings.actions.ts#L1-L80 - Problem: There is zero authentication, authorization, API key, or session validation anywhere in the administration endpoints or Next.js Server Actions.
- Why It Is Dangerous: Any anonymous user on the public internet can send HTTP requests directly to:
GET /api/admin/projectsto enumerate all backend projects.POST /api/admin/projectsto register arbitrary projects.- Server Action POSTs to
createServerAction,deleteServerAction,updateSettingsAction.
- Attack Scenario: An attacker issues
POSTrequests to create backend servers pointing to attacker-controlled command-and-control servers, or issuesdeleteServerActionto wipe every backend server in the system, causing total denial of service. - Recommended Fix: Implement robust authentication (e.g., Bearer JWT, session tokens, or API keys validated via middleware) enforcing role-based access control (RBAC) on all
/api/admin/*endpoints and Server Actions before deployment.
- Location:
services/load-balancer/RetryService.ts#L36-L132 - Problem:
RetryService.executeWithRetryindiscriminately retries requests on upstream failures or timeouts without checking HTTP idempotency. - Why It Is Dangerous: If a client sends a
POST /api/store/checkoutorPOST /api/wallet/transfer, and the upstream server receives the request, charges the user, but experiences a socket timeout or returns a transient502before the response completes: the load balancer automatically catches the failure and dispatches the identicalPOSTpayload to a second backend server. - Attack/Failure Scenario: A transient network blip on upstream nodes causes customers to be billed 2 to 4 times for the same transaction, or creates duplicate orders and conflicting database mutations.
- Recommended Fix: Restrict automatic retries strictly to idempotent HTTP methods (
GET,HEAD,OPTIONS,PUT,DELETE). Non-idempotent methods (POST,PATCH) must NEVER be retried automatically unless a verified upstreamIdempotency-Keyheader and consensus mechanism is explicitly enforced.
- Location:
package.json#L43-L44,middleware.ts#L4-L16,app/api/[...path]/route.ts - Problem:
package.jsondeclaresexpress-rate-limit, but it is an Express-specific package that is never imported or executed in the Next.js runtime. No rate limiting exists anywhere in the codebase. - Why It Is Dangerous: The application has no defense against API abuse, credential brute-forcing, scraping, or high-volume application-layer floods.
- Attack Scenario: A single script sending 1,000 requests/second from one laptop will overwhelm backend microservices, consume all available database connections, and trigger upstream service outages.
- Recommended Fix: Implement distributed sliding-window rate limiting in
middleware.tsusing Redis (e.g.,@upstash/ratelimitor Redis atomic Lua scripts) tracking both client IP and authenticated tenant tokens.
- Location:
app/api/[...path]/route.ts#L125-L135,services/load-balancer/RequestForwarder.ts#L38-L49 - Problem: For all non-GET/HEAD requests, the proxy executes:
It buffers the complete request payload into Node.js process heap memory with no
const buf = await request.arrayBuffer(); if (buf.byteLength > 0) reqBody = buf;
Content-Lengthvalidation or maximum buffer cap. - Why It Is Dangerous: Node.js v8/heap allocations are finite. Large payloads instantly exhaust RAM.
- Attack Scenario: An attacker sends 10 concurrent HTTP
POSTrequests with 300 MB payloads. The load balancer allocates ~3 GB in RAM, immediately triggeringJavaScript heap out of memoryand crashing the container. - Recommended Fix:
- Enforce a strict
Content-Lengthcap (e.g., 10 MB default) at the middleware layer. - Implement native Node.js / Web Streams (
request.bodystreamed directly to upstream axios/fetch) instead of buffering payloads entirely into memory.
- Enforce a strict
- Location:
lib/validations.ts#L9-L15(createServerSchema) - Problem: The URL validation schema only enforces that URLs begin with
http://orhttps://:It does not block private IP ranges (RFC 1918), loopback addresses (url: z.string().url().refine((u) => u.startsWith('http://') || u.startsWith('https://'))
127.0.0.1,localhost), link-local addresses (169.254.0.0/16), or Cloud Provider Metadata URLs. - Why It Is Dangerous: Combined with CRITICAL-01 (unauthenticated APIs), any user can register an internal infrastructure endpoint as a backend server.
- Attack Scenario: An attacker registers
http://metadata.google.internal/computeMetadata/v1/(on Google Cloud Run) orhttp://169.254.169.254/latest/meta-data/(on AWS). When TrackIt executes background health probes or proxies traffic, it captures and returns internal cloud environment credentials, IAM tokens, and private network services. - Recommended Fix: Implement strict IP resolution and validation: resolve DNS hostnames before registration/forwarding and reject any IP matching
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16,::1, or cloud metadata domains.
- Location:
services/load-balancer/RetryService.ts#L155-L170,services/logging/LoggingService.ts#L9-L27 - Problem: Every proxy request synchronously executes
loggingRepository.create(), writing an entry topublic.request_logsin PostgreSQL. - Why It Is Dangerous: PostgreSQL is an OLTP database not designed for high-frequency time-series logging. At 1,000–5,000 RPS, this creates 1,000–5,000 direct database INSERT operations per second.
- Failure Scenario: The database connection pool is immediately exhausted; write locks on
request_logsdegrade overall database performance; transaction latency spikes, causing the load balancer itself to crawl and time out. - Recommended Fix: Offload access logging to an asynchronous batching queue (e.g., in-memory ring buffer with bulk flush, Redis Stream, Kafka, or external log collectors like Datadog, Vector, or CloudWatch).
- Location:
Dockerfile#L1-L23 - Problem:
- The container runs as the
rootuser (USER nodeis omitted). - The entrypoint uses
CMD ["npm", "start"].
- The container runs as the
- Why It Is Dangerous: Running as
rootgrants full container privilege in the event of an RCE. Running vianpm startmeansnpmoccupies PID 1;npmdoes not forward UnixSIGTERMsignals to the child Node.js process. - Failure Scenario: During autoscaling or rolling deployments, the container orchestrator sends
SIGTERM. The application fails to receive it, cannot drain active connections gracefully, and is abruptly killed withSIGKILLafter 30 seconds, dropping all active user requests. - Recommended Fix: Use a multi-stage Docker build, set
USER node, and execute the Node process directly:CMD ["node", "server.js"](using Next.js standalone output).
- Location:
next.config.ts#L5-L7 - Problem:
serverActions: { allowedOrigins: ['localhost:3000'] }
- Why It Is Dangerous: When deployed to a production domain (e.g.,
lb.production.comor Google Cloud Run), Next.js CSRF validation for Server Actions strictly validates the incomingOriginagainstallowedOrigins. - Failure Scenario: In production, every single dashboard action (creating servers, toggling health, modifying settings) will fail with HTTP
403 Forbidden: Invalid Server Action request. - Recommended Fix: Make
allowedOriginsdynamically driven by environment variables (e.g.,process.env.APP_DOMAIN).
- Location:
services/load-balancer/RequestForwarder.ts#L30-L36 - Problem: The proxy iterates incoming headers and only omits
host. Untrusted clientx-forwarded-forand hop-by-hop headers (connection,keep-alive,transfer-encoding) are forwarded directly to upstream backends. - Why It Is Dangerous: Attackers can spoof their client IP address by setting
X-Forwarded-For: 127.0.0.1or bypass upstream IP whitelists. Upstream servers cannot trust client IP headers. - Recommended Fix: Sanitize proxy headers: strip incoming client
X-Forwarded-For, compute the true remote socket IP, append it cleanly toX-Forwarded-For, and explicitly appendX-Forwarded-ProtoandX-Forwarded-Host. Strip all RFC 2616 hop-by-hop headers.
- Location:
services/load-balancer/ServerSelector.ts#L21-L23 - Problem:
The database schema supports
// Fallback for IP_HASH to Round Robin (or we can use it directly) [Algorithm.IP_HASH]: roundRobin,
Algorithm.IP_HASH, but the algorithm strategy is not implemented. - Why It Is Dangerous: Administrators configuring a project for
IP_HASHexpect deterministic sticky routing. Instead, traffic is silently distributed round-robin. - Failure Scenario: Upstream stateful web applications relying on IP-based session persistence suffer broken sessions and repeated authentication logouts.
- Recommended Fix: Implement a concrete
IPHashStrategyhashing client IP against the active server ring, or removeIP_HASHfrom the UI/enums until implemented.
- Location:
app/api/[...path]/route.ts#L87-L119 - Problem: When a user queries
GET /api/{projectSlug}, the handler triggers:const healthResults = await Promise.all( enabledServers.map((server) => healthScheduler.checkServer(server)) );
- Why It Is Dangerous: The endpoint does not return cached health status; it actively probes all servers synchronously over the network on every HTTP GET.
- Attack Scenario: An attacker floods
GET /api/{projectSlug}at 500 RPS, triggering 500 network health probes per second to every backend server, effectively using the load balancer as an internal DDoS amplifier. - Recommended Fix:
GET /api/{projectSlug}must read health status exclusively fromCacheServicein RAM. Only internal background workers should execute active network probes.
- Location:
middleware.ts#L4-L16,next.config.ts - Problem: No security headers are injected into HTTP responses.
- Missing Headers:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preloadX-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-originContent-Security-Policy
- Recommended Fix: Configure standard security headers inside
next.config.tsormiddleware.ts.
- Location:
services/cache/CacheService.ts#L22-L27 - Problem: Active connection counts (
activeRequests), round-robin counters, and server failure counts are stored in process-local JavaScriptMaps. - Why It Matters: When scaled to multiple container instances, Instance A knows nothing about the connections on Instance B.
- Impact:
LEAST_CONNECTIONSonly balances connections within a single container. Failure counts do not aggregate across instances, delaying circuit breaking. - Recommended Fix: Back runtime connection tracking, failure metrics, and distributed state with Redis.
- Location:
app/api/cron/health/route.ts#L13-L15 - Problem:
If
if (cronSecret && authHeader !== `Bearer ${cronSecret}`) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); }
CRON_SECRETis undefined in.env, the conditional evaluates tofalse, allowing anyone on the internet to invoke/api/cron/healthwithout authorization. - Recommended Fix: Fail closed: if
!cronSecret || authHeader !== ..., immediately reject with401 Unauthorized.
- Location:
services/load-balancer/RetryService.ts#L94-L131 - Problem: When a backend fails, the loop immediately selects the next server with
0msdelay. - Why It Matters: If backends are struggling under high load, immediate retries exacerbate cascading failures (retry storms).
- Recommended Fix: Implement randomized exponential backoff with full jitter (e.g., 50ms, 150ms, 300ms) between retry attempts.
- Location:
Dockerfile#L1-L17 - Problem: The Dockerfile copies all files and runs
npm installwithout multi-stage separation. - Why It Matters: The resulting image is over 1.2 GB, contains source code, TypeScript tools, and unpruned dev dependencies, increasing attack surface and deployment cold-start latency.
- Recommended Fix: Use Next.js
output: 'standalone'with a multi-stage Dockerfile (node:22-alpinebuilder -> slim runner).
- Prune Dead Express Dependencies: Remove
express,express-rate-limit,helmet,cors,morgan,multer,bcryptfrompackage.jsonto eliminate dependency confusion and audit alerts. - Add Docker HEALTHCHECK: Add a native Docker
HEALTHCHECKdirective hittinghttp://localhost:3000/api/health. - HTTP/2 & Keep-Alive Tuning: Configure custom
http.Agentandhttps.AgentinRequestForwarderwithkeepAlive: trueandmaxSockets: 500to eliminate TCP/TLS handshake latency on repeated upstream calls. - Prisma Connection Pooling Documentation: Explicitly document transaction pooler vs direct connection port configurations in
.env.example.
| Question | Assessment & Reality |
|---|---|
| Where is rate limiting currently applied? | NOWHERE. There is zero rate limiting in the code. |
| Does traffic reach the backend before rejection? | Yes. Every single incoming request penetrates directly through to downstream backends. |
| Is it distributed? | No. There is no distributed counter or synchronization. |
| Can multiple servers bypass limits? | Yes. Attackers have infinite throughput capacity up to server saturation. |
| Is Redis involved? | No. Redis is not installed, connected, or configured. |
| Is WAF / Cloud DDoS involved? | Not in this codebase. It relies entirely on external infrastructure (e.g., Cloudflare/Cloud Armor). |
Layer 1: Edge WAF (Cloudflare / Cloud Armor)
├── Global Rate Limit: 10,000 req / minute / IP
└── DDoS L7 Mitigation / Managed Challenge
Layer 2: Load Balancer Middleware (Redis Token Bucket)
├── Public Proxy Routes: 1,000 req / minute / Project Token
├── Admin API Routes: 60 req / minute / Admin IP
└── Cron Health Trigger: 10 req / minute
Layer 3: Backend Microservices (Local Rate Limiters)
| Question | Assessment & Reality |
|---|---|
| Are sessions stateful or stateless? | The load balancer itself is stateless. However, it manages stateful downstream routing. |
| Can any backend serve any user? | Depends on downstream architecture. If upstream microservices rely on in-memory sessions, TrackIt will break them because IP_HASH is not implemented. |
| Is Redis required? | Yes. For multi-instance load balancer deployments, Redis is required for distributed active connection tracking, rate limits, and health status consensus. |
| Is sticky session required? | If downstream backends use in-memory sessions, sticky sessions (IP_HASH or cookie-based routing) are strictly required. If downstreams use JWT or Redis sessions, sticky routing is optional. |
| Can sessions leak between users? | In the load balancer proxy itself, No. Request contexts are scoped per request. However, because Host headers are stripped and client IPs are not sanitized, downstreams may misidentify client origins. |
[CRITICAL] Unauthenticated Admin API & Server Actions CVE-Equivalent: High
[CRITICAL] Blind Non-Idempotent Request Retries (POST) Financial / Data Duplication
[CRITICAL] Absent Rate Limiting CWE-770 (Uncontrolled Resource Allocation)
[CRITICAL] Uncapped In-Memory ArrayBuffer Buffering CWE-400 (Denial of Service via OOM)
[CRITICAL] Server-Side Request Forgery (SSRF) in URLs CWE-918 (Server-Side Request Forgery)
[HIGH] Synchronous DB Logging on Hot Proxy Path Database Exhaustion & Latency Spike
[HIGH] Container Root Execution & Broken SIGTERM CWE-250 (Execution with Unnecessary Privileges)
[HIGH] Server Actions Broken in Production Domain CSRF Origin Rejection
[HIGH] Client IP Spoofing via Unsanitized Headers CWE-345 (Insufficient Verification of Authenticity)
[HIGH] Phantom IP Hash Algorithm Algorithm Mismatch / Broken Affinity
[HIGH] Synchronous Health Check Flooding Amplification Vector
| Concurrent Users | Traffic (RPS) | System Behavior Under Current Code |
|---|---|---|
| 1,000 | ~50 - 100 RPS | Functional. In-memory cache handles lookups smoothly; database logging handles ~100 writes/sec without failing. |
| 10,000 | ~500 - 1,000 RPS | Degraded / High Latency. PostgreSQL request_logs experiences lock contention. Every 10 seconds, refreshAll() causes cache stampedes on the DB. |
| 50,000 | ~2,500 - 5,000 RPS | Severe Failure. Database connection pool saturates on logging; Node.js memory spikes from body buffering; requests time out and trigger retry storms. |
| 100,000 | ~10,000+ RPS | Total Crash. Container Out-Of-Memory crashes; database becomes completely unresponsive; cascading failovers across all backend nodes. |
- PostgreSQL Write Throughput (
request_logs): Saturation at ~800–1,200 RPS. - Process Heap Memory (
arrayBuffer): OOM crash during concurrent POST uploads. - Connection Pooling: Node.js and pgBouncer socket exhaustion under cascading retries.
Internet
│
▼
┌───────────────────────────────┐
│ Cloudflare / AWS CloudFront │
│ • Managed WAF & L7 DDoS │
│ • Global TLS Termination │
│ • Edge Static Asset Caching │
└───────────────┬───────────────┘
│
▼
┌───────────────────────────────┐
│ TrackIt Load Balancers │
│ (Next.js Standalone) │
│ • Autoscaled Cloud Run / K8s │
│ • Non-root container │
│ • Redis Token-Bucket Limiter │
│ • Streaming Request Proxy │
└───────┬───────────────┬───────┘
│ │
┌────────────────┴─────┐ └─────────────────────┐
▼ ▼ ▼
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ Redis Cluster │ │ Upstream Micro- │ │ Asynchronous Log │
│ • Rate Limiting │ │ service Pool │ │ Queue (Redis/SQS) │
│ • Shared Metrics │ │ (Private VPC Only) │ └──────────┬─────────┘
│ • Sticky Sessions │ └────────────────────┘ │
└────────────────────┘ ▼
┌────────────────────┐
│ PostgreSQL DB │
│ (Configuration & │
│ Aggregated Stats) │
└────────────────────┘
- Admin Authentication: Enforce strict session/API-key authentication on
/api/admin/*and all Server Actions. - Disable Non-Idempotent Retries: Modify
RetryService.tsto strictly retry idempotent methods (GET,HEAD,OPTIONS,PUT,DELETE). Never retryPOSTorPATCH. - Streaming Proxying & Payload Capping: Enforce maximum body size limits (
10MB) in middleware and stream request bodies instead of buffering entirearrayBuffers. - SSRF Validation: Validate server URLs on creation: reject loopback, link-local, private RFC 1918 addresses, and cloud metadata hostnames.
- Next.js Server Action Origins: Update
next.config.tsto read production domain from environment variables. - Fix Cron Authorization: Ensure
/api/cron/healthfails closed whenCRON_SECRETis unset.
- Asynchronous Logging: Decouple
request_logsfrom the hot proxy path. Buffer logs in memory or push to a background queue. - Distributed Rate Limiting: Connect Redis in
middleware.tsto enforce IP and tenant rate limits. - Client IP & Header Sanitization: Strip hop-by-hop headers and sanitize
X-Forwarded-Forusing real socket IPs. - Container Hardening: Update
Dockerfileto multi-stage build, non-root user (USER node), and standalone output. - Implement Concrete IP Hash: Implement real consistent hashing on client IP or remove the enum option.
- Retry Exponential Backoff: Add randomized exponential backoff and jitter to retry attempts.
- Cache Stored Health: Stop active network probes on
GET /api/{projectSlug}; serve exclusively from cache. - HTTP Keep-Alive Connection Pooling: Configure keep-alive HTTP/HTTPS agents in
RequestForwarderwith connection reuse. - Security Headers: Add HSTS, CSP, X-Frame-Options, and Referrer-Policy headers.
- Prune Dead Dependencies: Clean up unused Express packages in
package.json. - OpenTelemetry & Prometheus Export: Implement standardized telemetry metrics endpoints (
/metrics). - Circuit Breaker State Sharing: Synchronize circuit breaker open/half-open states via Redis.
- DNS configured with DNSSEC enabled.
- Cloud WAF (Cloudflare / AWS WAF / Google Cloud Armor) active with rate limits and DDoS mitigation.
- TLS 1.3 enforced; TLS 1.0 and 1.1 disabled.
- HTTPS redirect enforced globally.
- No public unauthenticated access to admin endpoints or Server Actions.
-
allowedOriginsconfigured with production hostnames. - Maximum request body size enforced (e.g., 10 MB).
- No non-idempotent HTTP request retries (
POST/PATCH). - Retries bounded with exponential backoff and jitter.
- Header sanitization active:
Hostreplaced, hop-by-hop headers stripped,X-Forwarded-*sanitized. - SSRF blocklist enforced on backend URLs.
- Container runs as non-root user (
USER node). - Container multi-stage build configured with
output: 'standalone'. - Process started via
node server.js(notnpm start) for cleanSIGTERMconnection draining. - Docker
HEALTHCHECKdefined and verified. - CPU and memory resource limits specified in orchestrator manifest.
- Row Level Security (RLS) enabled on all public PostgreSQL tables (
npm run db:secure). -
anonandauthenticatedroles denied direct PostgREST access. - Access logs decoupled from synchronous OLTP database writes.
- Connection pooler (pgBouncer / Supabase pooler) configured with max connection limits.
- Automated database backups with Point-In-Time-Recovery (PITR) enabled and tested.
- Structured JSON logging without sensitive headers or request body credentials.
- Health probe
/api/healthwired to uptime monitors with PagerDuty / Slack alerts. - P95 / P99 latency, 5xx error rate, and container memory alerts configured.
- Disaster recovery playbook verified for upstream cluster failure.
Report prepared and certified by Senior Cloud Infrastructure & Security Engineering.