C.W.K.
Stream
Lesson 04 of 05 · published

Private Distribution — Self-Host, Unlisted, Group Policy

~12 min · distribution, private, enterprise, group-policy

Level 0Extension Curious
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Public Web Store is the default. The three private paths are unlisted store, Workspace-private store, and group-policy force-install. Lesson 4 maps when each fits, what each costs, and how to avoid the dead-end attempt at sideloading."

Why Not Just Sideload

The naive private-distribution idea: build .crx, host on a server, users download and double-click. Chrome desktop has progressively closed this path. Today, dragging a .crx onto chrome://extensions produces a 'This extension can't be added' warning on standard Chrome. The legitimate sideload requires either:

  • Developer mode + Load unpacked — each user toggles developer mode, points Chrome at the directory. Works but requires every user to re-update by re-downloading and re-loading. No auto-updates.
  • Enterprise policy force-install — managed Chrome installations, group policy that lists your extension's ID + update URL.

The first is fine for a one-person team, untenable for ten. The second is great if your team uses managed Chrome (most large orgs do via Google Workspace or Active Directory); useless if they don't.

Path 1 — Unlisted on the Web Store

The 'just barely public' path. The submission flow is identical to a public listing — privacy policy, screenshots, review, the works. The difference is visibility: the extension does not appear in search results, in category browsing, or in the Web Store's recommendations. Anyone with the URL can install with one click.

Pros: free, auto-updates work, no sideload pain, no Enterprise infrastructure needed. Cons: requires Web Store review (5 minutes to a week), and anyone who finds the URL can install (security through obscurity, not actual access control).

This is the right answer for indie dev teams, small open-source projects with a few testers, and anyone who wants Chrome's auto-update without the public-search exposure.

Path 2 — Workspace-Private Store

If your team uses Google Workspace, the Chrome admin console lets you publish extensions visible only to users in your Workspace domain. The extension submission goes to your private store; users in your domain see it on chrome.google.com/webstore as if it were public; users outside the domain never see it.

Pros: real access control via Workspace identity, auto-updates work, no install warning beyond the normal one. Cons: requires Workspace admin setup, costs whatever Workspace costs, only your Workspace domain users get access.

Right for medium teams (20–500 people) on Google Workspace who want a real private app store experience.

Path 3 — Group Policy Force-Install

Chrome supports a registry/policy mechanism on Windows, plist on Mac, and managed prefs on Linux for force-installing extensions. The admin specifies the extension's ID and update URL; Chrome auto-installs on every managed Chrome profile in the org. Users see the extension in their chrome://extensions but cannot uninstall it (the admin owns the install).

Pros: granular per-OU control, no user action required for install, can be combined with permission restrictions. Cons: requires managed Chrome (Workspace, Microsoft AD, Jamf, etc.), the update URL must be a Chrome-format .xml endpoint, and you're responsible for hosting both the .xml and the .crx versioned files.

Right for large orgs (500+ people) that need org-wide auto-install with central admin control.

The Self-Hosted Update Endpoint

If you go down the self-hosted path (Path 3 minus Workspace), you need an XML endpoint Chrome polls for updates:

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='your-extension-id'>
    <updatecheck codebase='https://your-cdn.example.com/clipdeck-1.0.0.crx' version='1.0.0' />
  </app>
</gupdate>

Chrome polls this URL on a schedule (a few times a day). Update the XML's version and codebase to point to a new .crx when you release; Chrome downloads it on the next poll.

The Decision Tree

  1. Public-facing extension? → Public Web Store.
  2. Team uses Google Workspace and wants org-only visibility? → Workspace-private store.
  3. Small private team, can live with 'anyone with the URL can install'? → Unlisted Web Store.
  4. Large managed-Chrome org that needs force-install + admin control? → Group policy + self-hosted .crx + XML endpoint.
  5. One person, no team? → Just keep using developer mode + Load unpacked. There's no rule that says you must distribute.
Unlisted Web Store is the easy default for small private distribution. Workspace-private for managed teams. Group policy + self-host for org-wide control. Sideloading raw .crx files via download is a dead end on modern Chrome.
The Mac Gatekeeper twist. On macOS, Chrome enterprise extensions installed via policy can still be flagged by Apple's Gatekeeper if the binary isn't signed with a Developer ID. If you're force-installing an extension that talks to a native messaging host, that host binary needs its own Apple signing and notarization. ClipDeck v1 doesn't use native messaging, so this caveat doesn't apply yet; flag it for any future extension that does.

Code

update.xml — self-hosted Chrome update endpoint·xml
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='abcdefghijklmnopqrstuvwxyzabcdef'>
    <updatecheck
      codebase='https://cdn.example.com/clipdeck/clipdeck-1.0.0.crx'
      version='1.0.0' />
  </app>
</gupdate>
manifest.json — point the extension at the self-hosted update endpoint·json
{
  "update_url": "https://cdn.example.com/clipdeck/update.xml"
}
Chrome policy.json — force-install the extension via group policy·json
{
  "ExtensionInstallForcelist": [
    "abcdefghijklmnopqrstuvwxyzabcdef;https://cdn.example.com/clipdeck/update.xml"
  ]
}

External links

Exercise

Pick the distribution path that fits your situation: solo dev → keep developer-mode unpacked, no need to ship. Small private team (≤10) → unlisted Web Store; complete the submission dry-run from Lesson 3 with visibility set to Unlisted. Workspace team → confirm with your Workspace admin whether you can publish to a private listing. Enterprise org → look up your IT department's extension-install policy mechanism (probably Chrome's ExtensionInstallForcelist via group policy) and ask whether ClipDeck can be added to the allowed list. For each path, write down the answer to: 'When I release v1.1, what's the user-facing step they need to take to upgrade?' For Web Store paths, the answer is 'none.' For self-hosted, the answer involves updating the XML endpoint. Pick the path with the upgrade story you can actually maintain.
Hint
If you don't know your team's Chrome management situation, the easy first step is to ask a colleague to share their chrome://management page (Workspace-managed Chromes show org info there). If you can't get an answer in 24 hours, default to unlisted Web Store — the path with the cheapest setup. The Web Store's $5 fee is one-time; an unlisted listing costs $0 to maintain. Don't pick group policy because it sounds enterprise-grade; it's enterprise-grade overhead too, and overkill for most teams.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.