0–5 min: map publishers
Identify catalog owner, package maintainer, upstream, image publisher and registry.
Success checkEvery artifact and update path has a named trust actor.
Self-hosted app-store supply chain review · Updated 2026-07-05
A practical supply-chain review for self-hosted app catalogs, community stores, container images, package manifests, install scripts, update channels, and recovery paths.
A self-hosted app store is a software supply chain. The visible catalog entry may hide repository ownership, container image tags, lifecycle hooks, install scripts, host mounts, secrets, update behavior, backup hooks, and rollback constraints.
This review treats CasaOS, Umbrel, YunoHost, Nextcloud-style app ecosystems, and containerized apps as trust chains rather than convenience layers. The goal is to know who publishes an app, what artifact actually runs, what install/update code executes, what privileges it receives, how it is backed up, and how to recover from a compromised package or maintainer account.
RepoDaily verdict
Do not approve an app solely because it appears in a familiar catalog. Review publisher identity, source repository, manifest and lifecycle scripts, exact image or package source, digest/provenance evidence where available, host mounts, ports, secrets, update path, backup and restore hooks, and emergency removal/recovery. Community catalogs can be valuable, but catalog inclusion is not a substitute for artifact verification and operational ownership.
| Supply-chain layer | Review question | Failure signal | Evidence |
|---|---|---|---|
| Catalog ownership | Who controls listing and review? | Anonymous fork or stale maintainer with broad publish access | Repository owner, reviewers, release process |
| App source | Does listing point to inspectable upstream? | Opaque binary/image with no source mapping | Source repo and release tag |
| Manifest | What ports, mounts, env, dependencies and permissions are declared? | Broad host mounts or hidden dependencies | Manifest diff and policy review |
| Lifecycle hooks | What scripts run on install, start, update, stop and uninstall? | Shell hook downloads or mutates host state unexpectedly | Hook source and test log |
| Artifact identity | What exact image/package runs? | Mutable latest tag with no digest record | Digest, release ID, registry path |
| Provenance | Can build origin be verified? | Artifact cannot be tied to reviewed source/build | Provenance or attestation record |
| Permissions | What host/data/network/secrets access is granted? | App receives daemon socket, root, broad mounts, or unrelated secrets | Privilege and mount inventory |
| Updates | Who can publish and how does promotion happen? | Auto-update from mutable upstream without review | Update owner, policy, staged test |
| Backup hooks | Does backup include config, DB and app data consistently? | Backup archive omits state needed for restore | Restore drill result |
| Removal | Can uninstall leave privileged state or credentials? | Orphaned users, services, tokens, mounts, firewall rules | Post-uninstall audit |
| Compromise recovery | Can trust be revoked and clean state restored? | Only option is reinstalling same untrusted app | Blocklist/revoke path and clean restore |
Score one representative app before trusting the catalog at scale.
| Control | 0 points | 1 point | 2 points | Owner question |
|---|---|---|---|---|
| Publisher identity | Unknown | Known repo owner | Verified maintainer/review path and incident contact | Who can publish a trusted update? |
| Artifact pinning | latest tag | Version tag | Digest or immutable release plus recorded provenance | Can the same version silently change? |
| Manifest review | Install blindly | Manual glance | Policy review of ports, mounts, env, capabilities and dependencies | What privilege does the app receive? |
| Lifecycle scripts | Unknown | Scripts visible | Hooks reviewed, tested, bounded, and diffed on update | What code runs outside the app process? |
| Update governance | Automatic upstream trust | Manual approval | Staged promotion, change review and rollback/recovery path | How far can a bad update spread? |
| Backup integration | None | Files copied | App-consistent backup and clean restore tested | Can the app be rebuilt after host loss? |
| Vulnerability response | No owner | Upstream monitoring | Advisory intake, patch SLA, disable/revoke path, user notice | Who reacts to a compromised dependency? |
| Removal/recovery | Delete container only | Manual cleanup | Documented uninstall audit and clean-room recovery | What trusted state remains after removal? |
Use one representative app to evaluate the catalog trust model.
Identify catalog owner, package maintainer, upstream, image publisher and registry.
Success checkEvery artifact and update path has a named trust actor.
Review ports, mounts, env, capabilities, dependencies, downloads and lifecycle scripts.
Success checkNo hidden privilege or opaque execution path remains unexplained.
Record version, registry and digest or immutable release ID; check provenance/SBOM/signature evidence where available.
Success checkReviewed artifact can be identified exactly.
Install and update in a test host; observe new services, files, users, network calls and privilege changes.
Success checkRuntime behavior matches reviewed packaging intent.
Run supported backup, clean restore and uninstall; inspect leftover state.
Success checkRecovery works and privileged residue is understood.
Disable update path, stop app, preserve evidence, rotate one sample secret and choose trusted recovery artifact.
Success checkResponse does not depend on trusting the compromised path.
| Scenario | Main review target | Stop condition |
|---|---|---|
| CasaOS community app | Compose/manifest source, image registry, mounts, ports, update ownership | Mutable image and broad host access with unclear maintainer |
| Umbrel app | Manifest, dependencies and lifecycle hooks | Hook code downloads/executes unreviewed content or update changes privilege silently |
| YunoHost packaged app | Install/upgrade/backup/restore/remove scripts and package maintenance status | Backup/restore path is missing or package scripts mutate host unpredictably |
| Nextcloud app ecosystem | Publisher, app version compatibility, permissions, update channel and data migration | App update cannot be rolled back or restored with server state |
| Containerized media app | Image digest, volumes, users, media mounts, metadata-provider secrets | App needs writable access to entire storage tree or daemon socket |
| Community app-store fork | Store owner, review process, upstream sync, key/credential ownership | Fork presents itself as official or has no patch/advisory process |
| Emergency zero-day | Disable update/install, isolate running app, rotate secrets, verify clean artifact | Team keeps auto-updating from same compromised publisher path |
Users may trust every app because they trust the platform, even when apps are packaged and maintained by different people.
A version or latest tag can point to different bytes later. Record immutable digests for reviewed deployments when practical.
Install and update hooks can execute privileged host mutations outside the normal application runtime boundary.
Convenient app templates can grant write access to large host directories, Docker sockets, backups, or unrelated application data.
A compromised publisher account or bad package can spread quickly when catalog changes or mutable tags are promoted automatically.
A backup command existing in packaging does not prove that database, config, uploads and identity can be restored consistently.
A healthy upstream project can still be unsafe to run through a stale package whose manifests, images or upgrade scripts are no longer maintained.
Removing the visible app may leave users, services, scheduled tasks, tokens, firewall rules, data mounts or privileged helper state behind.
Record platform, catalog, packager, upstream, image publisher and registry as separate trust actors.
Review changes to mounts, ports, env, capabilities, hooks, image source and dependencies before update promotion.
Record the immutable image digest or release artifact that was tested, even when user-facing configuration keeps a version tag.
Install, update, back up, restore and uninstall one app in a disposable host while recording created state and network behavior.
Treat root, host networking, daemon sockets, devices, broad mounts and unrelated secrets as exceptions requiring written justification.
Maintain a path to disable new installs/updates for one app without breaking unrelated catalog entries or deleting forensic evidence.
Short answers for self-hosted catalog operators and users.
No. Official review can reduce risk, but you still need to understand who packages each app, what artifact runs, what privileges it receives, and how updates and recovery work.
A digest identifies exact image bytes, while tags can move. Digest evidence helps prove which artifact was reviewed and deployed.
Often no. Manifests can define ports, mounts, dependencies, environment, image sources and lifecycle behavior, so they are part of the security boundary.
Manifest changes, lifecycle scripts, image source/digest, new privileges, data migration, backup compatibility and maintainer/repository changes.
Trust transitivity: users trust a platform and unknowingly extend that trust to every package maintainer, image publisher and update path.
Stop distribution, isolate affected instances, preserve evidence, rotate exposed secrets, restore from clean trusted artifacts and data, then reopen updates deliberately.
Feedback
Anonymous feedback helps RepoDaily improve what is actually useful.