Access-control test coverage gaps (non-blocking, from Network Access Control review) #16

Open
opened 2026-08-03 12:02:49 +00:00 by james.oates · 0 comments
Owner

Background

Minor coverage gaps noted during per-task and whole-branch review of the Network Access Control feature. All the relevant logic was traced correct by reviewers and is exercised indirectly; these are "would-be-nice" explicit tests, not known bugs. Bundled into one issue.

Gaps

  1. Malformed CF-Connecting-IP headeraccess::effective_client_ip uses .and_then(|s| s.parse().ok()) then .unwrap_or(peer_ip), so an unparseable header falls back to the real peer (safe). No dedicated test asserts this fallback branch.

  2. Empty inner allow-list (allow_ips: Some(vec![])) — access::access_allowed runs .any() over the empty CIDR list → false → deny (safe direction). No dedicated test for this corner.

  3. API access_rules end-to-end round-tripaccess_rules is proven to round-trip at the DB layer (db.rs tests) and the DTO/serde layer (api.rs tests), but there's no single handler-level test POSTing a body with access_rules through register_service/register_l4_route and reading it back from the DB. Low risk (construction sites are compile-enforced; handler bodies are one-line field threads).

  4. OR-of-rules — first alternatetest_service_access_rules_or_together proves reachable-via-cloudflare (the second rule) and denied-via-lan, but never asserts reachable-via-tailscale (the first rule). A mutation that matched only the last rule in the list would still pass. Add a third request via tailscale asserting != NOT_FOUND to fully cover OR semantics.

Severity

Minor — coverage breadth only. No known incorrect behavior; the pure matching logic is unit-tested and the trust boundary is proven end-to-end over real sockets (test_trust_forwarded_for_honored_only_on_structurally_trusted_binding).

## Background Minor coverage gaps noted during per-task and whole-branch review of the Network Access Control feature. All the relevant logic was traced correct by reviewers and is exercised indirectly; these are "would-be-nice" explicit tests, not known bugs. Bundled into one issue. ## Gaps 1. **Malformed `CF-Connecting-IP` header** — `access::effective_client_ip` uses `.and_then(|s| s.parse().ok())` then `.unwrap_or(peer_ip)`, so an unparseable header falls back to the real peer (safe). No dedicated test asserts this fallback branch. 2. **Empty inner allow-list** (`allow_ips: Some(vec![])`) — `access::access_allowed` runs `.any()` over the empty CIDR list → `false` → deny (safe direction). No dedicated test for this corner. 3. **API `access_rules` end-to-end round-trip** — `access_rules` is proven to round-trip at the DB layer (`db.rs` tests) and the DTO/serde layer (`api.rs` tests), but there's no single handler-level test POSTing a body with `access_rules` through `register_service`/`register_l4_route` and reading it back from the DB. Low risk (construction sites are compile-enforced; handler bodies are one-line field threads). 4. **OR-of-rules — first alternate** — `test_service_access_rules_or_together` proves reachable-via-`cloudflare` (the second rule) and denied-via-`lan`, but never asserts reachable-via-`tailscale` (the first rule). A mutation that matched only the last rule in the list would still pass. Add a third request via `tailscale` asserting `!= NOT_FOUND` to fully cover OR semantics. ## Severity Minor — coverage breadth only. No known incorrect behavior; the pure matching logic is unit-tested and the trust boundary is proven end-to-end over real sockets (`test_trust_forwarded_for_honored_only_on_structurally_trusted_binding`).
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
IsoHex/edge-router#16
No description provided.