Turn off the public source. Properly.
A private winget repository is worth nothing while endpoints can still reach the public community source and the Microsoft Store source. Here are the exact Group Policy values that close it — including the one most write-ups get wrong.
Verified on Windows 11 22H2 · winget 1.8.1911 · isolated VM, not inferred from docs
An allowlist does not block the public source.
This is the failure we most want you to avoid, because it looks like success. EnableAllowedSources governs additional — that is, enterprise — sources. It does not touch the two Microsoft built-ins. On a clean VM, with an allowlist containing only our own source, winget search --source winget still returned results from the public repository. The allowlist stops a local admin adding a third source; it does not remove the two that shipped with Windows.
To fence a fleet you must disable the built-ins explicitly, with EnableDefaultSource=0 and EnableMicrosoftStoreSource=0. After that, winget source list shows only your source, and asking for a built-in by name answers “No sources match… The configured sources are: …”
Seven values under one key.
All of these live under HKLM\SOFTWARE\Policies\Microsoft\Windows\AppInstaller, set through the Desktop App Installer ADMX, a Group Policy preference, or an Intune configuration profile. The toggles are DWORDs on the key itself; the two source lists are REG_SZ entries in their own subkeys.
Force-adds your source fleet-wide. The value data is the JSON shape that winget source export produces. This is what makes the source visible to the interactive user.
Disables the public community source. Without this, the public winget source stays reachable no matter what your allowlist says.
Disables the msstore source. Same reasoning — an allowlist does not touch it.
Restricts which additional sources may exist, so a local admin cannot add their own. It governs enterprise sources only.
Stops winget install --manifest, which would otherwise route around the source entirely.
Blocks --ignore-security-hash. Defence in depth: in the elevated path a hash mismatch already cannot be overridden.
Stops users editing winget settings to undo the above.
Do not set EnableAppInstaller=0. That disables winget altogether rather than fencing it, and takes your managed install path down with it.
Register your source before you disable theirs.
If you disable the built-ins first, there is a window — however brief — in which the machine has no usable source at all, and every install fails, including the ones you intended to allow. Write the AdditionalSources entry first, confirm the source resolves, and only then turn off the defaults. Reverse the order when unwinding: restore the built-ins before removing your own source.
One more thing worth knowing before you roll this out: the policy key is readable by authenticated users, so if your source URL carries a per-endpoint token in the path, treat that token as locally readable rather than secret. Per-endpoint tokens with server-side revocation and read-only scope are what keep the blast radius to one machine.
A fence you set once is a fence that drifts.
Winget re-reads and enforces these values on every invocation, so the policy does the enforcing. What policy cannot do is notice when a local admin edits the key, or when an App Installer self-update transiently resets source state. Attestree’s agent applies the fence and then maintains it — repairing local edits, keeping the source URL and token current, and re-asserting after a winget self-update.
It also reports back. Each cycle emits a fence-state signal, so your fleet view distinguishes an endpoint that is enrolled from one that is actually fenced. For a security control, believing a machine is protected when it is not is the dangerous failure — so that gap is surfaced rather than assumed away.
> winget source listName Argumentattestree https://feed.internal/e/…> winget search --source wingetNo sources match the given value:winget. The configured sourcesare: attestree.> winget source remove attestreeThis operation is disabled byGroup Policy.
Straight answers.
How do I disable the default winget source?
Set EnableDefaultSource to 0 as a DWORD under HKLM\SOFTWARE\Policies\Microsoft\Windows\AppInstaller, via the Desktop App Installer ADMX or an Intune configuration profile. Disable the Store source in the same pass with EnableMicrosoftStoreSource = 0. Both are hidden by policy rather than uninstalled, so removing the policy restores them.
Does an allowed-sources policy block the public source on its own?
No, and this is the mistake that quietly leaves fleets open. EnableAllowedSources governs additional (enterprise) sources only — it does not touch the two Microsoft built-ins. We confirmed this on a clean VM: with an allowlist containing only our own source, winget search --source winget still returned results from the public source. You have to disable the built-ins explicitly.
Should I just set EnableAppInstaller to 0?
No. That disables winget entirely rather than fencing it, which breaks the managed install path along with everything else. The goal is a winget that works normally and can only see your source.
Can I add the source with winget source add instead of Group Policy?
Not for a fleet. A source added by SYSTEM lands in SYSTEM's own per-user source store, where interactive users never see it — the same class of bug as a per-user app installed by SYSTEM. The Group Policy path is what makes a source machine-wide, and it has a second benefit: a policy-forced source cannot be removed by a user. winget source remove answers "This operation is disabled by Group Policy: Enable Additional Windows App Installer Sources."
What stops someone installing a tampered package anyway?
Winget verifies the installer SHA-256 against the manifest and aborts on mismatch. We tested the bypasses on a clean VM: with the override disabled it refuses; with --ignore-security-hash it refuses; and with the override enabled it still refuses — "Installer hash does not match; this cannot be overridden when running as admin." The trigger is elevation rather than scope, and in winget's download flow that check is evaluated first and has no escape path, so for any elevated caller the mismatch is unbypassable. That is the property the whole attested-feed model rests on, and it holds even without the policy key. Set EnableHashOverride = 0 anyway, for the non-elevated edge.
Is the lockdown reversible?
Cleanly. Deleting the AppInstaller policy tree restored the public and Store sources automatically on our test box — no source reset, no reinstall — and the forced source disappeared. The built-in sources are hidden by policy, never destroyed.
What are the version requirements?
Group-Policy-forced REST sources need a recent App Installer; our verification ran on Windows 11 22H2 with winget 1.8.1911, deliberately older than a current dev box so the result is conservative. Note that App Installer updates independently of the OS build, so an OS version floor alone does not tell you whether a machine supports this.
Then give it something to point at.
A fenced fleet needs a source worth being fenced to — one where every version was detonated and signed before it was admitted.