Native Windows service host
This component uses Windows SCM, named pipes and Job objects around the stock Node broker. It does not rebuild Electron/Chromium or modify installed Chrome. It has not been installed or proven as the production network boundary.
Run node scripts/build-windows-service-host.mjs --self-test on Windows with
Visual Studio C++ Build Tools and SDK 10.0.26100.0. The builder uses explicit
compiler/include/library paths, /W4 /WX, static runtime, CFG, ASLR and DEP. Output
and fixed metadata evidence remain under ignored artifacts/native-service-host.
It changes no execution policy, service, firewall, DNS setting or user profile.
The builder accepts --self-test or --compile-only. Compile-only never launches
the executable and writes separate evidence. It bakes a disposable public key, retains
private test keys only in memory, and signs synthetic inventory fixtures after
compilation. It never creates a production release key or registers a service.
The actual negative tests verify: missing SCM service identity, unauthorized client image, oversized frame, wrong file hash, second pipe instance denied by its DACL, and a child plus grandchild retained in a non-breakaway kill-on-close Job and both observed terminal after closing the Job. These are meaningful native component tests; they do not prove an installed SCM or WFP deployment.
The fixed bridge is \\.\pipe\SafetyNet.Broker.v1, local-only, one authenticated
browser connection at a time. An enabled SCM service SID, protected code and
independently pinned deployment material are required before broker launch. The
client is the protected installed helper launched by the protected installed
SafetyNet.exe. Both must have matching medium/high, non-AppContainer user
tokens and sessions. Its process token and impersonated pipe token must agree
on user SID and session. The process handle remains retained and monitored;
client exit terminates the broker Job. The ACL excludes FILE_CREATE_PIPE_INSTANCE
from employee rights. No trust arises from a pipe name or claimed PID in JSON.
Frames are uint32 little-endian length followed by UTF-8 JSON. The first
parent-to-child frame is bounded to 2 MiB; subsequent frames and child responses
are 64 KiB. The constant child receives only inherited stdin/stdout handles and
--service-stdio; stderr goes to NUL. Seven Windows profile/runtime variables
and one fixed OS-derived SAFETYNET_SERVICE_CLIENT_SID are passed. No caller
environment supplies that SID. The Node adapter must validate the existing
v1 generation, monotonic sequence, typed audit/certificate receipts and pinned
service deployment authority. Framing does not authenticate policy or allow a
caller to replace its public key, device identity or version floor.
The --client-stdio mode connects once and authenticates the actual connected
handle's retained server process against signed release hashes, the exact
installed path and an enabled SCM service SID. It never probes and reconnects.
--trust-snapshot requires a service-token helper and a retained signed Node
parent. It returns bounded framed public anchor/SID/registry-floor metadata,
without accepting a registry path or trust key from its caller.
The fixed child entry is resources/broker/apps/network-broker/service-entry.cjs.
The prepared --topology-snapshot helper uses the compiled broker port 43120,
fixed installed browser/broker paths and the real SCM service SID. Service-token,
signed Node-parent and signed user-assignment checks precede its read-only BFE
enumeration. It verifies all eight owned filter keys, actions, conditions,
weights and service descriptor bytes, checks equal-priority collisions and BFE
state, and reports bounded metadata. It never accepts a plan, port or visibility
flag from IPC. The new topology source compiled, but its latest self-test launch
failed with UNKNOWN:spawn; compile-only evidence is separate from earlier
successful native tests. This helper has no installed execution proof yet.
Windows enumerators omit unreadable objects and notifications are asynchronous
and unreliable. Therefore the helper reports allObjectsReadable:false even at
successful EOF. Production admission requires an independently reviewed,
protected deployment prerequisite; token elevation or an ordinary JSON flag
cannot establish it. Ordinary-user enforcement assumes trusted administrators;
user-mode monitoring cannot promise zero packets during hostile privileged
kernel/BFE changes. See Microsoft's access control
and notification contract.
The fixed 64-bit HKLM key SOFTWARE\SafetyNet\Trust contains one canonical
AcceptanceState REG_BINARY value, including release/deployment digests and
sorted per-user policy floors. Missing or corrupt state fails closed. The
snapshot exposes {version, authenticatedSid, releaseAnchor, acceptanceState}.
--commit-acceptance accepts only {expectedPreviousSHA, candidateState},
checks a full monotonic transition under an authenticated fixed mutex, writes
one value, flushes and verifies readback before returning
{persisted:true,stateSha256}. State bytes are capped at 2 MiB minus 1024 bytes;
all stdio frames have a single bounded deadline. The trusted Node gate must
verify the actual signed policy before requesting a commit. Policy digests hash
the original base64url payload string; manifest digests hash canonical decoded
JSON bytes.
The prepared --management-credential command accepts exactly device ID,
canonical HTTPS origin, policy version, policy-key DER SHA256 and the accepted
policy-payload digest. It binds them to the native service-minted user SID,
signed v2 deployment and exact protected acceptance record. Its private reply
contains only the same fields and the token, bounded to 8 KiB. The separate fixed
key SOFTWARE\SafetyNet\ManagementCredentials requires a protected DACL owned
by SYSTEM/administrators, granting access only to them and the exact service SID.
Encrypted records use LocalMachine DPAPI with canonical metadata as entropy;
this is Windows encryption, not a post-quantum storage claim.
Each read first validates the exact current accepted policy request. It then selects the unique highest stored version at or below that request for the same SID, device, origin and policy key. Same-version digest conflicts, ambiguous duplicates and future versions fail closed. Decryption uses the record's own original metadata; the reply echoes the verified current request. Advancing a policy therefore does not require re-encrypting an otherwise valid credential. Provisioning replaces all records for that stable identity and preserves other identities, preventing a new record for every policy revision.
Internal --provision-management-credential additionally requires the previous
encrypted-store SHA256 and token. It uses the same authenticated service role,
serialized mutex, bounded canonical store (256 records/1 MiB), CAS, flush and
readback before returning a receipt. It accepts no registry path, user SID or
key selector. Neither command creates keys or supplies an initial empty store.
No renderer/enrollment provisioning endpoint is exposed. Initial protected
provisioning and actual service-token DPAPI/registry execution remain unproven;
the latest native source has compile-only evidence, not execution evidence.
The mutex uses an OWNER_RIGHTS read-control ACE rather than assuming the service SID can own objects. Actual native tests show owner WRITE_DAC denial while synchronization and modification remain allowed. Commit source is prepared, but no registry write, installed service positive or durable commit has been performed. Current uninstalled snapshot/commit/client tests require exit 5.
signed-manifest.h verifies canonical manifests using Windows CNG P-256/SHA256
and fixed 64-byte IEEE-P1363 signatures. The baked vendor key verifies release
inventory; its delegated customer key verifies deployment and user assignment.
This is a classical release signature, not a post-quantum signature. Actual
native tests verify positive delegation and reject tampering, the wrong customer
key, expiry and equal-sequence digest mismatch. A larger signed inventory tests
real envelope parsing. These fixture tests do not attest installed resource ACLs.
Before deployment, implement and independently verify these remaining gates:
- Actual vendor signing/provisioning and complete final inventory, including every broker, inspector, model and browser resource. The external signature avoids circular browser/host hashes; synthetic fixtures are not a release.
- Installed positive client/server authentication and lifecycle tests; current native negatives cannot prove a correctly provisioned SCM service.
- Protected initial acceptance-state provisioning and an actual service-token CAS/flush/readback proof before listen. Prepared source and uninstalled negative tests do not establish durable installed behavior.
- Real SCM provisioning under a least-privileged service identity, protected resource/state ACLs, actual service-start/stop and bounded I/O timeout tests.
- Per-user signed assignment binding and typed management/inspector/OTLP RPC. Interactive DPAPI audit persistence stays in the authenticated user parent.
- Transactional WFP outbound filters and receiver service-descriptor soft-permit plus lower block in the same owned sublayer, preserving corporate veto.
- Native readback and physical IPv4/IPv6/UDP/DNS/port-takeover tests, including another instance of the same stock Node executable and service crashes.
- Effective WFP hard-permit topology validation and BFE change monitoring; a low-priority sublayer or a static rule inventory cannot prove enforcement. Browser inbound-first IPv4/IPv6 TCP/UDP denies need physical receiver tests.
Until those gates pass, retain existing browser quarantine and enforcement.