Cybersecurity Browser Extension Agent
The local detection service for the Cybersecurity Browser Extension. It runs the
three-model phishing ensemble on your own machine and answers the extension on
http://127.0.0.1:5000.
Nothing about the pages you visit is sent anywhere. The extension parses each page in the tab and sends the agent a URL, a stripped text summary and 43 numeric features; the agent replies with a verdict. Raw HTML never leaves the browser, and the agent only ever accepts connections from your own computer.
browser tab ──► extension ──► 127.0.0.1:5000/predict_ensemble
├─ URL DistilBERT (ONNX)
├─ HTML MobileBERT (ONNX)
└─ meta LightGBM 43 features
└─ weighted vote → legitimate / suspicious / phishing
Requirements
- Python 3.10 or newer
- ~1 GB of disk: ~400 MB for the models, the rest for the runtime
- Windows, macOS or Linux — no admin rights needed, everything installs per-user
There is no GPU requirement. A page takes roughly 150 ms on a laptop CPU.
Install
python -m pip install "cybersecurity-browser-extension-agent[tray]"
[tray] adds the system-tray icon (pystray, pillow); leave it off for a headless
machine. The command it installs is cyberext. Optional on-device training:
python -m pip install "cybersecurity-browser-extension-agent[train]" # torch, transformers, peft
Use the same Python for both — the training add-on has to be installed next to the
agent it extends. From a source checkout, python -m pip install ".[tray]" in the
agent folder does the same.
Upgrading from the pre-rename package (phishguard-agent, command phishguard):
uninstall it first (python -m pip uninstall phishguard-agent), then install this one.
The existing ~/.phishguard folder — models, training weights, reports, consent — is
moved to ~/.cyberext on first start, and cyberext autostart enable /
cyberext shortcut create replace the old login entry and shortcuts.
[train] pulls in PyTorch (~1 GB). Skip it unless you intend to contribute model
updates — detection does not need it.
First run
cyberext start
No configuration is needed. Models come from the project's model service
(fl-api on Cloud Run), which hands the agent short-lived signed download links;
the storage bucket itself stays private, and no credentials are ever stored on
your machine.
To point the agent somewhere else (a test server, say), cyberext configure
--fl-server-url URL writes ~/.cyberext/config.json; --fl-server-url default
returns to the built-in service. Environment variables (FL_SERVER_URL,
FL_API_KEY, CYBEREXT_PORT, CYBEREXT_UPDATE_HOURS) override the file when
set, but a shell variable is not visible to an agent started at login — anything
the agent needs unattended belongs in the config file.
On the first start the agent downloads the current model version (~375 MB), checks each file against the sha256 in the manifest, and only then makes that version active. An interrupted download can never leave a half-swapped model in use.
Then load the extension and set Backend → Local (Dev) in its sidebar.
Commands
| Command | What it does |
|---|---|
cyberext start |
run the agent (tray icon if [tray] is installed) |
cyberext start --no-tray |
run it headless in the terminal |
cyberext status |
is it running, which model version, updater progress |
cyberext update [--force] |
check for new models now |
cyberext where |
print the paths it uses |
cyberext configure ... |
store settings for unattended start |
cyberext autostart enable|disable|status |
run at login |
cyberext shortcut create|remove|status |
desktop / launcher shortcut |
cyberext fetch-train-weights [--model M] |
PyTorch weights for on-device training ([train] extra) |
configure accepts --fl-server-url, --fl-api-key, --port, --update-hours;
the value default clears a setting (an empty "" works too, except in Windows
PowerShell 5.1, which silently drops empty arguments). Leave the port at 5000 — that is the only port
the extension connects to.
Start at login
cyberext autostart enable
Per-user, no services and no admin rights — and disable removes exactly what
enable created:
| OS | What it writes |
|---|---|
| Windows | %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\cyberext-agent.cmd (launches pythonw.exe, no console window) |
| macOS | ~/Library/LaunchAgents/com.cyberext.agent.plist (loaded with launchctl) |
| Linux | $XDG_CONFIG_HOME/autostart/cyberext-agent.desktop |
It starts with the tray icon where one is available, falling back to headless where it is not: a background process you cannot see or quit is worse than no icon.
Desktop shortcut
cyberext shortcut create
Starts the agent with a double-click, no terminal:
| OS | What it creates |
|---|---|
| Windows | Cybersecurity Browser Extension Agent.lnk on the Desktop and in the Start Menu, running pythonw.exe (no console window) |
| macOS | ~/Applications/Cybersecurity Browser Extension Agent.app (menu-bar icon only, no Dock tile) + a link on the Desktop |
| Linux | cyberext-agent.desktop in the application launcher, and on the Desktop if there is one |
Opening the shortcut while the agent is already running opens its status page
(http://127.0.0.1:5000/) instead of starting a second copy. shortcut remove checks
each file is one it made before deleting it, so a same-named shortcut of your own is
left alone.
Tray menu
Live status (model version, or download progress), the port it is listening on, a manual update check, the Contribute to model improvement switch, shortcuts to the status page and the data folder, and Quit.
An update-check failure while models are installed shows
Models 1.1.0 ready (update check failed) — detection still works, and the menu
says so rather than implying an outage.
HTTP API
Loopback only; every request is verified to come from 127.0.0.1 before it is
routed, so a misconfigured proxy or a host-header trick cannot reach it. On Windows the
port is also held exclusively, so no other program can bind beside the agent and
intercept what the extension sends. The routes
match the cloud predict-service exactly, so the extension needs no changes.
| Route | Purpose |
|---|---|
GET / |
human-readable status page (refreshes every 5 s) |
GET /health |
uptime, models_ready, model_version, training_available |
GET /ensemble_status |
which model files are present, updater state |
POST /predict_ensemble |
the full three-branch verdict |
POST /predict, POST /batch_predict |
URL-only classification (link scanning) |
GET /reports, POST /report, /report/update, /report/delete |
your local corrections |
POST /model/update, GET /model/update_status |
model download |
POST /fusion/report |
scan-panel correction (scores + label; uploaded only with consent) |
GET/POST /fl/consent |
device-owner consent for contributing (+ pending correction count) |
POST /fl_train, GET /fl_status |
local training round (needs [train] + consent) |
Where your data lives
Everything is under ~/.cyberext (override with CYBEREXT_HOME) — uninstalling
is a delete:
models/<version>/ the active and previous model versions
models/current which version is in use
config.json settings from `cyberext configure`
reports.json your corrections; kept locally, never uploaded as they are
contribute.flag present only if you turned on training consent
agent.log
Contributing to model improvement (opt-in)
Off by default. Switch it on from the extension's Federated Learning page or the
tray menu (both edit contribute.flag). While it is on, the agent sends — anonymously,
with no URL, page content, or device/account ID:
| What | When |
|---|---|
| a scan correction: the three branch scores + the right label | each time you flag a wrong verdict on the Page Scan panel |
| a training update: the LoRA adapter from a local round (~3 MB, safetensors) plus sample count, base version and update norm | after a training round you start |
On-device training needs the extra and the base weights:
python -m pip install "cybersecurity-browser-extension-agent[train]"
cyberext fetch-train-weights # ~466 MB; or --model distilbert
A round needs at least 32 reported URLs (the model service enforces the same floor), and the adapter's total change is clipped to a fixed norm before upload. Both reduce how much an update can reveal about the reports it came from; neither is a formal privacy guarantee. HTML-branch training needs reports with page text, which the Report page does not collect yet, so only the URL branch (DistilBERT) trains today.
Consent is separate from anything administrative: it authorises training on your data on your machine. Combining updates and publishing a new model version to everyone is an administrator's decision, made in the cloud. Adapters trained here are never loaded locally — the fleet converges through published versions, otherwise every training device drifts onto private weights.
Troubleshooting
"model server refused the request (HTTP 403)" — the agent was pointed away from
the built-in model service (or at an empty URL, which means "read the private bucket
directly"). Run cyberext configure --fl-server-url default and restart it.
"model server unreachable" — no internet, or the model service is down. Detection
keeps working with the models already installed; the tray shows
Models X ready (update check failed) until the next successful check.
"models_not_ready" from the extension — the first download has not finished.
cyberext status shows the percentage.
The extension says the agent is not running, but it is — check the port. The
extension only talks to 127.0.0.1:5000; the status page and tray menu show which port
the agent is on. If it is anything else, cyberext configure --port 5000 and restart it.
Port 5000 is taken — the agent refuses to start rather than share the port (the tray
icon turns grey and says not running: port in use). Find and stop whatever holds it (on Windows:
netstat -ano | findstr :5000). --port exists for testing; the extension cannot follow
the agent to another port.
The tray icon does not appear — headless Linux, Wayland without an AppIndicator,
or [tray] not installed. The agent still runs; the message says so and it falls
back to headless.
Windows: a model update seems stuck — Windows locks open ONNX files. The agent releases its sessions before swapping files; if you edited the model folder by hand while the agent was running, stop it and start again.
Uninstall
cyberext autostart disable
cyberext shortcut remove
python -m pip uninstall cybersecurity-browser-extension-agent
Then delete ~/.cyberext if you also want the downloaded models gone.
Release files for cybersecurity-browser-extension-agent 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cybersecurity_browser_extension_agent-1.1.1.tar.gz | 38.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cybersecurity_browser_extension_agent-1.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.8 kB
Release files / cybersecurity_browser_extension_agent-1.1.1.tar.gz
| Download URL | cybersecurity_browser_extension_agent-1.1.1.tar.gz |
|---|---|
| Size | 38.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
177647dcfd0ef46e88c8a4def7835196a9258755bdeab9878be3b5233d5c6007
|
|
BLAKE2b-256 checksum How to use checksums |
d27ac56050be78a23a85634508a525561ea6b8edbdd1c58aba7d69ca218e5851
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / cybersecurity_browser_extension_agent-1.1.1-py3-none-any.whl
| Download URL | cybersecurity_browser_extension_agent-1.1.1-py3-none-any.whl |
|---|---|
| Size | 43.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f9b87827d8b58adae85f4f63067be5b22bd3e019954780954e082ea3b6c6b1eb
|
|
BLAKE2b-256 checksum How to use checksums |
9eed6b210674cf18bde3ba0151f5a72115d331f6bd1b8e80fcb7a27696b7125b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|