Network

PAC Request Policy: Browser-Level Request Functions

How BotBrowser PAC Request Policy extends standard PAC routing with trusted request callbacks, routing actions, capture actions, and browser-level network policy.

Documentation

Prefer the maintained product doc?

This article has a matching page in the docs center. Use the docs for the canonical setup flow, current flags, and long-term reference.

Introduction

Proxy Auto-Config files have been part of browser networking for a long time. A PAC file lets the browser decide, for each request, whether it should use a proxy or connect directly. The decision happens inside the browser network layer before the request leaves the browser, which makes PAC different from page scripts, framework hooks, or application-level request handlers.

That older browser feature is still useful because modern browser workflows have become more complicated. Teams no longer run a single browser on one machine with one proxy. They run profile-backed sessions across Windows, macOS, Linux, headless servers, proxy pools, regional routes, long navigation chains, media-heavy pages, and automation frameworks. They need routing decisions to stay aligned with the browser identity instead of being scattered across helper scripts.

BotBrowser's PAC Request Policy support extends that operating model for approved enterprise workflows. It keeps request-aware policy close to the browser's managed network stack while preserving normal PAC routing behavior. The result is a cleaner way to express request policy without forcing every team to move routing decisions into page code or framework-specific request handlers.

This post covers the public PAC function model, supported request actions, deployment sources, and the product cases where browser-level request policy is cleaner than framework interception. For the short reference page, use the PAC Request Policy docs and the CLI flags reference.

Why PAC Still Matters

PAC is simple on the surface: the browser asks a function which route to use for a URL. That simplicity is the point. Routing belongs near the browser's network stack, not after a page framework has already started handling requests.

A proxy decision often depends on more than the target hostname. Some requests belong on a residential or mobile route. Some should use a regional proxy. Some internal services should stay on a local route. Some static assets can use a different path from authenticated navigation. Some enterprise workflows need to keep a small number of request classes under stricter policy while leaving the rest of the page on ordinary browser behavior.

Putting those decisions in application code can work for small scripts, but it becomes harder to maintain as the workflow grows. A Playwright route handler, a Puppeteer interception hook, a side proxy, a Node service, and a PAC file all become separate places where request behavior can change. When a support case appears, the first question becomes: which layer actually made the routing decision?

PAC reduces that ambiguity. The browser owns the routing question. The rule stays with the browser launch configuration. The same policy follows navigation requests, subresources, redirects, and browser-managed fetches more naturally than page-only code.

For privacy-focused browser work, that matters because identity is not only JavaScript. Network path, route selection, profile locale, timezone, browser-family behavior, and page runtime signals all need to agree. A profile can look coherent inside the page and still be weakened by inconsistent routing behavior. PAC keeps the routing side of that model explicit.

The Problem With Request Logic Outside The Browser

Automation frameworks give teams useful request controls. They are convenient for tests, mocks, and simple data collection tasks. They are not always the best place to own enterprise routing policy.

Page-level request handlers are usually scoped to one page or one context. They may require a framework-specific setup step. They often depend on enabling a request handling mode before navigation begins. They can be harder to reason about when service workers, redirects, preloads, popups, or browser-managed requests enter the workflow.

Side proxy services have a different tradeoff. They centralize network logic outside the browser, but they also separate the policy from the profile that defines browser identity. The proxy service sees network traffic, but it may not know which profile, context, or browser-family identity is supposed to be active. Teams can pass extra metadata around, but then the operating model becomes larger than the browser session itself.

Hardcoded launch flags are also limited. A single --proxy-server value is clean when one route is enough. It becomes too blunt when the browser needs route selection by request class, domain group, environment, or workflow stage.

PAC fills the gap between those extremes. It is browser-native, request-aware, and deployable as a small policy file. It can stay close to the browser launch, travel with the session configuration, and remain understandable during support review.

BotBrowser's Approach

BotBrowser supports trusted PAC request policy for enterprise workflows that need routing decisions to stay inside the browser network model. Standard PAC routing remains available. Teams can continue using PAC to choose direct routes, HTTP proxies, HTTPS proxies, SOCKS routes, or other normal PAC outcomes supported by the browser.

The additional value is operational consistency. A trusted PAC policy can live next to the profile and launch configuration. That keeps routing policy, browser identity, proxy configuration, and automation entrypoint in the same reviewable bundle. It also avoids spreading request decisions across page scripts and framework code when the browser network layer is the more natural owner.

Configuration uses the standard --proxy-pac-url launch shape:

chromium-browser \
  --bot-profile="profiles/profile.enc" \
  --proxy-pac-url="file:///absolute/path/to/policy.pac"

A controlled loopback PAC service is also a common enterprise shape when the policy is generated by an internal control plane:

chromium-browser \
  --bot-profile="profiles/profile.enc" \
  --proxy-pac-url="http://127.0.0.1:8080/policy.pac"

Keep the source explicit. A local file is easy to audit and version with the job definition. A loopback service is useful when an internal tool chooses policy per worker. In both cases, the policy should be treated as part of the browser environment, not as an incidental helper script.

BotBrowser's request policy model is intended for approved enterprise use. It should be paired with profile-backed browser identity, clear route ownership, and normal privacy validation. It is not a replacement for responsible use controls or customer-side authorization checks.

The Public Function Model

BotBrowser PAC Request Policy uses the normal PAC entrypoint first:

function FindProxyForURL(url, host) {
  if (dnsDomainIs(host, "example.internal")) {
    return "DIRECT";
  }
  return "SOCKS5 proxy.example.com:1080";
}

FindProxyForURL(url, host) remains the right function for ordinary proxy selection. It receives the URL and host, then returns a standard PAC result such as DIRECT, PROXY, HTTPS, SOCKS, SOCKS4, or SOCKS5.

Approved ENT Tier3 profiles can add BotBrowser's request callback in the same trusted PAC source:

function BotBrowserFindProxyForRequest(url, host, method, headersB64, bodyB64, bodyState) {
  if (method === "POST" && dnsDomainIs(host, "api.example.test")) {
    return "CAPTURE; CAPTURE_FILE /var/botbrowser/captures/api.jsonl; CAPTURE_TAG api-post; CONTINUE";
  }
  if (shExpMatch(url, "https://media.example.test/*")) {
    return "SOCKS5 media-proxy.example.net:1080";
  }
  if (dnsDomainIs(host, "static.example.test")) {
    return "HTTPS static-proxy.example.net:8443";
  }
  return "CONTINUE";
}

BotBrowserFindProxyForRequest is evaluated as a browser request policy callback. It does not remove standard PAC. When the callback returns CONTINUE, or when it does not return a valid route, the request continues through normal PAC routing. When it returns a standard PAC route, that route applies to the current request.

The callback receives six values:

ParameterMeaning
urlFull request URL.
hostRequest hostname.
methodHTTP method, for example GET or POST.
headersB64Base64-encoded request headers record.
bodyB64Base64-encoded request body when body bytes are available.
bodyStateBody availability state: none, bytes, file, stream, too_large, or unsupported.

This gives the PAC policy more context than standard FindProxyForURL, while still keeping the decision in the browser network path.

Request Actions

The BotBrowser callback can return routing actions, control actions, and capture actions. Actions can be combined with semicolons.

Return valueBehavior
CONTINUEContinue request handling and use standard PAC routing if the callback does not provide a route.
BLOCKStop the request.
CAPTUREEnable capture for this request when paired with CAPTURE_FILE <path>.
CAPTURE_TAG <tag>Attach a short tag to the capture record.
CAPTURE_FILE <path>Write capture records to an approved absolute path when paired with CAPTURE.
DIRECTConnect directly for the current request.
PROXY host:portRoute the current request through an HTTP proxy.
HTTPS host:portRoute the current request through an HTTPS proxy.
SOCKS host:portRoute the current request through a SOCKS proxy.
SOCKS4 host:portRoute the current request through a SOCKS4 proxy.
SOCKS5 host:portRoute the current request through a SOCKS5 proxy.

Capture is explicit. CAPTURE_FILE <path> alone does not write a record. CAPTURE and CAPTURE_FILE <path> must appear together. CAPTURE; CAPTURE_FILE <path>; BLOCK writes the approved capture record and then stops the request. CAPTURE; CAPTURE_FILE <path>; CAPTURE_TAG <tag>; CONTINUE records the request and keeps the normal route.

The return string can also mix policy and route selection. A media request can return a SOCKS5 route, an internal host can return DIRECT, and an ordinary navigation can return CONTINUE so the default FindProxyForURL decision remains active.

Trusted PAC Sources

The request callback is available only from explicit PAC sources that the deployment controls:

  • file:// PAC files.
  • data: PAC URLs.
  • Loopback HTTP(S) PAC services.
  • Explicit remote HTTP(S) PAC services controlled by the operator.

PAC auto-detect and WPAD remain useful for standard PAC routing, but they are not the right source for BotBrowser request callbacks. Enterprise request policy should come from a known file, a controlled loopback service, or a controlled remote service over HTTPS.

This trust model matters in production. The PAC file can route traffic, stop selected requests, or write approved capture records. Treat it as part of the browser launch package, with the same review discipline used for profiles, proxy inventory, and worker configuration.

Where It Fits

PAC Request Policy is most useful when a workflow has more than one request class but still needs one coherent browser identity.

A search or monitoring workflow may need navigation requests to follow a regional route while static assets use a different route. A QA workflow may need internal test hosts to remain local while external pages follow the selected profile route. A multi-region validation job may need route selection to be defined by a small policy table rather than by separate code paths in every automation script.

It also helps when the team wants the same browser workflow to run under Playwright, Puppeteer, raw CDP, or a worker service without rewriting route logic for each framework. The policy stays in PAC. The automation framework launches the browser and drives the page. The browser owns the network route decision.

This separation keeps responsibilities clear:

  • The profile defines the browser identity.
  • The proxy configuration defines available network paths.
  • The PAC policy selects the path for each request class.
  • The automation framework performs the workflow.
  • The validation process checks that the result stays consistent.

That division is boring in a good way. It gives support, QA, and platform teams fewer places to inspect when behavior changes.

Relationship To Per-Context Workflows

Per-context browser operation increases the need for clean policy boundaries. A single browser instance can host multiple independent contexts, each with its own profile, proxy route, storage, and runtime behavior. If request logic is scattered across page handlers, it becomes harder to know which rule belongs to which context.

PAC Request Policy gives teams a way to keep network policy close to the context's launch configuration. A context can carry the profile and routing policy it needs without relying on global process assumptions. That is especially important when workers are reused, contexts are created and destroyed over time, or a fleet runs many profile families on the same host.

The same principle applies to browser-family consistency. A profile-backed browser identity should not be separated from network behavior. If a workflow is validating a browser family, region, and route, the request policy should be part of that validation package.

Deployment Notes

Treat PAC policy as production configuration. Store it with the job definition, review it like code, and keep it small enough that an operator can understand the intended routing behavior.

Prefer explicit policy sources. A local file works well for stable deployments. A loopback service works well when a worker agent needs to provide a policy for the current job. Avoid relying on ambient machine state that is hard to reproduce later.

Keep policy names boring and descriptive. A file named policy.pac under a job directory is easier to review than a generated path whose purpose is unclear. If a team uses generated policies, emit a manifest with the job so the launch can be reproduced.

Keep route ownership clear. If a page route changes, the PAC file should be the first place to inspect. If a proxy credential changes, the proxy inventory should be the first place to inspect. If a profile changes, the profile package should be the first place to inspect. Mixing all of those concerns into one helper script makes support slower.

For sensitive workflows, avoid logging request contents from general-purpose automation code. Operational logs should focus on route decisions, policy version, profile family, and high-level outcome. Store detailed evidence only in controlled support packages when it is required for an authorized review.

Validation

Validation should confirm that policy behavior matches the deployment plan without turning the blog or docs into a low-level request inspection recipe.

Start with a simple route matrix. List the request classes that matter to the workflow, the expected route family for each class, and the profile family that will run the session. Keep this matrix near the deployment configuration.

Run the workflow with the same profile and route setup used in production. Review page behavior, route behavior, and browser signal consistency together. A route policy that works only in a synthetic test but changes behavior during a real navigation chain is not enough.

Repeat the same validation before and after browser updates, profile updates, or proxy inventory changes. PAC policy is most valuable when it becomes part of the release process rather than a one-time launch option.

For scale, validate a representative sample of workers instead of only one local machine. Routing behavior can be affected by host networking, proxy availability, file paths, and service startup order. A policy that is stable across the actual fleet is more useful than a policy that only works in a developer shell.

Common Mistakes

The first mistake is treating PAC as an afterthought. If the browser's network path matters to privacy and consistency, the PAC file is part of the product environment. It should be versioned, reviewed, and kept with the launch configuration.

The second mistake is splitting the same rule across too many layers. If a route decision lives partly in PAC, partly in Playwright, partly in a side proxy, and partly in job code, support becomes guesswork. Choose the owner for each decision and keep it there.

The third mistake is using PAC to compensate for a profile mismatch. PAC can select routes. It cannot make an inconsistent profile coherent. The browser identity, locale, timezone, proxy region, and route policy still need to be planned together.

The fourth mistake is making policy too clever. A small policy that covers the routes the workflow actually needs is easier to validate than a large policy with many rarely used branches. Start with the minimum routing map and grow only when operations require it.

The fifth mistake is forgetting headless and server deployment. Local desktop testing is not enough if production runs in Linux containers or headless servers. Validate PAC loading, file access, loopback service startup, and route behavior under the same deployment shape.

When To Use It

Use PAC Request Policy when the browser needs request-aware routing and the policy should remain tied to the browser environment.

It is a good fit for enterprise browser automation, regional validation, long-running workflows, per-context routing, and production QA where route behavior must be repeatable. It is also useful when teams want one policy model that can run under multiple automation frameworks.

It is not necessary for simple deployments where every request uses the same proxy. In that case, --proxy-server remains the cleaner option. It is also not a substitute for profile planning, proxy inventory management, or responsible use controls.

The practical rule is simple: if route decisions are part of the browser identity and support process, keep them in the browser network model. If the workflow only needs one route, keep the configuration simple.

There is also a team-process signal. If route changes require coordination between browser engineers, infrastructure engineers, QA, and support, PAC is often the right place to centralize the policy. It gives every team one artifact to review. The browser launch says which policy is active, the policy says which route family applies, and validation can confirm the result against the same file. That is easier to operate than a route decision hidden inside a test helper or copied across several worker scripts.

For smaller teams, the same benefit appears during debugging. A failed navigation can be reviewed by checking the active profile, the proxy route, and the PAC policy in order. If each piece is explicit, the support path stays short.

FAQ

Is this the same as a normal PAC file?

It starts from the normal PAC model. Standard PAC routing remains available. BotBrowser adds an enterprise request policy operating model around trusted PAC sources so route policy can stay close to profile-backed browser sessions.

Does it replace --proxy-server?

No. Use --proxy-server when one proxy route is enough. Use PAC when the browser needs request-aware routing under a reviewable policy.

Can this run from a local PAC file?

Yes. A local PAC file is a good choice when the policy is stable and should be versioned with the job. A controlled loopback PAC service is useful when internal tooling needs to provide policy dynamically for a worker.

Does it work with automation frameworks?

Yes. The framework launches and drives the browser, while PAC remains the owner of route selection. This keeps the routing policy less dependent on one framework's request handling API.

Should every workflow use PAC?

No. PAC adds value when routing decisions differ by request class or context. Simple single-route workflows should stay simple.

Summary

PAC Request Policy gives enterprise teams a browser-level way to keep request routing, profile identity, and automation workflows aligned. It preserves the strengths of standard PAC while fitting the way modern BotBrowser deployments run: profile-backed sessions, per-context operation, headless workers, proxy-aware routing, and repeatable validation.

Use it when routing policy is part of the browser environment. Keep the policy explicit, reviewable, and close to the profile and launch configuration. Validate it with the real workflow, not only a minimal test page. For teams that treat the browser as infrastructure, this keeps request-aware policy inside the same operating model as the rest of BotBrowser's privacy protection stack.

For configuration details, see PAC Request Policy, Proxy Configuration, and Per-Context Proxy.

#Pac#Request-Policy#Network#Proxy#Privacy#Enterprise

Take BotBrowser from research to production

The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.