Follow-up from PR #532 (Design Review, advisory).
The App Store derives all trust semantics client-side from the absence of the _registry field: isVerified, sourceLabel, and pickFeatured in website/src/components/appstore/ each treat "no _registry tag" as "trusted core entry". But _registry is an internal tagging detail of _load_external_registries in src/kiro_crew/apps/registry.py, not an API contract.
Three separate security holes in PR #532 were all instances of this one misplaced boundary:
- author spoof (external entry publishing
author: "KiroCrew")
- origin spoof (external entry publishing
origin: "builtin")
- featured spoof (external entry self-flagging into the Discover spotlight)
Each was patched at a different client call site. Nothing prevents a future backend change (e.g. _edition_registry_rows, or tagging core entries) from silently flipping the verified badge that sits next to an Install button running third-party setup with gateway privileges.
Proposal: have /api/apps/registry emit explicit provenance and verified fields computed server-side, and collapse the three client checks to read them. PR #532 was deliberately scoped to no backend changes, which made the current shape necessary rather than correct.
Follow-up from PR #532 (Design Review, advisory).
The App Store derives all trust semantics client-side from the absence of the
_registryfield:isVerified,sourceLabel, andpickFeaturedinwebsite/src/components/appstore/each treat "no_registrytag" as "trusted core entry". But_registryis an internal tagging detail of_load_external_registriesinsrc/kiro_crew/apps/registry.py, not an API contract.Three separate security holes in PR #532 were all instances of this one misplaced boundary:
author: "KiroCrew")origin: "builtin")Each was patched at a different client call site. Nothing prevents a future backend change (e.g.
_edition_registry_rows, or tagging core entries) from silently flipping the verified badge that sits next to an Install button running third-party setup with gateway privileges.Proposal: have
/api/apps/registryemit explicitprovenanceandverifiedfields computed server-side, and collapse the three client checks to read them. PR #532 was deliberately scoped to no backend changes, which made the current shape necessary rather than correct.