Browser API Integrity Across Realms
Understand which realm owns a browser API and why reflection is a bounded compatibility observation, not an identity signal.
BotBrowser Team
Want the structured docs for Platform?
This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.
BotBrowser can repeat an authorized Window, Worker, and iframe API journey in a declared controlled context and compare visible outcomes. It cannot make realm APIs identical, grant cross-origin access, or certify production privacy; the application remains responsible for ownership, origin policy, accessibility, and data minimization.
TL;DR
Window, Worker, and iframe APIs belong to their own realms. BotBrowser can repeat an authorized controlled-context comparison of visible results, but it cannot make realms identical or turn reflection into an identity or privacy guarantee.
Contents
- API ownership is realm-scoped
- Messages preserve explicit boundaries
- Reflection has a bounded meaning
- Accessible and privacy-safe fallback
- API integrity checklist
- BotBrowser capability and limitation
- Practical conclusion
API ownership is realm-scoped
WHATWG describes a realm as an execution environment with its own global object and intrinsics. The top-level Window, a dedicated Worker, and an iframe document therefore own separate API objects. A value such as Array or fetch must be interpreted in the realm that exposes it, not as a universal browser object.
MDN's JavaScript execution model also separates execution contexts, jobs, and agents. A Worker has no document DOM, while an iframe has its own document and policy context. A supported operation in one realm can be unavailable or intentionally restricted in another. The useful product contract is to name the owner, required capability, and fallback. For how Workers and OffscreenCanvas keep behavior consistent with the page, see Worker and OffscreenCanvas Consistency and Privacy, and for how frame policy can restrict a capability, see Permissions Policy, Browser Capabilities, and Privacy.
Messages preserve explicit boundaries
Window and iframe code can use postMessage, and a Worker can exchange messages with its owner. Structured clone creates receiver-owned values; it does not preserve the sender's object identity. Transferables such as ArrayBuffer move ownership and leave the sender unable to use the original resource. For a related case of handles used from Workers, see the article on Origin Private File System handles, workers, and privacy boundaries.
For every message, define a version, operation, bounded data record, and expected response. Validate event.origin and the schema before using data. An origin check identifies a web origin; it is not business authorization. After an iframe navigation, re-check the origin and protocol before accepting a reply.
Reflection has a bounded meaning
Reflection can answer a narrow question such as whether an API property is exposed or whether a value has a callable shape in this realm. It cannot prove that an implementation is complete, that another realm behaves the same way, or that a browser, device, or person has a particular identity. Constructors, property names, and exception text can vary by release and policy.
Use reflection only for the operation the application needs, then exercise the supported path with synthetic input. A property being present is not proof that permissions, user activation, network access, rendering, or accessibility will succeed. Record the declared browser context and visible result, not an unnecessary inventory of the global object.
Accessible and privacy-safe fallback
When a Worker or iframe capability is unavailable, expose a readable status, preserve keyboard focus, and offer a safe local or server-rendered alternative. A timeout or rejected message should have a visible recovery action and bounded retry behavior. Accessibility belongs to the application contract, not to a browser classification.
Send the smallest record needed for the operation. Avoid copying page state, account records, tokens, or diagnostic inventories across realms. Delete synthetic diagnostics after review and document retention. A realm label or reflection result must not become a hidden analytics dimension or persistent identifier.
API integrity checklist
- Name the owning realm: Window, Worker, or iframe document.
- State the required API operation and its supported fallback.
- Define a versioned message schema, origin check, timeout, and cleanup owner.
- Treat cloned values as receiver-owned and transferred resources as moved.
- Test with synthetic data, visible recovery, keyboard access, and minimal retention.
- Record the declared context and outcome without inferring identity or universal parity.
BotBrowser capability and limitation
BotBrowser controlled contexts can repeat this authorized API journey with a declared profile and compare visible results across isolated contexts. They cannot make Window, Worker, and iframe APIs identical, grant cross-origin access, authenticate messages, or turn reflection into proof of privacy, anonymity, device identity, or production security.
A practical review record. For a release review, record the page origin, owner realm, API operation, protocol version, expected visible state, fallback state, and cleanup result. Keep the request synthetic and small enough to understand from the report. Note whether the iframe stayed on the expected origin and whether the Worker ended after success, timeout, or cancellation. These fields help a team reproduce an application issue without retaining account data or a complete global-object inventory. The record should distinguish an exposed property from a completed operation: a callable method may still reject because permission is missing, user activation expired, the frame policy disallows it, or the host cannot provide the resource. Treat each outcome as a product branch with an accessible message, and name untested branches instead of turning one successful call into a universal guarantee. When a result changes, compare one declared variable at a time: application bundle, frame origin, policy header, browser release, or profile. Avoid broad collection while investigating. A short, synthetic fixture and a visible fallback usually provide enough evidence to adjust the application contract or document a supported limitation.
Realm ownership is also useful when an application has several teams. The page team can own the Window contract, a compute team can own the Worker message schema, and an embed team can own the iframe origin and permissions policy. Each owner can publish the fields it accepts and the visible states it returns. This makes a change review concrete: a renamed operation, a new transfer, or a changed frame origin becomes a contract change rather than an unexplained browser difference. The page should own worker startup and shutdown; the worker should return a bounded status rather than echoing the request; and the frame owner should approve origin and policy changes before production. Explicit accepted, rejected, cancelled, expired, complete, unavailable, and failed states let the page render useful status without exposing stack traces, host paths, or user content.
The same discipline applies to failure handling. A Worker may stop because its script failed, the page closed it, or the host suspended work. An iframe may remain loaded while its document changes origin. The page should report a bounded status, stop pending work, and release resources in every branch. A timeout is an application event with a recovery choice, not evidence that a browser is untrustworthy. If a user leaves a page, cancel pending work, clear queues, release transferred resources, and ignore late responses. A WindowProxy can remain usable while an iframe document changes, so check current origin and protocol after navigation. Workers can be delayed or fail while loading, so bounded retries must not duplicate a side effect.
For user-facing features, test the successful path and at least one expected limitation in every supported realm. Check that status text is announced, focus remains usable, and a keyboard-only user can choose the fallback. Do not hide a missing capability behind a silent retry loop. A clear explanation and a safe alternative often preserve more trust than an attempt to make every environment look equivalent. Accessibility review should cover timeouts, stale announcements, focus, keyboard order, reduced motion, and the supported alternative.
Reflection should remain deliberately narrow in production code. Checking one method before invoking it can prevent an avoidable error; enumerating every global property creates a larger privacy and maintenance surface. If diagnostics are needed, use a fixed allowlist of application-relevant fields, keep values synthetic, and remove the record after the support decision. Constructor names and prototypes can differ after cloning, so prefer schema validation and operation tests. The goal is a reliable user journey, not a catalogue of implementation details. When data crosses a boundary, consider its lifetime on both sides. A cloned object may remain in a queue after the original page has moved on. A transferred buffer may be held by a worker until cancellation. Define who clears queues, terminates workers, closes ports, and removes temporary frame state. Support records should use synthetic fixtures, redact URLs and free-form text, and define deletion. These ownership decisions belong in the application documentation and should be visible in the release checklist.
For a release record, keep one row per branch: success, schema-rejected, origin-mismatch, timeout, and capability-unavailable. Each row names the browser release, profile, frame origin, policy header, protocol version, synthetic input, visible status, and cleanup result. This makes a failure reproducible without collecting a global-object inventory. A method can exist yet reject because the page is insecure, activation expired, or the frame policy denies it; record those as separate product states.
When a result changes, rerun the same synthetic request in a fresh controlled context and vary one field: browser release, frame origin, policy header, or bundle version. Compare the visible branch and cleanup result. Keep the fallback accessible, avoid widening permissions, and delete temporary records after review. These concrete boundaries let product, support, and privacy reviewers decide whether to expand support, retain the fallback, or remove the dependency.
A bounded fixture for each realm.
Use a small fixture with one page, one dedicated worker, and one iframe served from a declared origin. The page creates a request with a numeric protocolVersion, a synthetic requestId, and an operation name from a fixed allowlist. The worker accepts only that version, validates the object shape, and returns status: complete or status: rejected; it never echoes arbitrary fields. The iframe receives the same request only after its current origin matches the allowlist. A visible status element reports the branch and a cancel button terminates pending work.
Run the fixture in five deliberate cases. In the success case, the page records the worker completion and closes the worker. In the schema case, change protocolVersion from 3 to 4 and verify a rejection without a retry. In the origin case, navigate the iframe to a second test origin and verify that the parent refuses the response. In the timeout case, delay the worker response, cancel before it arrives, and verify that the page reports cancellation and clears its queue. In the unavailable case, omit the worker script and verify that the local fallback renders an explanation and remains keyboard reachable. These outcomes are more useful than enumerating every property on Window or Worker.
The report should preserve the exact command, browser release, profile identifier, fixture revision, and stdout line that describes the visible branch. Keep the request synthetic, for example requestId=fixture-07, and redact the page URL to its origin. Record workerClosed=true, iframeOriginChecked=true, and queueLength=0 after cleanup. If the browser rejects a permission or policy, record the rejection category and the user-facing fallback rather than a stack trace. A support engineer can then reproduce the same branch without receiving account data, cookies, tokens, or a global-object dump.
Keep the fixture deterministic by fixing the request order and using one synthetic request for every run. The page should log when it creates the worker, when it sends the request, when it receives a response, and when it performs cleanup. The worker should log whether validation succeeded before doing any work. The iframe should log its current origin and whether its listener was installed. These four checkpoints show whether a failure occurred during setup, validation, delivery, or cleanup. They also make a useful before-and-after comparison when a browser release or application bundle changes.
Do not treat a callable method as proof that the operation is available. A method may reject because the document lacks a secure context, a user activation has expired, a permissions policy was not delegated, or the requested resource is unavailable. Present those cases as distinct statuses so the user sees an actionable next step. A local fallback can offer a smaller calculation, a retry button, or a documented route to continue. It must preserve the same origin checks and data-minimization rules as the primary operation.
For incident review, compare only one declared variable per run. Keep the browser release and fixture revision fixed while changing the frame origin; then restore the origin and change the policy header. If the visible status changes, the report identifies the boundary that changed without requiring a full browser inventory. Retain the run record long enough to reproduce the decision, then delete synthetic requests and temporary logs. This gives engineering a compact compatibility artifact and gives privacy reviewers a clear deletion point. Keep the record limited to the branch, version, origin, and cleanup result so it remains useful without becoming a user profile.
Realm boundaries also define ownership after navigation. The page owns the request timeout and can cancel it; the worker owns its transferred buffer until termination; the iframe owner approves any origin or permissions-policy change. A WindowProxy may remain reachable while the iframe document changes origin, so check location.origin immediately before accepting a response. A transferred ArrayBuffer is detached from the sender, so the report must identify which side releases it. A cloned object remains available to both sides, so keep it small and remove it from queues after the status is rendered. These distinctions prevent a cleanup success from being mistaken for an authorization guarantee.
For accessibility, announce each state through one aria-live element and keep focus on the cancel or fallback control. Test with keyboard-only navigation and with reduced motion enabled. A retry must be bounded and must not repeat a side effect after a late worker response. If the iframe becomes unavailable, preserve the same task in a readable local explanation instead of silently sending it through a new origin. The practical contract is simple: a declared realm may complete the operation, reject it, cancel it, or expose a documented fallback; the result does not identify a person or prove that another origin is trustworthy.
This bounded record also gives release reviewers a clear acceptance checklist for the next browser update.
Practical conclusion
Name the owning realm before comparing an API, validate message origin and schema at each boundary, and keep accessible fallbacks available. Use BotBrowser for bounded authorized comparisons of visible behavior; do not treat matching reflection results as proof of cross-realm equivalence, identity, or production privacy.
Sources
- WHATWG HTML: Realms
- WHATWG HTML: Web messaging
- MDN: JavaScript execution model
- BotBrowser advanced features
Related reading: cross-realm browser consistency.
This article is part of the guide: Web Platform Surfaces: A Consistency Review Map
Related Articles
Cross-Realm Browser Consistency and Privacy
PlatformBrowser Feature Support Is Not Feature Quality
PlatformWeb MIDI API: Permission and Device Privacy
PlatformDocument Picture-in-Picture: Permission and Window Boundaries
PlatformBrowser API Compatibility Data and Feature Fallbacks
PlatformSecure Contexts: Why Advanced Browser APIs Need HTTPS
Run the same check in BotBrowser
Load a profile, keep the signals you just read about consistent inside the browser, and confirm the result on your own machine before a rollout.