Please report security issues privately through GitHub's "Report a
vulnerability" (Security tab of the repository). Do not open a public issue
for a vulnerability. Include the version (agentgo.exe version), what you did
and what you expected. We aim to acknowledge reports within a few days.
- The native bridge exists only for the exact
agentgo://shellorigin and main frame (docs/threat-model.md, T1/T2). A page in a content tab cannot navigate to AgentGo's own documents: the request is cancelled inon_before_browseandtabs.navigaterefuses the scheme. - Policy is evaluated below every adapter. Money actions, CAPTCHA handoff and certificate bypass rules are absolute in every mode.
- Secrets live in Windows Credential Manager or DPAPI. Redaction runs before anything is stored or sent. Instance secrets are redacted from debug output.
- Downloads are off by default, never run automatically, get the Mark of the Web (with the source address) and are scanned with Microsoft Defender. A file Defender flags cannot be opened from AgentGo; a file that was not scanned is never reported as clean and the open prompt says so.
- Dependencies are pinned and hash-verified (
scripts/pins.json). Changes to them are explicit and tested. - No telemetry. Every outgoing connection is listed in
docs/NETWORK_CALLS.md.
| Area | What AgentGo does |
|---|---|
| Renderer sandbox | The release package uses CEF's bootstrap.exe + agentgo.dll shape. Renderers run at untrusted integrity, the GPU process at low integrity. The unsandboxed agentgo.exe is a development build only (package.ps1 -Unsandboxed). |
| DevTools port | AGENTGO_REMOTE_DEBUGGING_PORT is ignored in release builds unless AGENTGO_UNSAFE_DEVTOOLS=1 is also set. Agent-launched instances always clear both. |
| Local files | Agents may open file:// pages only inside a folder the operator granted with --upload-dir. A web page cannot redirect itself to file://. |
| Local SDK server | Binds to loopback, needs a bearer token (constant-time compare), rejects any Host that is not exactly 127.0.0.1, localhost or [::1] (DNS rebinding) and any foreign Origin, and bounds header size. |
| Callers | Pipe and WebSocket session ids are generated by AgentGo. An HTTP client's session is named http-<X-AgentGo-Client> so its tab leases survive between requests; that name is chosen by a client that already holds the bearer token and can never be the operator's UI (only the trusted agentgo://shell documents are). |
| Saved passwords | credentials.fill types a saved sign-in without returning it. Password fields cannot be read back (runtime.get_property, read_property, get_attribute, get_value, edit.cut), runtime.set_property only sets plain state (no markup, addresses, handlers or type), request and response bodies an agent reads have the typed password replaced by [hidden], page script (runtime.evaluate, call_function, init scripts) is refused on the site where a password was typed, and a tab with network interception rules is never filled. |
| Payments and submissions | Money movement always needs the person's approval, in every mode, and a final form submission needs it in approval mode. The check runs for every way of pressing: a reference, a screen position (click, tap, pen, pointer down), Enter or Space on a focused control, and typing or pasting into a card field (including a payment provider's frame). |
| Agent settings | An agent may change only appearance settings (theme, accent, motion, favoritesBar, showHome, showExtensions, siteDark*, translateTo); every other setting is the operator's. Sync and imported profiles never bring in security settings. |
| Agent files | Agents read their artifact folder and the download folder, and change files only in the artifact folder. |
| Extension pages | agentgo-ext://<id>/ and an engine-run extension's chrome-extension://<id>/ pages open as a tab only in the window AgentGo opened for that extension's toolbar button or options, or when the extension itself opens them; websites and agents cannot navigate a tab to them (an extension's own frames inside pages it changes stay allowed, as in Chrome). |
| Approvals | Single use, bound to session, tab, origin and target; pending ones expire after 5 minutes, granted ones 5 minutes after the decision; at most 20 pending per session. |
| Error pages | agentgo://shell/error.html opens only with this run's random key, so a website cannot show a look-alike AgentGo warning. |
| Local model | The GoMini worker (llama-server on 127.0.0.1) needs a random API key generated at each start. |
| Updates | browser.update_check and update_stage accept only a manifest signed with AgentGo's Ed25519 release key (public key compiled in), refuse downgrades and verify the zip's SHA-256. The zip is unpacked by a Rust extractor that rejects .., absolute paths, links and oversize archives. A swap that cannot move every file restores the previous version. |
| Setup | The online AgentGo Setup installs a package only when its SHA-256 matches the release's update-manifest.json and that manifest carries a valid signature from the same release key; every file is then checked against SHA256SUMS.txt (required). The offline installer carries the package hash inside itself. |
| Extensions | Chrome Web Store packages (CRX2/CRX3) must carry a valid signature whose key matches the extension id before they are unpacked. Only the person installs, turns on or removes an extension. Extensions with their Web Store key run in Chromium's extension engine with the permissions their manifest declares, as in Chrome (in the person's and agents' tabs alike); every other extension source (Google Chrome's registry list, policy, component apps) stays off. |
| Process | CEF background networking, component updates, sync and domain-reliability pings are switched off. |
Update manifests are signed with scripts/dev/sign-update.js. The private key
lives outside the repository (%USERPROFILE%\.agentgo-signing\). Back it up
and never commit it. Rotating the key means shipping a new build that contains
the new public key (crates/agentgo-cef/src/runtime/update-key.pub).
-
Release files are built on the maintainer's machine. The Sigstore signatures made by
sign-release.ymlshow that a file was on the release when the workflow ran, not which source it was built from; the Ed25519 release key (kept offline) is what Setup and in-app updates trust. -
The Windows executables are not Authenticode-signed unless you run
package.ps1 -Signwith your own certificate. -
Defender scanning needs Microsoft Defender; without it downloads are marked
unavailable, notclean. -
Cross-origin iframes are not observed or driven by agents.
See docs/SECURITY_TESTING.md for how each claim above is tested.