Repository navigation
Add operator-marked trusted scanners (#64) - #77
Merged
Merged
Conversation
Operator tests and legitimate LAN scanners trip decoys and produce High
alerts identical to an intrusion, which trains people to stop reading
alerts. This adds a per-device trusted_scanner flag the operator sets in
the device detail view. Decoy trips from a trusted scanner are still
recorded in the forensic log and still count toward the decoy's
connection total, but they neither create nor feed Decoy Trip alerts.
Credential trips stay Critical regardless of the flag.
Sensor:
- Schema v13 adds devices.trusted_scanner (INTEGER NOT NULL DEFAULT 0),
with an idempotent migration for existing databases.
- /devices and /devices/{id} return trusted_scanner; PUT /devices/{id}
accepts it. Device WebSocket payloads carry it too.
- DecoyAlertHandler reads the flag at event time, so flipping it in the
app takes effect on the next connection in either direction.
App:
- DeviceSummary/DeviceDetail decode trusted_scanner as an optional so a
pre-v13 sensor still decodes; isTrustedScanner is the read surface.
- Device detail gains a Mark/Unmark Trusted Scanner action and a header
badge. Every DeviceSummary reconstruction carries the flag so a
presence flip or trust change does not clear it.
Deception integrity: control surface only. The decoy's response to a
trusted device is unchanged, so a compromised trusted device cannot
detect that it is trusted.
The v12 campaign test pinned SCHEMA_VERSION == 12; it now asserts the
v12 row exists and the version is at least 12.
mattmacrocket
force-pushed
the
feature/trusted-scanners
branch
from
October 18, 2026 04:26
57b81b6 to
8fb5f2d
Compare
chrissyrocket
previously approved these changes
Oct 18, 2026
# Conflicts: # docs/USER_GUIDE.md # sensor/tests/integration/test_decoy_alert_handler.py
…eature/trusted-scanners
chrissyrocket
approved these changes
Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #64.
What
A per-device trusted scanner flag, set from the device detail view. Decoy trips from a trusted scanner are kept as forensic evidence and still count toward the decoy's connection total, but they neither create nor feed Decoy Trip alerts. Credential trips stay Critical regardless of the flag. The flag is independent of trust status.
Sensor
devices.trusted_scanner INTEGER NOT NULL DEFAULT 0, idempotent_apply_v13for existing databases.GET /devices,GET /devices/{id}returntrusted_scanner;PUT /devices/{id}accepts it. Device WebSocket payloads carry it.DecoyAlertHandler._is_trusted_scannerreads the flag at event time (not cached), so toggling in the app takes effect on the next connection in either direction. The branch sits after the discovery-probe check and before the credential branch, so credential use never reaches it.App
DeviceSummary/DeviceDetaildecodetrusted_scannerasBool?so a pre-v13 sensor still decodes;isTrustedScanneris the read surface.DeviceUpdateRequest.trustedScanner(trusted_scanner), nil leaves the sensor value unchanged.DeviceSummaryreconstructions (presence flips inWSEventProcessorandAppState, save edits, trust changes) carry the flag so none of them clears it.Deception integrity
Control surface only. Nothing under
decoys/orscouts/changes; the decoy's response to a trusted device is byte-identical to its response to anyone else, so a compromised trusted device cannot detect that it is trusted.Tests
Red first, then green:
TestMigrationV13(default false on fresh DB; applies to a v12 DB and is idempotent)TestTrustedScannerintest_routes_devices.py(list/detail expose it, PUT sets and clears it)TestTrustedScannerintest_decoy_alert_handler.py(trip is evidence without an alert and counters still increment; credential use is still Critical; marking a source trusted stops feeding its open alert; untrusted device still alerts)DeviceSummarydecodes with and without the key;updateDeviceencodes onlytrusted_scannerwhen that is all that changedtest_schema_v12_adds_campaign_tablepinnedSCHEMA_VERSION == 12; it now asserts the v12 row exists and the version is at least 12.Full runs: sensor
pytest2539 passed, 6 skipped;ruff checkclean;swift test160 passed across both targets.Docs
docs/USER_GUIDE.md: new action under Device Detail View, and the Decoy Trip row notes trusted-scanner activity is retained without an alert.