Every installer that reaches a managed endpoint passes through hands, shares and consoles that attackers would love to control, and most organisations cannot say who touched a package between the vendor's download page and the device. Allowlisting decides what may run and deployment-tool hardening protects the console, but the packaging chain in between is often a file share, a packager's laptop and a wrapper script running as SYSTEM. This guide covers that chain of custody: sourcing install media, building and signing packages, storing them, publishing them to a self-service portal or package source, and proving that what landed on the device is what was approved. It is written for endpoint engineers, packaging teams and the security staff who review them, with Windows examples from Microsoft documentation because that is where most enterprise packaging happens.
Key takeaways
- Treat the packaging pipeline as a production system. A package runs with SYSTEM rights on thousands of devices, so the share, the build host and the people who can edit it deserve the same controls as a domain controller change.
- Verify at intake, not at install. Check the vendor signature and published hash when media enters the pipeline, record the result, and store the original next to the package.
- Wrapper scripts are the weak link. Install, detection and requirement scripts are code that runs as SYSTEM; sign them, review them and turn on signature checks where the tool offers it.
- Managed installer trust follows the delivery path. If your allowlisting trusts files written by the deployment agent, anything that sneaks into a package inherits that trust.
- Self-service portals and package sources are distribution channels too. Control who can publish, which sources clients may use, and how fast a bad package can be withdrawn.
Where packaging sits between allowlisting and deployment
Three existing controls usually get the attention. Application allowlisting decides what may execute (see the Application Allowlisting Guide). Deployment platform hardening protects the console and its admin roles (see the Microsoft Configuration Manager Security Guide and MITRE ATT&CK T1072 Software Deployment Tools). Vendor code signing protects the binary itself (see the Code Signing Security Guide). The gap is the internal work done between them: downloading media, repackaging, adding transforms and wrapper scripts, uploading, assigning and publishing.
That gap matters because a deployment platform does what it is told. If a packager's account or a source share is compromised, the attacker does not need to touch the console's admin roles; they modify content the console will faithfully push. MITRE ATT&CK describes both halves of this: T1072 Software Deployment Tools for abuse of the distribution system and T1195.002 Compromise Software Supply Chain for manipulation of software before the consumer receives it.
| Pipeline stage | What can go wrong | Control to put in place |
|---|---|---|
| Media sourcing | Installer pulled from a mirror, a search result or an old copy on a share | Download only from the vendor's own channel; verify signature and hash; log source URL and date |
| Packaging and wrapping | Edited transforms, wrapper scripts or bundled config files carry unreviewed changes | Source control for scripts and transforms; peer review; signed scripts |
| Content storage | Writable source share lets anyone with access swap a file before upload or redistribution | Read-only content library for consumers; write access limited to the build identity |
| Upload and assignment | Package assigned to all devices without test; wrong version superseded | Ring-based assignment; approval before broad deployment; multi-admin approval where available |
| Self-service publication | Portal or package source offers unvetted titles or an untrusted source | Curated catalogue; restricted source list; owner per title |
| Endpoint execution | Installer runs as SYSTEM and spawns updaters or post-install launchers | Detection rules that reflect the real install; no auto-launch during install; allowlisting in force |
Sourcing install media you can vouch for
The chain of custody starts with the first download. Most repackaging incidents begin with an installer nobody can trace: a copy found on a team share, a build sent by email, or a file from a download aggregator.
- Vendor channel only: Record the exact vendor URL, portal or licensing site used. Where the vendor publishes hashes, compare them and record the match.
- Signature check: On Windows,
signtool verify /pa /allverifies all signatures in a file with multiple signatures using the Default Authentication Verification Policy. Record the signer subject so you can spot a change of signer on the next release. - Provenance where it exists: For software published with build provenance, the SLSA specification (v1.2, Approved) recommends that consumers compare provenance against expected values for at least the builder identity, canonical source repository,
buildTypeandexternalParameters. Developer tools and open source agents increasingly ship this way. - Quarantine before use: Scan new media in an isolated intake area and hold it until checks pass. Unsigned media should need a named exception with an owner, not silent acceptance.
- Keep the original: Store the untouched vendor file, its hash and the intake record beside the package so any later investigation can compare what you received with what you shipped.
Our recommendation at NHI Mgmt Group: make the intake record a required field in the packaging request, so a package cannot move to test without a source URL, hash, signer and date.
Building packages: wrappers, transforms and signing
Repackaging adds code. A Win32 app in Intune, for example, is built with the Win32 Content Prep Tool (IntuneWinAppUtil.exe), which zips everything in the setup folder into an .intunewin file. Microsoft's documentation warns to keep the tool separate from the installer folder because it captures all files and subfolders, which is also a reminder that stray files on a packager's workstation can end up inside a package.
Scripts that run with high privilege
Intune Win32 apps can use a custom detection script and script-based requirement rules, and the install can run in System or User context. Both the requirement script and the custom detection script offer an Enforce script signature check setting; when set to Yes the script must carry a trusted publisher signature, and the default is No. Turn it on and sign these scripts with an internal code signing certificate held by the build service, not by individual packagers.
Signed package formats
Some formats force signing. Microsoft states that Windows requires MSIX packages to be signed with a valid code signing certificate that chains to a trusted root on the device, and that timestamping is highly recommended because an expired, timestamped signature still installs while an expired, untimestamped one fails. For bundles only the bundle needs signing. Use the MSIX uap10:PackageIntegrity declaration with content enforcement on where you need Windows to enforce package integrity for non-Store packages.
Version control and review
- Everything in source control: Wrapper scripts, MST transforms, response files, detection logic and the package definition live in a repository with branch protection, not on a shared drive.
- Two-person rule for production: A second packager or engineer reviews the diff before a package is promoted beyond the test ring.
- Reproducible builds: Build packages on a dedicated build host or pipeline from the repository and the intake copy, so the output can be rebuilt and compared.
- No secrets inside packages: Licence keys, service account passwords and API tokens embedded in scripts or config files ship to every device. Use the vendor's licensing service, a device-scoped credential, or retrieve secrets at run time. See the Secrets in Container Images and Build Artefacts Guide.
Content libraries, shares and the managed installer effect
Package content has to sit somewhere before and after upload: a source share for Configuration Manager, a staging folder for Intune uploads, a REST source for WinGet. Whoever can write to that location can change what gets deployed.
| Location | Who should write | Who should read | Monitoring |
|---|---|---|---|
| Intake quarantine | Packaging team intake role | Scanning service, packaging team | New file events, failed signature checks |
| Source content share | Build pipeline identity only | Deployment site servers, distribution points | File modification and permission changes on the share |
| Packaging repository | Packagers through reviewed merges | Packaging team, auditors | Direct pushes, force pushes, branch protection changes |
| Internal package source | Publishing pipeline only | Managed clients | New or changed manifests, source configuration changes |
Allowlisting raises the stakes. Microsoft's App Control for Business can trust software delivered by a managed installer: the deployment agent (for example the Configuration Manager client or the Intune Management Extension) is designated through an AppLocker ManagedInstaller rule collection, and files it and its child processes write are tagged with an origin claim that App Control then allows (policy option 13, Enabled:Managed Installer). Microsoft describes this as a heuristic with weaker guarantees than explicit rules. In practice it means a tampered package is not only deployed but also pre-authorised. Microsoft also advises configuring deployments so installers do not auto-launch the application, because a launched app can extend authorisation to files it creates on first run. Event IDs 3090, 3091 and 3092 record allowed, audited and blocked decisions based on origin.
Self-service portals and package sources
Self-service changes who pulls the trigger, not who is responsible for the content. Company Portal style catalogues, software centres and package managers let users install approved titles on demand, so the catalogue is effectively a pre-approved allowlist.
- Curate, do not mirror: Each title in the portal has a named owner, a licence position and a review date. Retire titles nobody owns.
- Control package manager sources: WinGet ships with the
msstore,wingetandwinget-fontsources by default. Adding, removing or resetting sources needs administrator rights, andwinget source exportproduces the JSON Microsoft suggests using when configuring Group Policy for source management. Decide whether managed devices may use the community repository, the Store source, an internal REST source, or a combination, and enforce that centrally. - Internal sources are publishing systems: A private REST source or repository needs the same write controls as the content share. See the Private Package Repository and Proxy Guide and, for Linux, the Linux Package Signing and Repository Trust Guide.
- Fast withdrawal: Know in advance how to unpublish a title, stop assignments and trigger uninstall. Write it down as a runbook and test it.
Choosing a distribution approach
| Approach | Fits when | Chain of custody trade-off |
|---|---|---|
| Vendor-signed MSI or MSIX deployed unmodified | The vendor provides a usable enterprise installer | Strongest: the vendor signature covers what lands on the device; you control only parameters |
| Repackaged or wrapped installer | Silent install needs transforms, prerequisites or clean-up | Your scripts become part of the trusted code; sign and review them |
| Package manager from a public source | Large catalogue of common tools, small team | You rely on the source's own review; restrict sources and pin versions for sensitive groups |
| Internal package source or catalogue | You want package manager convenience with your own review | You own publishing security, signing and withdrawal |
| Vendor self-update | Fast-moving browsers and agents | Updates bypass your pipeline; managed installer tagging may not cover updated files, so add explicit publisher rules |
Small organisations: Prefer vendor-signed installers deployed unmodified, a short curated catalogue and a single packaging owner with a reviewer from IT. Large organisations: Build a packaging pipeline with a build service identity, signed scripts, ring assignments and a separate approver role, and integrate package records with the asset inventory (see the Asset Inventory and CMDB Security Guide).
Where identity fits
Three identities hold the keys to this pipeline. The build service identity writes to content shares and uploads packages; it is a non-human identity with deployment-grade privilege and should be scoped to those actions, use short-lived or certificate-based credentials and be monitored like an admin. The signing identity that signs scripts and internal packages belongs in an HSM or managed signing service with approval gates. The human packagers and approvers need separate roles, MFA and, where the platform offers it, multi-admin approval for changes that reach all devices. Microsoft notes that when Intune Multi-Admin Approval is enabled, PowerShell scripts cannot be uploaded during app creation, which is a useful forcing function for a reviewed path. See the Service Account Security Guide.
How to implement
- Map the current chain. List every place install media and packages live, every account that can write there, and every console role that can assign. Expect to find personal shares and old service accounts.
- Lock down storage first. Make source shares read-only for everyone except a build identity; move packagers to a repository plus pipeline. Keep a copy of the old permissions for rollback.
- Introduce intake records. Require source URL, hash, signer and date for every new title and version. Start with new packages, then backfill the top 50 deployed titles.
- Sign scripts and turn on checks. Issue an internal script signing certificate to the build service, sign detection and requirement scripts, then set Enforce script signature check to Yes on a pilot set of apps.
- Introduce rings. Assign every new version to a packaging test group, then a pilot ring, then broad deployment, with an approval step between pilot and broad.
- Restrict self-service sources. Decide the allowed package sources and catalogue titles, enforce them centrally, and remove unowned titles.
- Test withdrawal. Run a tabletop and a live drill that pulls a package from all rings and the portal within your target time.
- Roll back safely. If signature enforcement breaks installs, revert the setting per app rather than globally, and fix the signing step. Keep the previous package version available for supersedence rollback.
Detection and measurement
- Content changes: Alert on file writes and permission changes to source shares and internal package sources by anyone other than the build identity.
- Assignment changes: Alert when an app is assigned to all devices or all users, or when a package is modified after approval. Review deployment platform audit logs weekly.
- Signer drift: Compare each new version's signer with the previous version; a changed or missing signer needs a human decision.
- Origin events: Watch App Control events 3091 and 3092 to find software arriving outside the managed path.
| Metric | Target (ours) |
|---|---|
| Deployed packages with a complete intake record | 100% of new versions, 90% of the estate within 6 months |
| Wrapper and detection scripts signed with signature checks on | 95% or more |
| Accounts with write access to package content | Build identities plus a named break-glass, reviewed quarterly |
| Packages promoted without pilot ring | Zero, except recorded emergency changes |
| Time to withdraw a package from all channels | Under 1 hour in drills |
Common failure patterns
- The everyone-writes share: A content share inherited broad modify rights years ago, so any IT account can replace an installer that is about to be redistributed.
- Credentials baked into packages: A wrapper script holds a local admin or service account password in plain text and is cached on every endpoint.
- Unsigned SYSTEM scripts: Detection and requirement scripts run unsigned because the default was left in place.
- Auto-launch after install: The installer starts the app as part of deployment, so managed installer trust spreads to files the app writes on first run.
- Unowned self-service titles: Old versions stay in the catalogue long after the vendor stops patching them.
- Signer change ignored: A new release is signed by a different entity and nobody asks why before packaging it.
Framework mapping
| Framework | Reference | How this guide applies it |
|---|---|---|
| NIST SP 800-53 Rev. 5 | CM-14 Signed Components; SI-7 Software, Firmware, and Information Integrity; SI-7(15) Code Authentication | Signature checks at intake and on scripts |
| NIST SP 800-53 Rev. 5 | SR-4 Provenance; SR-11 Component Authenticity | Intake records, provenance verification |
| NIST SP 800-53 Rev. 5 | CM-3 Configuration Change Control; CM-7(5) Authorized Software, Allow-by-exception; CM-11 User-installed Software | Ring approvals, curated self-service |
| NIST CSF 2.0 | ID.AM-02; PR.PS-01; PR.PS-02 | Software inventory, configuration management, maintained software |
| NIST SP 800-218 (SSDF) | PS.2 Provide a mechanism for verifying software release integrity; PS.3 Archive and protect each software release | Applied to internal packages as if you were the producer |
| MITRE ATT&CK | T1072 Software Deployment Tools; T1195.002 Compromise Software Supply Chain; T1553.002 Code Signing | Threats the pipeline controls address |
| ISO/IEC 27001:2022 | Annex A control on installing software on operational systems | Controlled installation path |
Practitioner checklist
- Record source URL, hash, signer and date for every package version.
- Make content shares and package sources writable only by a build identity.
- Keep wrapper scripts, transforms and detection logic in source control with review.
- Sign scripts and set Enforce script signature check to Yes where offered.
- Remove secrets from packages and retrieve them at run time instead.
- Deploy through test, pilot and broad rings with an approval step.
- Stop installers auto-launching apps when a managed installer is trusted.
- Restrict package manager sources and curate self-service titles with owners.
- Drill package withdrawal and measure the time taken.
Standards and references
- NIST: SP 800-218 Secure Software Development Framework (SSDF) Version 1.1
- NIST: SP 800-53 Rev. 5
- SLSA: Build, Verifying artifacts (v1.2)
- MITRE ATT&CK: Software Deployment Tools
- Microsoft: Allow apps deployed with a managed installer
- Microsoft: Add and assign Win32 apps to Intune
- Microsoft: Sign an MSIX package overview
- Microsoft: winget source command
Related NHI Mgmt Group resources: Application Allowlisting Guide · Code Signing Security Guide · Microsoft Configuration Manager Security Guide · Private Package Repository and Proxy Guide