cybersecurity-browser-extension-agent 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. cybersecurity_browser_extension_agent-1.1.0/LICENSE +21 -0
  2. cybersecurity_browser_extension_agent-1.1.0/PKG-INFO +292 -0
  3. cybersecurity_browser_extension_agent-1.1.0/README.md +247 -0
  4. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/PKG-INFO +292 -0
  5. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/SOURCES.txt +22 -0
  6. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/dependency_links.txt +1 -0
  7. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/entry_points.txt +2 -0
  8. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/requires.txt +20 -0
  9. cybersecurity_browser_extension_agent-1.1.0/cybersecurity_browser_extension_agent.egg-info/top_level.txt +1 -0
  10. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/__init__.py +4 -0
  11. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/autostart.py +111 -0
  12. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/cli.py +204 -0
  13. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/config.py +147 -0
  14. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/contribute.py +190 -0
  15. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/icon.py +43 -0
  16. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/infer.py +214 -0
  17. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/reports.py +141 -0
  18. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/server.py +415 -0
  19. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/shortcut.py +286 -0
  20. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/train.py +168 -0
  21. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/tray.py +155 -0
  22. cybersecurity_browser_extension_agent-1.1.0/phishguard_agent/updater.py +218 -0
  23. cybersecurity_browser_extension_agent-1.1.0/pyproject.toml +66 -0
  24. cybersecurity_browser_extension_agent-1.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yap Zheng Xian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: cybersecurity-browser-extension-agent
3
+ Version: 1.1.0
4
+ Summary: Local phishing-detection agent for the Cybersecurity Browser Extension (Chrome)
5
+ Author: Yap Zheng Xian
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/zxianyap142857/cybersecurity-browser-extension
8
+ Project-URL: Privacy policy, https://zxianyap142857.github.io/Cybersecurity-Browser-Extension/privacy-policy.html
9
+ Keywords: phishing,security,onnx,federated-learning,browser-extension
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Security
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: flask>=3.0
27
+ Requires-Dist: flask-cors>=4.0
28
+ Requires-Dist: waitress>=3.0
29
+ Requires-Dist: onnxruntime>=1.17
30
+ Requires-Dist: tokenizers>=0.15
31
+ Requires-Dist: numpy>=1.24
32
+ Requires-Dist: pandas>=2.0
33
+ Requires-Dist: scikit-learn==1.7.2
34
+ Requires-Dist: lightgbm>=4.0
35
+ Requires-Dist: joblib>=1.3
36
+ Provides-Extra: tray
37
+ Requires-Dist: pystray>=0.19; extra == "tray"
38
+ Requires-Dist: pillow>=10.0; extra == "tray"
39
+ Provides-Extra: train
40
+ Requires-Dist: torch>=2.2; extra == "train"
41
+ Requires-Dist: transformers<6,>=4.40; extra == "train"
42
+ Requires-Dist: peft<1,>=0.10; extra == "train"
43
+ Requires-Dist: safetensors>=0.4; extra == "train"
44
+ Dynamic: license-file
45
+
46
+ # Cybersecurity Browser Extension Agent
47
+
48
+ The local detection service for the **Cybersecurity Browser Extension**. It runs the
49
+ three-model phishing ensemble on your own machine and answers the extension on
50
+ `http://127.0.0.1:5000`.
51
+
52
+ Nothing about the pages you visit is sent anywhere. The extension parses each page
53
+ in the tab and sends the agent a URL, a stripped text summary and 43 numeric
54
+ features; the agent replies with a verdict. Raw HTML never leaves the browser, and
55
+ the agent only ever accepts connections from your own computer.
56
+
57
+ ```
58
+ browser tab ──► extension ──► 127.0.0.1:5000/predict_ensemble
59
+ ├─ URL DistilBERT (ONNX)
60
+ ├─ HTML MobileBERT (ONNX)
61
+ └─ meta LightGBM 43 features
62
+ └─ weighted vote → legitimate / suspicious / phishing
63
+ ```
64
+
65
+ ## Requirements
66
+
67
+ - Python 3.10 or newer
68
+ - ~1 GB of disk: ~400 MB for the models, the rest for the runtime
69
+ - Windows, macOS or Linux — no admin rights needed, everything installs per-user
70
+
71
+ There is no GPU requirement. A page takes roughly 150 ms on a laptop CPU.
72
+
73
+ ## Install
74
+
75
+ ```bash
76
+ python -m pip install "cybersecurity-browser-extension-agent[tray]"
77
+ ```
78
+
79
+ `[tray]` adds the system-tray icon (pystray, pillow); leave it off for a headless
80
+ machine. The command it installs is `cyberext`. Optional on-device training:
81
+
82
+ ```bash
83
+ python -m pip install "cybersecurity-browser-extension-agent[train]" # torch, transformers, peft
84
+ ```
85
+
86
+ Use the same Python for both — the training add-on has to be installed next to the
87
+ agent it extends. From a source checkout, `python -m pip install ".[tray]"` in the
88
+ `agent` folder does the same.
89
+
90
+ Upgrading from the pre-rename package (`phishguard-agent`, command `phishguard`):
91
+ uninstall it first (`python -m pip uninstall phishguard-agent`), then install this one.
92
+ The existing `~/.phishguard` folder — models, training weights, reports, consent — is
93
+ moved to `~/.cyberext` on first start, and `cyberext autostart enable` /
94
+ `cyberext shortcut create` replace the old login entry and shortcuts.
95
+
96
+ `[train]` pulls in PyTorch (~1 GB). Skip it unless you intend to contribute model
97
+ updates — detection does not need it.
98
+
99
+ ## First run
100
+
101
+ ```bash
102
+ cyberext start
103
+ ```
104
+
105
+ No configuration is needed. Models come from the project's model service
106
+ (`fl-api` on Cloud Run), which hands the agent short-lived signed download links;
107
+ the storage bucket itself stays private, and no credentials are ever stored on
108
+ your machine.
109
+
110
+ To point the agent somewhere else (a test server, say), `cyberext configure
111
+ --fl-server-url URL` writes `~/.cyberext/config.json`; `--fl-server-url default`
112
+ returns to the built-in service. Environment variables (`FL_SERVER_URL`,
113
+ `FL_API_KEY`, `CYBEREXT_PORT`, `CYBEREXT_UPDATE_HOURS`) override the file when
114
+ set, but a shell variable is not visible to an agent started at login — anything
115
+ the agent needs unattended belongs in the config file.
116
+
117
+ On the first start the agent downloads the current model version (~375 MB), checks
118
+ each file against the sha256 in the manifest, and only then makes that version
119
+ active. An interrupted download can never leave a half-swapped model in use.
120
+
121
+ Then load the extension and set **Backend → Local (Dev)** in its sidebar.
122
+
123
+ ## Commands
124
+
125
+ | Command | What it does |
126
+ |---|---|
127
+ | `cyberext start` | run the agent (tray icon if `[tray]` is installed) |
128
+ | `cyberext start --no-tray` | run it headless in the terminal |
129
+ | `cyberext status` | is it running, which model version, updater progress |
130
+ | `cyberext update [--force]` | check for new models now |
131
+ | `cyberext where` | print the paths it uses |
132
+ | `cyberext configure ...` | store settings for unattended start |
133
+ | `cyberext autostart enable\|disable\|status` | run at login |
134
+ | `cyberext shortcut create\|remove\|status` | desktop / launcher shortcut |
135
+ | `cyberext fetch-train-weights [--model M]` | PyTorch weights for on-device training (`[train]` extra) |
136
+
137
+ `configure` accepts `--fl-server-url`, `--fl-api-key`, `--port`, `--update-hours`;
138
+ the value `default` clears a setting (an empty `""` works too, except in Windows
139
+ PowerShell 5.1, which silently drops empty arguments). Leave the port at 5000 — that is the only port
140
+ the extension connects to.
141
+
142
+ ### Start at login
143
+
144
+ ```bash
145
+ cyberext autostart enable
146
+ ```
147
+
148
+ Per-user, no services and no admin rights — and `disable` removes exactly what
149
+ `enable` created:
150
+
151
+ | OS | What it writes |
152
+ |---|---|
153
+ | Windows | `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\cyberext-agent.cmd` (launches `pythonw.exe`, no console window) |
154
+ | macOS | `~/Library/LaunchAgents/com.cyberext.agent.plist` (loaded with `launchctl`) |
155
+ | Linux | `$XDG_CONFIG_HOME/autostart/cyberext-agent.desktop` |
156
+
157
+ It starts **with** the tray icon where one is available, falling back to headless
158
+ where it is not: a background process you cannot see or quit is worse than no icon.
159
+
160
+ ### Desktop shortcut
161
+
162
+ ```bash
163
+ cyberext shortcut create
164
+ ```
165
+
166
+ Starts the agent with a double-click, no terminal:
167
+
168
+ | OS | What it creates |
169
+ |---|---|
170
+ | Windows | `Cybersecurity Browser Extension Agent.lnk` on the Desktop and in the Start Menu, running `pythonw.exe` (no console window) |
171
+ | macOS | `~/Applications/Cybersecurity Browser Extension Agent.app` (menu-bar icon only, no Dock tile) + a link on the Desktop |
172
+ | Linux | `cyberext-agent.desktop` in the application launcher, and on the Desktop if there is one |
173
+
174
+ Opening the shortcut while the agent is already running opens its status page
175
+ (`http://127.0.0.1:5000/`) instead of starting a second copy. `shortcut remove` checks
176
+ each file is one it made before deleting it, so a same-named shortcut of your own is
177
+ left alone.
178
+
179
+ ## Tray menu
180
+
181
+ Live status (model version, or download progress), the port it is listening on, a
182
+ manual update check, the *Contribute to model improvement* switch, shortcuts to the
183
+ status page and the data folder, and Quit.
184
+
185
+ An update-check failure while models are installed shows
186
+ `Models 1.1.0 ready (update check failed)` — detection still works, and the menu
187
+ says so rather than implying an outage.
188
+
189
+ ## HTTP API
190
+
191
+ Loopback only; every request is verified to come from `127.0.0.1` before it is
192
+ routed, so a misconfigured proxy or a host-header trick cannot reach it. On Windows the
193
+ port is also held exclusively, so no other program can bind beside the agent and
194
+ intercept what the extension sends. The routes
195
+ match the cloud predict-service exactly, so the extension needs no changes.
196
+
197
+ | Route | Purpose |
198
+ |---|---|
199
+ | `GET /` | human-readable status page (refreshes every 5 s) |
200
+ | `GET /health` | uptime, `models_ready`, `model_version`, `training_available` |
201
+ | `GET /ensemble_status` | which model files are present, updater state |
202
+ | `POST /predict_ensemble` | the full three-branch verdict |
203
+ | `POST /predict`, `POST /batch_predict` | URL-only classification (link scanning) |
204
+ | `GET /reports`, `POST /report`, `/report/update`, `/report/delete` | your local corrections |
205
+ | `POST /model/update`, `GET /model/update_status` | model download |
206
+ | `POST /fusion/report` | scan-panel correction (scores + label; uploaded only with consent) |
207
+ | `GET/POST /fl/consent` | device-owner consent for contributing (+ pending correction count) |
208
+ | `POST /fl_train`, `GET /fl_status` | local training round (needs `[train]` + consent) |
209
+
210
+ ## Where your data lives
211
+
212
+ Everything is under `~/.cyberext` (override with `CYBEREXT_HOME`) — uninstalling
213
+ is a delete:
214
+
215
+ ```
216
+ models/<version>/ the active and previous model versions
217
+ models/current which version is in use
218
+ config.json settings from `cyberext configure`
219
+ reports.json your corrections; kept locally, never uploaded as they are
220
+ contribute.flag present only if you turned on training consent
221
+ agent.log
222
+ ```
223
+
224
+ ## Contributing to model improvement (opt-in)
225
+
226
+ Off by default. Switch it on from the extension's **Federated Learning** page or the
227
+ tray menu (both edit `contribute.flag`). While it is on, the agent sends — anonymously,
228
+ with no URL, page content, or device/account ID:
229
+
230
+ | What | When |
231
+ |---|---|
232
+ | a **scan correction**: the three branch scores + the right label | each time you flag a wrong verdict on the Page Scan panel |
233
+ | 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 |
234
+
235
+ On-device training needs the extra and the base weights:
236
+
237
+ ```bash
238
+ python -m pip install "cybersecurity-browser-extension-agent[train]"
239
+ cyberext fetch-train-weights # ~466 MB; or --model distilbert
240
+ ```
241
+
242
+ A round needs **at least 32 reported URLs** (the model service enforces the same
243
+ floor), and the adapter's total change is **clipped** to a fixed norm before upload.
244
+ Both reduce how much an update can reveal about the reports it came from; neither is a
245
+ formal privacy guarantee. HTML-branch training needs reports with page text, which the
246
+ Report page does not collect yet, so only the URL branch (DistilBERT) trains today.
247
+
248
+ Consent is separate from anything administrative: it authorises training on *your*
249
+ data on *your* machine. Combining updates and publishing a new model version to
250
+ everyone is an administrator's decision, made in the cloud. Adapters trained here are
251
+ never loaded locally — the fleet converges through published versions, otherwise every
252
+ training device drifts onto private weights.
253
+
254
+ ## Troubleshooting
255
+
256
+ **"model server refused the request (HTTP 403)"** — the agent was pointed away from
257
+ the built-in model service (or at an empty URL, which means "read the private bucket
258
+ directly"). Run `cyberext configure --fl-server-url default` and restart it.
259
+
260
+ **"model server unreachable"** — no internet, or the model service is down. Detection
261
+ keeps working with the models already installed; the tray shows
262
+ `Models X ready (update check failed)` until the next successful check.
263
+
264
+ **"models_not_ready" from the extension** — the first download has not finished.
265
+ `cyberext status` shows the percentage.
266
+
267
+ **The extension says the agent is not running, but it is** — check the port. The
268
+ extension only talks to `127.0.0.1:5000`; the status page and tray menu show which port
269
+ the agent is on. If it is anything else, `cyberext configure --port 5000` and restart it.
270
+
271
+ **Port 5000 is taken** — the agent refuses to start rather than share the port (the tray
272
+ icon turns grey and says *not running: port in use*). Find and stop whatever holds it (on Windows:
273
+ `netstat -ano | findstr :5000`). `--port` exists for testing; the extension cannot follow
274
+ the agent to another port.
275
+
276
+ **The tray icon does not appear** — headless Linux, Wayland without an AppIndicator,
277
+ or `[tray]` not installed. The agent still runs; the message says so and it falls
278
+ back to headless.
279
+
280
+ **Windows: a model update seems stuck** — Windows locks open ONNX files. The agent
281
+ releases its sessions before swapping files; if you edited the model folder by hand
282
+ while the agent was running, stop it and start again.
283
+
284
+ ## Uninstall
285
+
286
+ ```bash
287
+ cyberext autostart disable
288
+ cyberext shortcut remove
289
+ python -m pip uninstall cybersecurity-browser-extension-agent
290
+ ```
291
+
292
+ Then delete `~/.cyberext` if you also want the downloaded models gone.
@@ -0,0 +1,247 @@
1
+ # Cybersecurity Browser Extension Agent
2
+
3
+ The local detection service for the **Cybersecurity Browser Extension**. It runs the
4
+ three-model phishing ensemble on your own machine and answers the extension on
5
+ `http://127.0.0.1:5000`.
6
+
7
+ Nothing about the pages you visit is sent anywhere. The extension parses each page
8
+ in the tab and sends the agent a URL, a stripped text summary and 43 numeric
9
+ features; the agent replies with a verdict. Raw HTML never leaves the browser, and
10
+ the agent only ever accepts connections from your own computer.
11
+
12
+ ```
13
+ browser tab ──► extension ──► 127.0.0.1:5000/predict_ensemble
14
+ ├─ URL DistilBERT (ONNX)
15
+ ├─ HTML MobileBERT (ONNX)
16
+ └─ meta LightGBM 43 features
17
+ └─ weighted vote → legitimate / suspicious / phishing
18
+ ```
19
+
20
+ ## Requirements
21
+
22
+ - Python 3.10 or newer
23
+ - ~1 GB of disk: ~400 MB for the models, the rest for the runtime
24
+ - Windows, macOS or Linux — no admin rights needed, everything installs per-user
25
+
26
+ There is no GPU requirement. A page takes roughly 150 ms on a laptop CPU.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ python -m pip install "cybersecurity-browser-extension-agent[tray]"
32
+ ```
33
+
34
+ `[tray]` adds the system-tray icon (pystray, pillow); leave it off for a headless
35
+ machine. The command it installs is `cyberext`. Optional on-device training:
36
+
37
+ ```bash
38
+ python -m pip install "cybersecurity-browser-extension-agent[train]" # torch, transformers, peft
39
+ ```
40
+
41
+ Use the same Python for both — the training add-on has to be installed next to the
42
+ agent it extends. From a source checkout, `python -m pip install ".[tray]"` in the
43
+ `agent` folder does the same.
44
+
45
+ Upgrading from the pre-rename package (`phishguard-agent`, command `phishguard`):
46
+ uninstall it first (`python -m pip uninstall phishguard-agent`), then install this one.
47
+ The existing `~/.phishguard` folder — models, training weights, reports, consent — is
48
+ moved to `~/.cyberext` on first start, and `cyberext autostart enable` /
49
+ `cyberext shortcut create` replace the old login entry and shortcuts.
50
+
51
+ `[train]` pulls in PyTorch (~1 GB). Skip it unless you intend to contribute model
52
+ updates — detection does not need it.
53
+
54
+ ## First run
55
+
56
+ ```bash
57
+ cyberext start
58
+ ```
59
+
60
+ No configuration is needed. Models come from the project's model service
61
+ (`fl-api` on Cloud Run), which hands the agent short-lived signed download links;
62
+ the storage bucket itself stays private, and no credentials are ever stored on
63
+ your machine.
64
+
65
+ To point the agent somewhere else (a test server, say), `cyberext configure
66
+ --fl-server-url URL` writes `~/.cyberext/config.json`; `--fl-server-url default`
67
+ returns to the built-in service. Environment variables (`FL_SERVER_URL`,
68
+ `FL_API_KEY`, `CYBEREXT_PORT`, `CYBEREXT_UPDATE_HOURS`) override the file when
69
+ set, but a shell variable is not visible to an agent started at login — anything
70
+ the agent needs unattended belongs in the config file.
71
+
72
+ On the first start the agent downloads the current model version (~375 MB), checks
73
+ each file against the sha256 in the manifest, and only then makes that version
74
+ active. An interrupted download can never leave a half-swapped model in use.
75
+
76
+ Then load the extension and set **Backend → Local (Dev)** in its sidebar.
77
+
78
+ ## Commands
79
+
80
+ | Command | What it does |
81
+ |---|---|
82
+ | `cyberext start` | run the agent (tray icon if `[tray]` is installed) |
83
+ | `cyberext start --no-tray` | run it headless in the terminal |
84
+ | `cyberext status` | is it running, which model version, updater progress |
85
+ | `cyberext update [--force]` | check for new models now |
86
+ | `cyberext where` | print the paths it uses |
87
+ | `cyberext configure ...` | store settings for unattended start |
88
+ | `cyberext autostart enable\|disable\|status` | run at login |
89
+ | `cyberext shortcut create\|remove\|status` | desktop / launcher shortcut |
90
+ | `cyberext fetch-train-weights [--model M]` | PyTorch weights for on-device training (`[train]` extra) |
91
+
92
+ `configure` accepts `--fl-server-url`, `--fl-api-key`, `--port`, `--update-hours`;
93
+ the value `default` clears a setting (an empty `""` works too, except in Windows
94
+ PowerShell 5.1, which silently drops empty arguments). Leave the port at 5000 — that is the only port
95
+ the extension connects to.
96
+
97
+ ### Start at login
98
+
99
+ ```bash
100
+ cyberext autostart enable
101
+ ```
102
+
103
+ Per-user, no services and no admin rights — and `disable` removes exactly what
104
+ `enable` created:
105
+
106
+ | OS | What it writes |
107
+ |---|---|
108
+ | Windows | `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\cyberext-agent.cmd` (launches `pythonw.exe`, no console window) |
109
+ | macOS | `~/Library/LaunchAgents/com.cyberext.agent.plist` (loaded with `launchctl`) |
110
+ | Linux | `$XDG_CONFIG_HOME/autostart/cyberext-agent.desktop` |
111
+
112
+ It starts **with** the tray icon where one is available, falling back to headless
113
+ where it is not: a background process you cannot see or quit is worse than no icon.
114
+
115
+ ### Desktop shortcut
116
+
117
+ ```bash
118
+ cyberext shortcut create
119
+ ```
120
+
121
+ Starts the agent with a double-click, no terminal:
122
+
123
+ | OS | What it creates |
124
+ |---|---|
125
+ | Windows | `Cybersecurity Browser Extension Agent.lnk` on the Desktop and in the Start Menu, running `pythonw.exe` (no console window) |
126
+ | macOS | `~/Applications/Cybersecurity Browser Extension Agent.app` (menu-bar icon only, no Dock tile) + a link on the Desktop |
127
+ | Linux | `cyberext-agent.desktop` in the application launcher, and on the Desktop if there is one |
128
+
129
+ Opening the shortcut while the agent is already running opens its status page
130
+ (`http://127.0.0.1:5000/`) instead of starting a second copy. `shortcut remove` checks
131
+ each file is one it made before deleting it, so a same-named shortcut of your own is
132
+ left alone.
133
+
134
+ ## Tray menu
135
+
136
+ Live status (model version, or download progress), the port it is listening on, a
137
+ manual update check, the *Contribute to model improvement* switch, shortcuts to the
138
+ status page and the data folder, and Quit.
139
+
140
+ An update-check failure while models are installed shows
141
+ `Models 1.1.0 ready (update check failed)` — detection still works, and the menu
142
+ says so rather than implying an outage.
143
+
144
+ ## HTTP API
145
+
146
+ Loopback only; every request is verified to come from `127.0.0.1` before it is
147
+ routed, so a misconfigured proxy or a host-header trick cannot reach it. On Windows the
148
+ port is also held exclusively, so no other program can bind beside the agent and
149
+ intercept what the extension sends. The routes
150
+ match the cloud predict-service exactly, so the extension needs no changes.
151
+
152
+ | Route | Purpose |
153
+ |---|---|
154
+ | `GET /` | human-readable status page (refreshes every 5 s) |
155
+ | `GET /health` | uptime, `models_ready`, `model_version`, `training_available` |
156
+ | `GET /ensemble_status` | which model files are present, updater state |
157
+ | `POST /predict_ensemble` | the full three-branch verdict |
158
+ | `POST /predict`, `POST /batch_predict` | URL-only classification (link scanning) |
159
+ | `GET /reports`, `POST /report`, `/report/update`, `/report/delete` | your local corrections |
160
+ | `POST /model/update`, `GET /model/update_status` | model download |
161
+ | `POST /fusion/report` | scan-panel correction (scores + label; uploaded only with consent) |
162
+ | `GET/POST /fl/consent` | device-owner consent for contributing (+ pending correction count) |
163
+ | `POST /fl_train`, `GET /fl_status` | local training round (needs `[train]` + consent) |
164
+
165
+ ## Where your data lives
166
+
167
+ Everything is under `~/.cyberext` (override with `CYBEREXT_HOME`) — uninstalling
168
+ is a delete:
169
+
170
+ ```
171
+ models/<version>/ the active and previous model versions
172
+ models/current which version is in use
173
+ config.json settings from `cyberext configure`
174
+ reports.json your corrections; kept locally, never uploaded as they are
175
+ contribute.flag present only if you turned on training consent
176
+ agent.log
177
+ ```
178
+
179
+ ## Contributing to model improvement (opt-in)
180
+
181
+ Off by default. Switch it on from the extension's **Federated Learning** page or the
182
+ tray menu (both edit `contribute.flag`). While it is on, the agent sends — anonymously,
183
+ with no URL, page content, or device/account ID:
184
+
185
+ | What | When |
186
+ |---|---|
187
+ | a **scan correction**: the three branch scores + the right label | each time you flag a wrong verdict on the Page Scan panel |
188
+ | 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 |
189
+
190
+ On-device training needs the extra and the base weights:
191
+
192
+ ```bash
193
+ python -m pip install "cybersecurity-browser-extension-agent[train]"
194
+ cyberext fetch-train-weights # ~466 MB; or --model distilbert
195
+ ```
196
+
197
+ A round needs **at least 32 reported URLs** (the model service enforces the same
198
+ floor), and the adapter's total change is **clipped** to a fixed norm before upload.
199
+ Both reduce how much an update can reveal about the reports it came from; neither is a
200
+ formal privacy guarantee. HTML-branch training needs reports with page text, which the
201
+ Report page does not collect yet, so only the URL branch (DistilBERT) trains today.
202
+
203
+ Consent is separate from anything administrative: it authorises training on *your*
204
+ data on *your* machine. Combining updates and publishing a new model version to
205
+ everyone is an administrator's decision, made in the cloud. Adapters trained here are
206
+ never loaded locally — the fleet converges through published versions, otherwise every
207
+ training device drifts onto private weights.
208
+
209
+ ## Troubleshooting
210
+
211
+ **"model server refused the request (HTTP 403)"** — the agent was pointed away from
212
+ the built-in model service (or at an empty URL, which means "read the private bucket
213
+ directly"). Run `cyberext configure --fl-server-url default` and restart it.
214
+
215
+ **"model server unreachable"** — no internet, or the model service is down. Detection
216
+ keeps working with the models already installed; the tray shows
217
+ `Models X ready (update check failed)` until the next successful check.
218
+
219
+ **"models_not_ready" from the extension** — the first download has not finished.
220
+ `cyberext status` shows the percentage.
221
+
222
+ **The extension says the agent is not running, but it is** — check the port. The
223
+ extension only talks to `127.0.0.1:5000`; the status page and tray menu show which port
224
+ the agent is on. If it is anything else, `cyberext configure --port 5000` and restart it.
225
+
226
+ **Port 5000 is taken** — the agent refuses to start rather than share the port (the tray
227
+ icon turns grey and says *not running: port in use*). Find and stop whatever holds it (on Windows:
228
+ `netstat -ano | findstr :5000`). `--port` exists for testing; the extension cannot follow
229
+ the agent to another port.
230
+
231
+ **The tray icon does not appear** — headless Linux, Wayland without an AppIndicator,
232
+ or `[tray]` not installed. The agent still runs; the message says so and it falls
233
+ back to headless.
234
+
235
+ **Windows: a model update seems stuck** — Windows locks open ONNX files. The agent
236
+ releases its sessions before swapping files; if you edited the model folder by hand
237
+ while the agent was running, stop it and start again.
238
+
239
+ ## Uninstall
240
+
241
+ ```bash
242
+ cyberext autostart disable
243
+ cyberext shortcut remove
244
+ python -m pip uninstall cybersecurity-browser-extension-agent
245
+ ```
246
+
247
+ Then delete `~/.cyberext` if you also want the downloaded models gone.