Get GE-Enforce closer to running on credential-less Intune/Entra display PCs that pull manifest + payloads over HTTPS instead of SMB. Server (plugins/geenforce/api/routes.py): - Rate-limit + 512MB served-size ceiling on GET /payload/<sha256> (reuses the login limiter's cache pattern, config-overridable via GEENFORCE_PAYLOAD_*). - New tests: payload hardening, manifestblobs model-vs-migration parity, and a report-contract test locking the lowercase per-entry report keys. PS client (plugins/geenforce/client/): - Fix New-ShopdbReport per-entry key casing to lowercase (name/action/selfhealed/ exitcode/message) to match what the server reads; the engine emits PascalCase. - Enforce TLS 1.2 in the network functions. - Fetch + merge the fleet-wide common scope alongside the pctype scope (pctype wins on conflict; -NoCommon opt-out). - Normalize whatever the engine returns into a well-formed summary. - Make the empty-cache fail-safe observable: event-log entry + report ping instead of a silent exit 0. Manifest (plugins/geenforce/seed_display_scope.py + docs/GE-ENFORCE-DISPLAY.md): - Seed a gea-shopfloor-display scope: 4 Edge kiosk drift-heal registry entries + 1 data-driven dispatcher (Dashboard/Lobby/3DPrintRoom via display-type.txt). Kiosk EXEs stay image-baked; the manifest heals policy/config drift only. - Documents the common SMB-payload audit (entries needing http/inline before a share-less display can inherit common). Migration registry (shopdb/plugins/alembic_template.py + test): - Register the pre-existing manifestblobs and the new printersupplyalerts tables in PLUGIN_TABLE_OWNERS; update EXPECTED_HEAD_REVISION for geenforce (0002blobs), printers (0002supplyalerts), and printedparts (0004txnrev) which had drifted.
6.3 KiB
GE-Enforce: the gea-shopfloor-display scope
Displays are the share-less corner of the fleet. They are Intune/Entra-joined,
credential-less kiosk PCs that pull their manifest over HTTPS on port 443 and
authenticate with a read-only service PAT scoped geenforce.fetch, sent as
X-API-Key. They have no SMB share mount. The kiosk engine and the kiosk
browser are baked into the display image, not shipped over HTTPS, so the display
manifest heals POLICY / CONFIG drift and inherited common entries, never EXEs.
There are three display subtypes, selected by C:\Enrollment\display-type.txt:
Dashboard, Lobby, and 3DPrintRoom.
Authoring the scope
The scope is authored programmatically by
plugins/geenforce/seed_display_scope.py, which builds a manifest dict and
hands it to service.replace_scope_draft (the same call the import-share CLI
uses), then attaches the inline dispatcher payload. From a Flask app context:
from plugins.geenforce.seed_display_scope import seed_display_scope
seed_display_scope(publish=True) # publish=False leaves it as a draft
replace_scope_draft is an idempotent draft rebuild. publish=True additionally
freezes an immutable published snapshot (that step is not idempotent: it always
creates a new version).
What the scope contains
- Four
Registrydrift-heal entries that re-assert the Microsoft Edge kiosk relaunch policies set at imaging by09-Setup-Display.ps1. Each writes the value and detects drift withDetectionMethod = ValueMatchesagainst the same path/name, so a display that loses a policy self-heals on the next enforce cycle with no keyboard or mouse on site:RelaunchNotification = 2(DWord, Required auto-restart)RelaunchNotificationPeriod = 3600000(DWord, 1 hour)RelaunchHeadsUpPeriod = 60000(DWord, 1 minute)RelaunchWindow(String, JSON, 02:00 start, 120 minute duration)
- One
PS1dispatcher, delivered inline over HTTPS. It readsC:\Enrollment\display-type.txtand launches the kiosk target for the subtype. The subtype -> route map is a data-driven table (DISPLAY_TYPE_TARGETS) at the top of both the seed module and the generated script, so targets are easy to edit.DetectionMethod = Alwaysso it re-asserts each cycle, but the script is idempotent (it skips relaunch if a kiosk process is already serving the target URL).
display-type -> target map
| display-type.txt | kiosk route | notes |
|---|---|---|
Dashboard |
/shopfloor |
core ShopfloorDashboard, standalone full-screen |
Lobby |
/tv |
slides plugin TV dashboard (surface lobby) |
3DPrintRoom |
/parts-kiosk |
PLACEHOLDER, TODO-confirm printedparts parts kiosk route; confirm the real 3D-print-room target with the floor team before publishing to production displays |
Inheritance: the client merges common
The manifest model has no inheritance column. The display scope is a plain
(non-common) runtime scope carrying only display-specific entries. The CLIENT
merges the fleet-wide common scope underneath the display scope at fetch time.
So common is where the fleet-wide policy/config/self-update entries live, and
gea-shopfloor-display adds the kiosk-only entries on top.
Blocker: common carries SMB payloads that break on share-less displays
Before a share-less display can safely inherit common, every common entry
that pulls a payload file from the SMB share must first be given an http or
inline payload (with a payloadsha256). A display has no share mount, so any
inherited entry whose Installer / Source / Script resolves to a
share-relative path will fail its fetch.
Registry entries in common carry no payload (they write inline reg values) and
are safe to inherit as-is. The entries below reference a share file and must be
converted first. This audit is the authoritative to-convert list; the payload
bytes themselves are not converted here (that needs the real payload files).
Common entries that reference an SMB/share payload (as of the on-share
common/manifest.json, 22 entries, Version 2.0):
| # | Common entry | Type | Share payload | Field |
|---|---|---|---|---|
| 1 | Adobe Acrobat Reader DC | CMD | scripts/Install-AcroReader.cmd |
Installer |
| 2 | Migrate pc-type.txt to gea-shopfloor-* taxonomy | PS1 | scripts/Migrate-PCType.ps1 |
Script |
| 3 | WJF Defect Tracker | MSI | apps/WJF_Defect_Tracker.msi |
Installer |
| 4 | 3OF9 barcode font | File | configs/3OF9.ttf |
Source |
| 5 | Edge IE-Mode site list | File | configs/enterprise-mode-site-list.xml |
Source |
| 6 | Ensure VNC firewall rule | PS1 | scripts/ensure-vnc-firewall.ps1 |
Script |
| 7 | FMS hosts pin (WJFMS3.AE.GE.COM) | PS1 | scripts/Set-FmsHostsEntry.ps1 |
Script |
| 8 | Oracle Client 11.2 | CMD | scripts/Install-Oracle11r2.cmd |
Installer |
| 9 | PrinterInstallerMap (site-map printer installer) | File | apps/PrinterInstallerMap.exe |
Source |
| 10 | OpenText HostExplorer ShopFloor | CMD | scripts/Setup-OpenText.cmd |
Installer |
| 11 | GE-Enforce dispatcher (self-update) | File | GE-Enforce.ps1 |
Source |
| 12 | Install-FromManifest lib (self-update) | File | lib/Install-FromManifest.ps1 |
Source |
| 13 | Report asset (host + IP + machine number) to ShopDB | PS1 | apps/Report-AssetToShopDB.ps1 |
Script |
| 14 | EventSaver screensaver (binary) | File | apps/EventSaver.scr |
Source |
| 15 | EventSaver screensaver (config) | File | configs/EventSaver.ini |
Source |
| 16 | EventSaver enable (per-user screensaver) | PS1 | scripts/Set-EventSaverScreensaver.ps1 |
Script |
| 17 | EventSaver power (keep monitor awake) | PS1 | scripts/Set-EventSaverPower.ps1 |
Script |
| 18 | EventSaver disable (measuring-tool bays) | PS1 | scripts/Set-EventSaverDisable.ps1 |
Script |
| 19 | EventSaver disable (specific hostnames) | PS1 | scripts/Set-EventSaverDisable.ps1 |
Script |
Safe to inherit as-is (Registry entries, no share payload): 3OF9 barcode font registry entry, Edge IE-Mode policy level, Edge IE-Mode policy site list pointer.
Not every entry above is relevant to a display (a display needs no Oracle
client, OpenText, or Defect Tracker), so a follow-up decision is which common
entries a display should actually run (via PCTypes targeting) versus which
must be repackaged as http/inline. But any that survive targeting must have
a non-SMB payload before displays inherit common.