Skip to content

[P1] Add bounded distributed admission control, trusted client attribution, and overload behavior #83

Description

@seonghobae

Production gap

Wardnet's production admission boundary still needs a coherent identity hierarchy, bounded local overload protection, and a released shared/global quota authority. Protected main@5829a0f08d78de464dd24393ce5d0f25fba9d126 includes the #159 CI/Fuzz runner/concurrency foundation, but the product slices below remain candidates until their exact deltas reach protected truth.

Current bounded lanes — 2026-09-05

  • PR feat(gateway): bound local limiter cardinality #135 exact fb24394308ccdc835cce344b7e945f5537e99756 owns bounded local limiter cardinality/TTL/capacity behavior and is non-force aligned with current protected main. Exact CI 33908241610 and Fuzz 33908241585 are terminal success; Security 33908241643, SAST 33908241722, and CodeQL 33908241644 remain queued. This is partial exact-head evidence only, not an integrable complete gate.
  • PR refactor(config): centralize runtime bootstrap snapshot #140 exact 054c11aafe835e497d6149efb09f1ccdee9d03bd is the canonical Runtime Configuration foundation. Hostile RED 0f22aaff... proves zero is invalid for positive RATE_LIMIT_WINDOW and MAX_BODY_BYTES bounds; causal GREEN d28a0119... rejects zero while preserving the distinct RATE_LIMIT=0 disable semantic. Current 054c11a... is a linear documentation/rustdoc-only child of that production repair. All current refactor(config): centralize runtime bootstrap snapshot #140 review threads are resolved. Exact CI 33923492873 is queued pre-checkout with job 101186801054, steps=[], runner_id=0; Fuzz 33923492809 is pending and Security 33923492923, SAST 33923493032, CodeQL 33923492956 are queued.
  • PR feat(gateway): trust forwarded client IPs only from trusted proxies #165 now has actual exact head 99581e056645e98e866157443a6732a4bbd729c4 and owns the trusted client-IP attribution slice. The causal trusted-CIDR repair remains 4b96f4e3...; protected-main adoption is 95b9f3d9...; the sole subsequent commit 99581e0..., docs: raise trusted-proxy doc coverage, adds only rustdoc/test documentation and does not change trusted-proxy/network semantics. Current source still rejects noncanonical mapped-CIDR aliases and native/mapped /129 prefixes. All current review threads remain resolved. Exact-current CI 33923347634, Fuzz 33923347839, Security 33923348060, and SAST 33923347715 are terminal cancelled; CodeQL 33923347950 remains pending. These are non-passing Draft/current-head evidence, not GREEN.
  • PR feat(gateway): trust forwarded IPs only from trusted proxies #157 remains a preservation lane for unique trusted-proxy fuzz target/corpus/invariant evidence. It must not merge independently or be closed until that evidence is demonstrably transferred into the coherent successor after refactor(config): centralize runtime bootstrap snapshot #140 becomes protected truth.

No predecessor check/review result transfers after a branch/head movement. #165 still carries a local Runtime Configuration adaptation and therefore remains Draft behind #140 despite being aligned with current protected main. Its cancelled/pending Draft-current-head runs are non-passing evidence, not reason to redispatch by source churn. None of these lanes authorizes a distributed/global quota implementation inside Wardnet if Noema or another canonical released owner supplies it.

Current runner/materialization/scanner behavior is centralized .github#712 evidence, not a product PASS and not permission for no-op redispatch. Fresh post-#159 Wardnet specimens are recorded on .github#712 comment 5547036615. Live solo-maintainer ruleset repair remains .github#772 / owner-plane #1644, with current Wardnet handoff comment 5547038262; self/model approval and routine administrator bypass remain forbidden.

Required architecture

  1. Define the traffic identity hierarchy: authenticated tenant/subject/service first, then verified network identity, with source IP only as a bounded fallback.
  2. Trust Forwarded/X-Forwarded-For only from explicitly configured proxy CIDRs and parse the chain deterministically; otherwise use the peer address. Normalize observed address representations, but keep configured trusted-network authority canonical and fail closed on aliases or malformed/out-of-range prefixes.
  3. Give the local limiter a hard cardinality bound, TTL eviction, memory budget, metrics, and safe behavior under lock contention.
  4. Use Noema or another approved released shared authority for distributed/global quotas; Wardnet retains local emergency admission, circuit breaking, and protocol response behavior.
  5. Support per-tenant, per-route, per-subject/service, and global policies with deterministic precedence, versioning, and rollback.
  6. Return stable 429 responses with bounded Retry-After; distinguish quota exhaustion from dependency overload and policy denial.
  7. Add concurrency limits, bounded request/body/header/time limits, downstream connection-pool bounds, queue limits, and backpressure.
  8. Define fail-open/fail-closed behavior per traffic class when the distributed limiter is unavailable. Management/enforcement writes must fail closed; a deliberately configured data-plane degradation policy may be narrower and must be auditable.
  9. Prevent retry storms through jitter, budgets, circuit breakers, and the durable worker rules in [P0] Add a transactional outbox and idempotent leased workers for external effects #81.
  10. Export saturation, rejection, queue, latency, limiter-authority health, and cardinality metrics without high-cardinality labels.

RED → GREEN verification

  • Distributed multi-replica test proves one global quota instead of one quota per replica.
  • Spoofed forwarded headers do not change identity when the peer is untrusted; trusted multi-proxy chains resolve correctly.
  • Observed IPv4-mapped peer/header addresses normalize consistently, while mapped-CIDR aliases and native/mapped out-of-range prefixes fail closed before they can become trusted configuration authority.
  • High-cardinality IP/subject attack remains within the declared memory bound and evicts deterministically.
  • Window/bucket boundaries, clock movement within supported limits, concurrent increments, policy update, and rollback are deterministic.
  • Distributed-authority timeout/outage follows the documented per-class degradation policy.
  • Backpressure tests prove bounded memory and stable behavior when upstreams, event sinks, or workers stall.
  • Existing Strix attack-detection CI requirement in 서버를 켜고 Strix가 포트를 향해 각종 공격을 할 때 감지해내야 함 (CI) #11 becomes an end-to-end acceptance lane rather than a separate hand-written duplicate.

Acceptance criteria

  • No attacker-controlled cardinality can grow process memory without a configured bound.
  • Replica count does not multiply global quotas.
  • Client identity cannot be spoofed through untrusted proxy headers or malformed network-authority syntax.
  • Every overload path has a stable status/reason, metric, and audit/trace context.
  • Required management paths fail closed when admission authority is unavailable.
  • Soak/load/attack tests publish reproducible capacity and degradation evidence.
  • One exact protected candidate has terminal current repository/security/coverage/package/SBOM/provenance/review/governance evidence before release.

Boundaries

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionpriority: highHigh-priority or P1 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions