Skip to content

P1 windows release: consume promoted OpenPath installer fixes and prove generated ClassroomPath EXE end-to-end #165

Description

@balejosg

Severity

P1 downstream rollout / security verification

Summary

On 2026-09-03 a Windows installer generated through ClassroomPath was new as a personalized .exe, but its embedded OpenPath Windows template came from the last exact promoted OpenPath contract (a3846d6cbbb5c816d12dc4c5a60409760e121b90, release scripts-v4.1.0-a3846d6c, 2026-08-30).

That template predates the Firefox discovery fix OpenPath #246 and also predates the fixes that will be produced for the newly discovered AppLocker/watchdog fail-open incident.

This is not a reason to resolve OpenPath main dynamically. ClassroomPath must continue consuming one exact immutable OpenPath Promotion Contract v2 as established by #160.

This issue owns the downstream step after OpenPath publishes a corrected contract.

Blocked by:

Upstream security fixes/evidence feeding #255:

  • OpenPath #253 — installer cannot leave AppLocker/watchdog absent while config says Enforced;
  • OpenPath #186 — health/recovery must reflect missing AppControl/watchdog;
  • OpenPath #246 — Firefox Release discovery source fix;
  • OpenPath #254 — strict Firefox-only allowlist hardening (may land in the same or a subsequent promoted release according to upstream security decision).

Related ClassroomPath release architecture:


Incident evidence

The generated installer installed OpenPath files with timestamps matching the 2026-08-30 template:

C:\OpenPath\lib\AppControl.psm1               8/30/2026 11:17:06 PM
C:\OpenPath\lib\internal\Watchdog.Runtime.ps1 8/30/2026 11:17:06 PM

The machine then showed:

config enableNonAdminAppControl = true
mode = Enforced
approved browser = Firefox

OpenPath-Restricted = absent
OpenPath-* scheduled tasks = absent
AppLocker Local = empty
AppLocker Effective = empty
portable EXE = AllowedByDefault
Edge = launches

OpenPath installation log also reproduced the pre-#246 Firefox detection symptom:

Firefox machine ExtensionSettings policy written ...
WARN Firefox not detected; network autoconfig skipped
=== OpenPath update completed successfully ===

The OpenPath installer phase ordering then allows Firefox readiness failure before scheduled-tasks and app-control; root fix is upstream #253.


Core downstream invariant

ClassroomPath may only claim the Windows installer fix shipped when the exact OpenPath contract embedded in the active ClassroomPath Release Bundle points to a physically verified Windows template containing the fixes, and a .exe generated through the live ClassroomPath path has been installed/tested successfully.

Required identity chain:

ClassroomPath source SHA
-> exact OpenPath submodule SHA
-> exact OpenPath Promotion Contract v2 bytes
-> contract SHA256
-> windowsOfflineInstaller.sourceSha
-> releaseTag
-> templateSha256
-> ClassroomPath Release Bundle releaseId
-> provisioned exact template
-> generated personalized EXE
-> real Windows installed bytes/runtime

No step may substitute latest, OpenPath main, a current release tag, or a recomputed pin.


Implementation / rollout instructions for an LLM agent

Phase 0 — read contracts before changing anything

  1. Read ClassroomPath root AGENTS.md completely.
  2. Read refactor(release): consume exact OpenPath contract and promote immutable release bundles #160 completion/current implementation.
  3. Read hardening(release): make production promotion and rollback hermetic and operationally provable #162 but do not mix its production-executor work into this ticket.
  4. Read upstream OpenPath #255 completion report and exact published v2 contract.
  5. Inspect:
    • scripts/resolve-openpath-promotion-contract.mjs;
    • release bundle builder/parser;
    • scripts/resolve-windows-offline-installer-template-pin.mjs in its current verifier/projection role;
    • template provisioning code;
    • Windows installer generation service/API;
    • Windows installer canary;
    • RC/staging Windows evidence;
    • production bundle/runtime projection.
  6. Do not edit upstream/openpath/ from ClassroomPath.
  7. Do not deploy staging/production, create tags, or promote without separate explicit authorization.

Phase 1 — update only to an exact promoted OpenPath SHA

After #255 publishes its contract:

S = exact promoted OpenPath SHA from #255

Update the OpenPath submodule only to S.

Then require exact retrieval of:

promotion-contracts/v2/S.json

Assert:

contract.openpathSha == S
contract.components.windowsOfflineInstaller matches #255 completion identity

A missing exact contract must fail. Do not search ancestors or choose a previous template.

Phase 2 — prove release bundle projection

The ClassroomPath RC/release bundle must contain the exact contract bytes/hash and project the Windows tuple without independent selection:

windows_offline_installer_template_version
windows_offline_installer_template_commit/sourceSha
windows_offline_installer_template_release_tag
windows_offline_installer_template_sha256
payload manifest identity where exposed

Add/extend tests that fail if the active release bundle can carry an OpenPath SHA/contract while projecting a different Windows template identity.

Phase 3 — provision exact template atomically

Provision from the contract only.

Verify before publish/use:

release tag exact
template sidecar exact
template bytes SHA256 exact
payload manifest exact

Do not destroy a known-good current template before the replacement is fully verified.

Readiness must fail if the required release bundle points to a template that is absent/corrupt/wrong generation.

Phase 4 — generated EXE provenance test

Generate a personalized Windows installer through the same ClassroomPath service/API/UI path used by users.

Do not test only the generic OpenPath template file.

Prove that the resulting personalized EXE was produced from the exact provisioned template. Use the canonical trailer/overlay parser and template identity checks; do not infer from file modification timestamps.

Safe test/evidence should include:

ClassroomPath releaseId
OpenPath SHA
OpenPath contract SHA256
Windows template source SHA
releaseTag
template SHA256
generated EXE SHA256

Never include enrollment tokens, raw download refs, Authorization/Cookie values, or personalized trailer secrets.

Phase 5 — real Windows end-to-end

Install the exact generated .exe on a clean/supported Windows test endpoint.

Required proof after successful installation:

Firefox regression

normal Firefox Release discovered
no false firefox-release-missing
managed extension readiness passes

AppControl lifecycle

OpenPath-Watchdog task exists
required restricted targeting state exists
AppIDSvc running
Get-AppLockerPolicy -Effective has required enforced collections

Runtime boundary

Under a local standard student account:

Firefox -> allowed
Edge -> denied
portable arbitrary PE in Downloads -> denied

If upstream #254 is included in this promoted release, also run its unknown-browser/strict-allowlist adversarial probes.

Health

healthy after valid install

Then deliberately break/remove effective AppLocker in the disposable test endpoint and prove health no longer reports healthy, as required by OpenPath #186.

Phase 6 — staging evidence (only when explicitly authorized)

A staging deployment must consume the exact RC bundle produced above.

Prove:

live RELEASE_ID == selected releaseId
live OPENPATH_SHA == bundle OpenPath SHA
live contract SHA == bundle contract SHA
provisioned template SHA == contract template SHA
ClassroomPath-generated EXE canary uses that template

Do not claim staging proof without actually running it.

Phase 7 — production promotion (only when explicitly authorized)

Use #160/#162 release semantics:

promote exact staged releaseId
no rebuild
no OpenPath re-resolution
no current/latest template lookup

Production completion requires safe evidence that a live generated Windows installer is backed by the intended contract/template identity. A full destructive Windows reinstall in production is not required if product policy uses staging/canary machines for runtime proof, but the production service/template identity must match the release proven in staging.


Provenance/diagnostic improvement

The incident was harder to diagnose because config.json had a blank agentVersion and file timestamps were used as a clue.

Add the smallest safe operator-visible provenance necessary to answer:

Which OpenPath Windows component produced this installed endpoint?

Prefer immutable identities already present in the promotion contract/payload manifest, for example:

OpenPath source SHA
Windows template source SHA/release tag

Do not duplicate release selection logic in the endpoint. Do not treat filesystem timestamps as provenance.

If this belongs upstream in OpenPath rather than ClassroomPath, create/link the upstream follow-up and only consume/display the canonical value here.


Tests required

Contract / bundle

  • exact submodule SHA requires exact v2 contract;
  • wrong/missing contract fails;
  • Windows template projection equals contract component exactly;
  • contract hash is preserved in release bundle;
  • no previous-pin fallback can authorize the RC.

Provisioning

  • wrong releaseTag fails;
  • sidecar mismatch fails;
  • template bytes mismatch fails;
  • payload manifest mismatch fails;
  • atomic replacement preserves previous valid generation on failure.

Generation

  • personalized EXE is based on exact provisioned template;
  • generated EXE hash recorded safely;
  • fresh generation semantics remain intact;
  • no secret provenance/evidence leak.

Windows E2E

  • #246 Firefox regression;
  • #253 watchdog/AppLocker install invariant;
  • Edge denied;
  • arbitrary portable PE denied;
  • Firefox allowed;
  • #186 health negative test.

Release regression

Add a test/gate that makes it impossible to report a ClassroomPath Windows canary as proving a fix for an OpenPath SHA different from the exact openpathSha + contract hash + template identity in the selected releaseId.


Acceptance criteria

  • Blocked until OpenPath #255 publishes a corrected exact v2 contract.
  • ClassroomPath submodule updates to that exact promoted SHA, not an arbitrary later main.
  • Exact v2 contract exists and validates for the submodule SHA.
  • Release Bundle contains the exact contract hash and source SHA.
  • Windows runtime projection comes only from the contract.
  • Exact new template is provisioned and SHA-verified.
  • Personalized EXE generation proves it uses that exact template.
  • Real Windows install no longer reproduces #246.
  • Real Windows install satisfies #253 AppLocker/watchdog invariant.
  • Edge is denied for standard student when Firefox-only.
  • Portable arbitrary EXE is denied.
  • Firefox is allowed.
  • Broken effective AppLocker makes health non-healthy per #186.
  • Safe provenance can identify the OpenPath/Windows component without relying on timestamps.
  • Required ClassroomPath tests pass.
  • Staging/production evidence is claimed only after explicit authorization and actual execution.
  • Production, when eventually promoted, uses the exact releaseId proven in staging with no OpenPath/template re-resolution.

Non-goals

  • Do not make ClassroomPath consume OpenPath main/latest.
  • Do not recreate OpenPath component selection in ClassroomPath.
  • Do not patch OpenPath source from this repo.
  • Do not weaken immutable Release Bundle v2.
  • Do not deploy or tag without explicit authorization.

Completion report

Report separately:

  1. CONSUMED — exact OpenPath SHA/contract/template identity in ClassroomPath RC;
  2. WINDOWS PROVEN — exact generated EXE + real Windows results;
  3. STAGING SHIPPED — only if authorized and executed;
  4. PRODUCTION SHIPPED — only if authorized and executed.

Do not collapse these states into a generic "fixed".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions