Skip to content

Report browser-control CDP commands in the control telemetry category - #323

Open
archandatta wants to merge 1 commit into
archand/kernel-1870/telemetry-control-platform-splitfrom
archand/kernel-1870/cdp-control-telemetry
Open

Report browser-control CDP commands in the control telemetry category#323
archandatta wants to merge 1 commit into
archand/kernel-1870/telemetry-control-platform-splitfrom
archand/kernel-1870/cdp-control-telemetry

Conversation

@archandatta

@archandatta archandatta commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Stacked on #322 — the base is that branch, so this diff is only the new event.

Summary

  • the CDP proxy emits cdp_command under control for the methods that drive the browser: input gestures, navigation, dialog handling, file selection and screenshots
  • configuration and the DOM/Runtime traffic a client library issues on the caller's behalf are not reported; Runtime.evaluate and Runtime.callFunctionOn are excluded deliberately, since every locator resolution is one and including them would bury the gestures
  • mouseMoved, keyUp and char are dropped, so a click reads as a press and a release rather than three frames
  • payload is shape only: method, session_id, event_type, x, y, button, text_length, and key for keys that command the page (Enter, Tab, arrows, modifiers, F-keys, by allowlist). Never typed characters, never the URL — control is captured by default

Why

api_call covers browser control that arrives through the kernel-images API, but a client driving the browser over the CDP proxy — Playwright, Puppeteer, an SDK — produced nothing at all. A session whose agent works over CDP showed cdp_connect, cdp_disconnect, and nothing in between.

Hot path

Every client frame hits the transform, so classification scans for the frame's method name and does a map lookup; only an allowlisted method is unmarshalled, and a large Runtime.callFunctionOn costs the scan rather than a parse. The scan checks every "method" the frame contains and the parsed top-level method is what decides, so a nested "method" inside params can neither spoof a control command nor hide one.

Existing behavior is unchanged: message relaying, cdp_connect/cdp_disconnect and the message_count they report are untouched, and nothing is emitted for the upstream direction.

Testing

  • go vet ./... clean; go test -race green across the non-e2e packages
  • new: a classification table (control vs configuration vs library bookkeeping vs command results vs upstream events vs nested-method frames vs malformed), a payload-leakage test asserting text, key, URL and file-path frames leak none of those values, and a proxy-level test asserting two client gestures produce two events while the echoed upstream frames produce none
  • TestUpstreamManagerDetectsChromiumAndRestart flakes about 1 in 4 runs on this package — reproduced on the unmodified base, it launches real Chromium. The new tests passed 10/10.
  • e2e not run — needs Docker

Note

Medium Risk
Runs on every client CDP frame in the proxy hot path and emits control telemetry that is on by default; redaction mistakes could leak credentials, though tests explicitly guard typed text and URLs.

Overview
Adds cdp_command telemetry (control) for client→browser CDP traffic through the DevTools WebSocket proxy, so Playwright/Puppeteer sessions are visible between connect and disconnect.

The proxy’s message transform calls publishCdpCommand only on client-to-upstream text frames. New cdpcommand logic allowlists browser-control methods (input, navigation, screenshots, etc.), skips noisy phases (mouseMoved, keyUp, char) and library/runtime bookkeeping, and uses a byte scan before JSON parse on the hot path. Event payloads are shape-only (method, coordinates, text_length, allowlisted named_key)—never typed text, URLs, or file paths.

OpenAPI and generated oapi / category_gen register BrowserCdpCommandEvent and map cdp_command to control. Tests cover classification edge cases, secret leakage, and proxy-level emission counts.

Reviewed by Cursor Bugbot for commit 02ad34d. Bugbot is set up for automated code reviews on this repo. Configure here.

@archandatta
archandatta force-pushed the archand/kernel-1870/cdp-control-telemetry branch from b630069 to 0296e93 Compare August 4, 2026 13:20
@archandatta
archandatta force-pushed the archand/kernel-1870/cdp-control-telemetry branch from 0296e93 to 0962339 Compare August 6, 2026 16:20
@archandatta
archandatta force-pushed the archand/kernel-1870/cdp-control-telemetry branch 2 times, most recently from 054ecbb to 59554b4 Compare August 7, 2026 12:51
@archandatta
archandatta marked this pull request as ready for review August 7, 2026 13:43
api_call covers browser control issued through the kernel-images API, but a
client driving the browser over the CDP proxy — Playwright, Puppeteer, an SDK —
produced nothing at all, so a session whose agent works over CDP showed connect,
disconnect and nothing in between.

The proxy now emits cdp_command under control for the methods that drive the
browser: input gestures, navigation, dialog handling, file selection and
screenshots. Configuration and the DOM/Runtime traffic a client library issues
on the caller's behalf stay out, and the phases that duplicate a gesture
(mouseMoved, keyUp, char) are dropped so one action reads as one event.

Payloads are shape only: method, session, event type, coordinates, button and
the length of submitted text. Never the text, the key or the URL — control is
captured by default, and on a login page those are the credentials.

Frames are rejected by a single scan for the method name before anything is
unmarshalled, so a large Runtime.callFunctionOn costs a scan rather than a
parse. The parsed top-level method decides classification, so a nested "method"
key cannot spoof one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@archandatta
archandatta force-pushed the archand/kernel-1870/cdp-control-telemetry branch from 59554b4 to 02ad34d Compare August 7, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant