in reviewhumanPR #145Communication
Nandatown: composable middleware, distributed HTTP hardening, skills API security, and local deploy tooling
| Tier | Files (review first) |
Description
The pitch.
> **Supersedes closed draft [#140](https://github.com/projnanda/nandatown/pull/140).** Same head `c32e4c0` (Apache-2.0). CI for this commit lineage was proven green on private `abhishekeb211/nanda` (all lint/typecheck/test/security/dashboard jobs). Fork PRs may still need maintainer approval to run workflows on this repo. ## Review guide | Tier | Files (review first) | |------|----------------------| | **Core** | `middleware.py`, `middleware_builtins/*`, `http_config.py`, `network_runner.py`, `worker.py`, `plugin_wiring.py`, `plugin_rpc.py`, `runner.py`, `skills-api-guard.ts`, `url-safety.ts`, `route.ts` | | **Supporting** | `docs/security-audit.md`, `docs/distributed.md`, `deploy-local.ps1`, CI workflow, scenario trace JSONLs | ## Review responses | Feedback | Fix | |----------|-----| | **Collaborator: merge conflicts** | Merged `main` (`eac3375`); resolved `skills/page.tsx`, `communication.md`, `payments.md` | | **Collaborator: whitespace noise** | Removed interleaved blank-line churn across 113 files; added `.editorconfig` (`end_of_line = lf`); `ruff format` on touched paths (`0441ed1`) | | **Collaborator: PR size** | Review guide above ΓÇö core ~15 files vs supporting | | **Copilot: metadata_filter** | Restored in `InMemoryRegistry.lookup` / `_matches` + test (`2f9b6d0`) | | **Copilot: RPC 413** | Early return before routing oversized bodies + test | | **Copilot: plugin_wiring** | Lazy `nest_plugins_reference` import | | **Copilot: deploy-local.ps1** | Merge `.env.local` keys; only update `DATABASE_URL` | ## Motivation A July 2026 red-team audit of Nanda Town found three weak clusters in an otherwise strong Tier-1 simulation engine: 1. **Distributed HTTP surface** ΓÇö worker bridges accepted any caller when `NEST_HTTP_SHARED_SECRET` was unset; health checks omitted auth headers when a secret was configured. 2. **Next.js `/skills` API** ΓÇö public `POST` with no rate or body limits; server-side reachability probe vulnerable to SSRF. 3. **Simulator regressions** ΓÇö `partition_heal_at_tick` not forwarded to worker simulators; JwtAuth not bound to the virtual clock; `auth_scope` silently passed when no auth plugin was present. This PR is **hackathon platform infrastructure** (middleware seam, distributed runner hardening, dashboard deploy tooling, and documentation). Full findings register: [`docs/security-audit.md`](docs/security-audit.md). ## What changed ### Middleware layer Composable inbound/outbound message hooks resolved from built-ins or `nest.middleware` entry points: | Name | Purpose | |------|---------| | `resilience` | Isolate `on_message` failures | | `observability` | Structured per-message logging | | `auth_scope` | Enforce bearer tokens; **denies** when auth plugin is missing | | `latency` | Deterministic per-hop delay via virtual clock | Key files: [`packages/nest-core/nest_core/sim/middleware.py`](packages/nest-core/nest_core/sim/middleware.py), [`packages/nest-core/nest_core/sim/middleware_builtins/`](packages/nest-core/nest_core/sim/middleware_builtins/), [`packages/nest-core/nest_core/middleware_registry.py`](packages/nest-core/nest_core/middleware_registry.py). ### Distributed HTTP hardening (P0/P1) - `require_http_shared_secret()` ΓÇö fails fast when `workers > 1` or `worker_bind` is not localhost - `hmac.compare_digest` in `http_auth_valid` (timing-safe secret comparison) - `check_health()` and `RoutedTransport` send `http_auth_headers()` when secret is set - Worker stack: [`network_runner.py`](packages/nest-core/nest_core/sim/network_runner.py), [`http_config.py`](packages/nest-core/nest_core/sim/http_config.py), [`worker.py`](packages/nest-core/nest_core/sim/worker.py), [`partition.py`](packages/nest-core/nest_core/sim/partition.py), [`trace_merge.py`](packages/nest-core/nest_core/sim/trace_merge.py) ### Worker simulator fixes - `partition_heal_at_tick` forwarded to each worker `Simulator` (partition scenarios heal in distributed r …
Try it
Open PR on GitHubView diffCheckout locally
git fetch origin pull/145/head:pr-145
git checkout pr-145