feat(devicepolicy): enforce VS Code private marketplace URL#178
Open
raysubham wants to merge 3 commits into
Open
feat(devicepolicy): enforce VS Code private marketplace URL#178raysubham wants to merge 3 commits into
raysubham wants to merge 3 commits into
Conversation
Fold an optional extensions.gallery.serviceUrl into the existing ide_extension#vscode reconciler, written into the user-scope settings.json beside extensions.allowed via one atomic multi-key write. The agent owns both keys: set is authoritative, removal is ownership-gated (never deletes a user-configured value), and drift, convergence, selective clear, and post-write rollback all cover both. - api: lift gallery_service_url from run-config into EffectivePolicy - settings_writer: managedSettingsWriter (ReadManaged / ApplyManaged / RestoreManaged) over a set of keyed ops; single-key Write/Read/Clear kept - reconcile: ownership-gated set/remove/preserve for the gallery key; convergence over both keys before the idempotency short-circuit; drift over owned keys; atomic multi-key rollback; per-key ownership-safe clear - cache: additive WrittenSettings map (omitempty; an allowlist-only record is unchanged on disk) - probe: yield mdm_managed when an MDM owns AllowedExtensions OR ExtensionGalleryServiceUrl (Windows / macOS / Linux) Additive and regression-guarded: an allowlist-only policy writes exactly as before (byte-identical settings.json and ownership record).
…tings Move the VS Code allowlist's ownership record from the scalar WrittenValue into the WrittenSettings map alongside the gallery URL, so every managed key is tracked uniformly by setting id. WrittenValue is now used only by the single-key (npm) writer; adds omitempty so managed records no longer carry a dead written_value field. No behavior change: ownership is read back from the same values the agent writes.
… map) The run-config policy payload is now a settings map (setting id → compiled value) instead of the bare extensions.allowed object plus a sibling gallery_service_url field; the hash covers the whole map. enforce and clear are fully driven by the settings map and recorded ownership — no per-key special-casing — so a new managed setting rides through with no code change. Fetch now requires extensions.allowed to be present and a JSON object. Deleted managedKeys/managedGalleryValue; added compactSettings/sortedUnion/sortedKeys. Breaking run-config wire change (pre-GA): requires agent-api to emit the settings-map shape.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Folds an optional VS Code private-marketplace URL (
extensions.gallery.serviceUrl) into the existingide_extension#vscodereconciler, delivered through the same agent enforcement lane as the extension allowlist. The agent writes both keys into the user-scopesettings.jsonin one atomic merge and tracks ownership of each independently.Additive and regression-guarded: an allowlist-only policy compiles, writes, and records ownership exactly as before (byte-identical
settings.jsonand cache record). No agent-version gating — marketplace-URL tenants run current agents, so the resolver always sends the URL and one hash covers it.What changed (
internal/devicepolicy/)gallery_service_urlfrom run-config intoEffectivePolicy(no request change).managedSettingsWriterseam —ReadManaged/ApplyManaged/RestoreManagedover a set of keyed ops (one atomic load→patch→store). Single-keyWrite/Read/Clearretained for any single-key writer.clear; atomic multi-key rollback on a post-write persist failure.WrittenSettings map[string]string(omitempty→ an allowlist-only record is unchanged on disk).mdm_managedwhen an MDM ownsAllowedExtensionsorExtensionGalleryServiceUrl(Windows / macOS / Linux).Semantics
clear:true→ remove each owned key independently; a tampered / foreign key is left in place.settings.jsonimmediately (file state is the contract, as today).Testing
go test ./internal/devicepolicy/ -race— writer goldens (allowlist-only bytes identical to the pre-featureWrite, both-key, remove-tolerates-absence, preserve, presence flags, restore round-trip, refuse-unsalvageable, special-char round-trip), reconcile transitions (first / idempotent / gallery-only drift / allowlist drift / URL added / replaced / removed-when-owned / foreign-preserved / clear-owned-only / multi-key rollback / rollback-failure / readback-mismatch), cache round-trip + omitempty, probe either-key (darwin native; linux + windows fixtures).gofmt -lclean ·go vet(darwin/linux/windows) · cross-compileCGO_ENABLED=0linux/amd64 + darwin/arm64 + windows/amd64 ·go mod tidyno-diff ·golangci-lint0 issues ·make smoke44/44.No version bump or CHANGELOG entry (handled at release cut).