Chrome 152 introduced Connection Allowlists as an origin-trial mechanism: a page can restrict the endpoints its document and workers may contact. In a proxy-backed test, that adds a failure boundary before the gateway.
If a request is missing from proxy logs, do not immediately rotate the exit. First determine whether the browser allowed the request to leave the page context.
Store one normalized attempt
Keep evidence useful but non-secret:
function normalizeAttempt(input) {
return {
capturedAt: new Date(input.capturedAt).toISOString(),
browserVersion: input.browserVersion,
requestNumber: input.requestNumber,
initiatorType: input.initiatorType, // document | worker | other
policyOutcome: input.policyOutcome, // allowed | blocked | unknown
proxyObserved: Boolean(input.proxyObserved),
gatewayLabel: input.gatewayLabel,
requestedRegion: input.requestedRegion,
exitCohort: input.exitCohort,
dnsOwner: input.dnsOwner, // local | browser | gateway | socks-remote
addressFamily: input.addressFamily, // ipv4 | ipv6
status: input.status,
contentCheck: input.contentCheck,
result: input.result, // pass | fail | inconclusive
};
}
Do not include Authorization, Proxy-Authorization, cookies, raw session tokens, or full response bodies.
Classify by the first boundary that produced evidence
function classify(attempt) {
if (attempt.policyOutcome === "blocked" && !attempt.proxyObserved) {
return "browser-policy";
}
if (attempt.proxyObserved && attempt.status === 407) {
return "proxy-authentication";
}
if (attempt.proxyObserved && [403, 429].includes(attempt.status)) {
return "destination-policy";
}
if (attempt.status >= 200 && attempt.status < 300 && !attempt.contentCheck) {
return "application-contract";
}
if (!attempt.proxyObserved && attempt.policyOutcome === "allowed") {
return "dns-route-or-gateway";
}
return "inconclusive";
}
This classifier is deliberately conservative. It does not infer that a proxy is healthy from a browser policy result, and it does not infer usable data from a 200 status.
Run a seven-case matrix
| Case | Variable | Expected evidence |
|---|---|---|
| Baseline | healthy route | policy allowed, proxy observed, content valid |
| Browser negative | controlled host omitted | policy blocked, proxy not observed |
| Proxy negative | invalid test credential | explicit 407 at gateway |
| Route negative | gateway unavailable | fail closed, no direct fallback |
| Redirect | approved chain | every hop permitted and observed |
| Worker | worker fetch | initiator and scope match the design |
| Dual stack | IPv4 then IPv6 | DNS and route evidence agree for each family |
Run at concurrency one and change one variable at a time. A shared timeout without layer evidence is not diagnostic.
Keep direct fallback impossible
A proxy outage must not cause the client to use the device's normal connection. Test that failure deliberately in an authorized environment. Record the gateway and exit cohort using non-secret labels, then check IPv4 and IPv6 independently.
DNS is another independent field. A hostname can be permitted by browser policy but resolved by a different component than expected. Record whether the resolver is local, browser-managed, gateway-side, or SOCKS remote DNS.
Minimum release gate
- Pin the browser version and origin-trial state.
- Review required hosts; avoid unrestricted wildcards.
- Test redirects, workers, APIs, assets, and WebSockets where relevant.
- Confirm an omitted test host never reaches the proxy.
- Verify gateway, protocol, region, and exit cohort.
- Fail closed when the proxy is unavailable.
- Separate DNS evidence from route evidence.
- Validate content, locale, and freshness after transport success.
- Mark uncertain cases
inconclusiveinstead of guessing.
Connection policy is not authorization to collect data. Test only systems you are allowed to use, respect destination limits and denial signals, and never widen policies or rotate exits to evade a block.
Disclosure: I work with 98IP. We publish proxy engineering material for lawful, authorized workflows. https://en.98ip.com/?k=dev
Top comments (0)