Profile anatomy
A profile is a JSON document in the profiles/ catalog. It defines a coordinated target across supported HTTP, transport, packet and browser-observation surfaces. The operator chooses the profile; STATIC resolves its supported overrides and startup choices before distributing the effective policy.
The runtime separates declared observations from actual browser operations. It does not automatically choose a different profile by surveying host hardware, silently substitute native values for covered fields, or disable protection according to a site’s hostname.
Read a profile from the outside in
The shipped chrome-windows.json, edge-windows.json and firefox-windows.json files are full examples. This schematic shape omits required values and is not a runnable profile:
{
"profile_identity": { "family": "chromium-like", "variant": "chrome", "platform": "windows" },
"extends": ["primitives/windows-tcp.json"],
"replace": [["User-Agent", "…"]],
"replaceDynamic": [["Accept", { "default": "…", "text/html": "…" }]],
"pass": ["Cookie", "Authorization"],
"fingerprint": { "user_agent": "…", "platform": "Win32" },
"tls": { "schema_version": 2, "hello_variants": [], "http2": {} },
"seeded_overlays": { "screen_profiles": [], "hardware_profiles": [] }
}
| Section | Reader’s question | Consumer |
|---|---|---|
profile_identity | Which family, variant and presented platform? | Catalog, identity checks, browser policy and packet defaults. |
extends | Which parent JSON is merged first? | Loader with relative resolution and cycle checks. |
remove, replace, replaceArbitrary, replaceDynamic, set, append, pass | Which request headers are targeted, and in what context? | Header stage; pass does not establish a filtering allowlist. |
fingerprint | Which observations and enablement flags are controlled? | Shared browser contract and realm-specific installers. |
tls, including http2 | Which supported outbound behavior is desired? | Transport plan and fetcher adapter. |
seeded_overlays | Which declared startup variants may be selected? | Validated profile materialization before requests. |
Resolution and selection
The loader discovers catalog entries, skips manifests/primitives as runtime choices, resolves inheritance and deep-merges parents before the child. Every seeded candidate is checked before selection; zero-weight candidates are excluded, and the selected combined profile validates again. Invalid input must not wait for a particular startup choice to fail. Seeded choices stay stable for the materialized process profile; they are not independent per-request personas.
Proxy startup requires an explicit --profile or configured default. The control plane can select another entry for new Flows; active Flows retain the policy they captured. Already initialized pages/workers likewise retain their browser runtime, so reload or navigate relevant contexts after changing selection. A profile that becomes unavailable is not silently replaced with another catalog identity.
Same-engine profiles provide the most coherent starting point. Cross-family selection does not implement another engine’s APIs or rendering. Firefox-targeted policy suppresses Chromium-only identity hints where covered rather than returning the host identity, but interface presence and operational differences remain. The operator’s choice is not automatically rewritten to match the host.
Browser policy contract
Rust and JavaScript consume a shared browser-profile schema covering supported fields, types, ranges, defaults, aliases and explicit metadata/unsupported fields. Unknown fields, contradictory aliases and invalid supported settings reject before delivery or mutation. The implementations validate the contract subset used by STATIC; they are not general JSON Schema engines or an exhaustive proof of browser fidelity.
Covered semantic checks require a browser variant and reject inconsistent UA/platform/product-major and mapped hint values, available-screen dimensions beyond the screen, enabled inner viewport dimensions beyond outer dimensions, and incompatible destination channel metadata. Supported time zones, safe fixed storage usage/quota, permission states and typed Client Hint arrays validate before delivery. WoW64 denotes a 32-bit binary on 64-bit Windows; configured underlying platform bitness must agree. WebGL 1/2 parameter records use a shared enum/version contract, including extension-owned observations; unresolved names or conflicting aliases do not silently disappear. Actual GPU/extension functionality remains distinct.
Accepted fields are classified as observations, partial controls, aliases or unsupported metadata. Configured fonts can restrict FontFaceSet.check queries; they do not supply installed fonts or a glyph renderer. Public fingerprint labels do not promise a particular output hash. The schema is not a complete captured-device corpus: cross-surface operational equivalence and real reference provenance require independent evidence. Check the runtime schema and JavaScript behavior before interpreting a field as implemented protection.
Observations and real operations
| Policy area | Controlled observation | Operational boundary |
|---|---|---|
| Storage | Fixed advertised quota/usage, with explicit operator overrides. | Real writes, exhaustion, persistence and OPFS. |
| Audio | Configured metadata and selected output interventions; explicit settings take precedence. | Native engine parameters, audible behavior and worklet processors. |
| Media | Finite support/performance policy on covered queries. | Actual codecs, encoding and DRM handles/failures. |
| WebGL | Declared metadata, limits, precision and inventory. | GPU allocation, genuine extensions, shaders and rendering. |
| Genuine standardized cohort, genuine empty disabled collections where available, or explicit collection denial. | Branded collection/viewer parity is not supplied on absent or mismatching hosts. | |
| Devices/voices | Bounded genuine objects with normalized identifying observations. | Physical/installed absence, selection and actual output. |
| WebRTC | Peer/generation-owned address/SDP observations; explicit relay-only transport and relay-routing observation choice. | TURN and real two-peer traffic; mask-all relay rewriting can prevent signaling. |
Controls can intentionally favor privacy over compatibility. A reported capability does not create missing hardware or software. See runtime restrictions and storage configuration.
Keep layers coherent
Compare HTTP user agent and supported Client Hints with the browser identity policy, including high-entropy fields and cached hint requests. Compare TLS/HTTP2/packet targets with their actual supported adapters. A version string does not implement its network behavior, API inventory or rendering.
The profile’s materialized startup choices and private per-realm output state have different purposes. Neither a consistent persona nor changed rendering output alone demonstrates unlinkability. Follow Request headers, TLS, HTTP/2 and JavaScript for each boundary.
Publication bytes and maintenance
Use the existing profile manifest script after profile edits. It normalizes JSON to UTF-8/LF and hashes the actual publication bytes, including inherited primitives. Validate candidate Git-normalized bytes and then the exact committed files for the chosen release; a Windows checkout-only hash is insufficient.
Profile hashes protect byte consistency, not operational equivalence or privacy effectiveness. Use the catalog and ProfileStore matching your build.