Open a private security advisory or email dtduc.contact@gmail.com. Please do not open a public issue for a vulnerability.
jevnav run and jevnav go send one request per decision to your configured
Jev endpoint (TYPESAFE_BASE_URL, default https://api.typesafe.ai). That
request contains the page URL, the page title, the candidate list — element
roles, accessible names, hrefs, placeholders — and, for candidates that hold
one, the current field value (password fields are masked to ••••).
jevnav go also sends a digest of the page's visible text (headings, labels,
paragraph text; at most 700 characters), because judging "is the goal done?"
needs the page, not just its controls. Scripted flows (jevnav run) send no
page text. Neither ever sends screenshots, cookies or storage.
jevnav replay sends nothing: it re-resolves recorded decisions against the
page locally, with no model call. There is no telemetry, no analytics and no
hosted component.
A flow value written as ${NAME} is read from the environment at run time and
recorded as value_from_env: "NAME" — the value itself is never written to the
trace. A literal value in the flow file is recorded (it is already plaintext in
your repository).
A trace is evidence, and evidence can be sensitive: it holds page URLs, element
names and the actions taken. Traces are gitignored by default. Read one before
sharing it, and prefer ${ENV} for anything you would not paste into a ticket.
With --user-data-dir jevnav reads and writes a Chromium profile of your
choosing; with --cdp it acts inside the Chrome you already have open, with
everything that browser is logged into. Anything jevnav decides can then act as
you on those sites — that is the point, and it is also the risk. Point it at
your own accounts deliberately, and prefer a dedicated profile over your daily
one. jevnav only talks to the running instance over CDP; it never opens a
profile Chrome has locked, and it never closes a browser it attached to.
browse, goal and run execute actions only when the gate says auto.
review and blocked decisions are recorded and never acted on.
replay --execute re-resolves actions by fingerprint and refuses to act when the
target is gone or duplicated, so a shifted page cannot be clicked by position.
Fresh-browser mode (the default, no --user-data-dir/--cdp) starts a clean
profile with no stored cookies. run/go only visit the URLs in your flow;
under MCP the agent names its own URLs with goto/new_page — that is the point
of the tool — so point the server at sites you are willing to let it browse.
The gate covers the calls where Jev chooses: browse, goal, and the intent
variants of fill_form/upload_files. Everything else is a direct primitive
that runs immediately — press_key, fill_form/upload_files with a
selector, drag, route, read_js, the artifact writers — because the
caller (the agent or the host behind it) already chose the exact target. Those
tools carry MCP annotations (destructiveHint, openWorldHint) so a host can
require confirmation; MCP annotations are hints, so a host that needs a hard
boundary must enforce it itself.
What the server does enforce:
- Every acting call is recorded in the session trace, with typed values,
JS expressions and single-character keys masked (
kind: "action"; decisions arekind: "step") — unless the server was started with--no-trace. Observation tools are not traced, by design (see SPEC). Masking is textual: a modifier combination such asShift+ais recorded as given, and an error message from the page can quote what was typed. - Files stay in one root.
upload_filesreads only inside--file-root(default: the working directory), andscreenshot,heap_snapshotandtrace_stopwrite only inside it. - URLs are http(s).
goto/new_pagerefusefile://unless the server is started with--allow-file-urls;lighthousefollows the same rule and pins its npm version. read_jsis a read channel. It runs arbitrary JavaScript in the page and returns the value — with--cdpattached to your own Chrome it can read anything that browser is logged into. Start the server with--no-evalto close it; the rest of jevnav works unchanged.
jevnav drives a browser and can therefore do anything a browser can do on the sites you point it at. Do not point it at systems you are not authorised to automate, and do not run untrusted flows: a flow file is code-shaped input.