Self-hosted app-store supply chain review · Updated 2026-07-05

App Store Supply Chain Review: Catalog Trust, Manifests, Lifecycle Hooks, Image Digests, Provenance, Permissions, Backup Hooks, Updates, and Recovery

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.

Quick matrix

Supply-chain layerReview questionFailure signalEvidence
Catalog ownershipWho controls listing and review?Anonymous fork or stale maintainer with broad publish accessRepository owner, reviewers, release process
App sourceDoes listing point to inspectable upstream?Opaque binary/image with no source mappingSource repo and release tag
ManifestWhat ports, mounts, env, dependencies and permissions are declared?Broad host mounts or hidden dependenciesManifest diff and policy review
Lifecycle hooksWhat scripts run on install, start, update, stop and uninstall?Shell hook downloads or mutates host state unexpectedlyHook source and test log
Artifact identityWhat exact image/package runs?Mutable latest tag with no digest recordDigest, release ID, registry path
ProvenanceCan build origin be verified?Artifact cannot be tied to reviewed source/buildProvenance or attestation record
PermissionsWhat host/data/network/secrets access is granted?App receives daemon socket, root, broad mounts, or unrelated secretsPrivilege and mount inventory
UpdatesWho can publish and how does promotion happen?Auto-update from mutable upstream without reviewUpdate owner, policy, staged test
Backup hooksDoes backup include config, DB and app data consistently?Backup archive omits state needed for restoreRestore drill result
RemovalCan uninstall leave privileged state or credentials?Orphaned users, services, tokens, mounts, firewall rulesPost-uninstall audit
Compromise recoveryCan trust be revoked and clean state restored?Only option is reinstalling same untrusted appBlocklist/revoke path and clean restore

App-store trust readiness scorecard

Score one representative app before trusting the catalog at scale.

Control0 points1 point2 pointsOwner question
Publisher identityUnknownKnown repo ownerVerified maintainer/review path and incident contactWho can publish a trusted update?
Artifact pinninglatest tagVersion tagDigest or immutable release plus recorded provenanceCan the same version silently change?
Manifest reviewInstall blindlyManual glancePolicy review of ports, mounts, env, capabilities and dependenciesWhat privilege does the app receive?
Lifecycle scriptsUnknownScripts visibleHooks reviewed, tested, bounded, and diffed on updateWhat code runs outside the app process?
Update governanceAutomatic upstream trustManual approvalStaged promotion, change review and rollback/recovery pathHow far can a bad update spread?
Backup integrationNoneFiles copiedApp-consistent backup and clean restore testedCan the app be rebuilt after host loss?
Vulnerability responseNo ownerUpstream monitoringAdvisory intake, patch SLA, disable/revoke path, user noticeWho reacts to a compromised dependency?
Removal/recoveryDelete container onlyManual cleanupDocumented uninstall audit and clean-room recoveryWhat trusted state remains after removal?

45-minute app-store supply-chain review

Use one representative app to evaluate the catalog trust model.

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.

5–15 min: inspect manifest and hooks

Review ports, mounts, env, capabilities, dependencies, downloads and lifecycle scripts.

Success checkNo hidden privilege or opaque execution path remains unexplained.

15–20 min: resolve artifact identity

Record version, registry and digest or immutable release ID; check provenance/SBOM/signature evidence where available.

Success checkReviewed artifact can be identified exactly.

20–30 min: disposable install/update

Install and update in a test host; observe new services, files, users, network calls and privilege changes.

Success checkRuntime behavior matches reviewed packaging intent.

30–40 min: backup/restore/uninstall

Run supported backup, clean restore and uninstall; inspect leftover state.

Success checkRecovery works and privileged residue is understood.

40–45 min: rehearse compromise

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.

App catalog review flow

  1. Identify catalog and app publisher ownership. Separate platform maintainers, catalog maintainers, app packagers, upstream developers, image publishers, and registry operators.
  2. Read the app manifest and all lifecycle hooks or packaging scripts. Record ports, host mounts, volumes, environment variables, secrets references, capabilities, devices, dependencies and external downloads.
  3. Resolve the runtime artifact. Prefer immutable image digests or equivalent fixed releases for reviewed deployments; record the exact artifact that passed review.
  4. Check whether provenance, SBOM, signatures or other attestations exist and whether the deployment path actually verifies them instead of only displaying badges.
  5. Run the app in a disposable host or VM. Observe filesystem writes, users/services created, network destinations, image pulls, privileges, install/update behavior and uninstall leftovers.
  6. Test update governance. Diff manifest, hooks, image digest and privileges before promotion; avoid letting an upstream mutable tag become an immediate production update.
  7. Test backup and restore using the platform's actual hooks or app documentation. Verify config, database, identity, uploads/media and version compatibility.
  8. Define compromise response: disable listing or updates, stop affected app, preserve logs and artifacts, revoke credentials, replace trusted artifacts, restore clean state and notify users when needed.

Scenario table

ScenarioMain review targetStop condition
CasaOS community appCompose/manifest source, image registry, mounts, ports, update ownershipMutable image and broad host access with unclear maintainer
Umbrel appManifest, dependencies and lifecycle hooksHook code downloads/executes unreviewed content or update changes privilege silently
YunoHost packaged appInstall/upgrade/backup/restore/remove scripts and package maintenance statusBackup/restore path is missing or package scripts mutate host unpredictably
Nextcloud app ecosystemPublisher, app version compatibility, permissions, update channel and data migrationApp update cannot be rolled back or restored with server state
Containerized media appImage digest, volumes, users, media mounts, metadata-provider secretsApp needs writable access to entire storage tree or daemon socket
Community app-store forkStore owner, review process, upstream sync, key/credential ownershipFork presents itself as official or has no patch/advisory process
Emergency zero-dayDisable update/install, isolate running app, rotate secrets, verify clean artifactTeam keeps auto-updating from same compromised publisher path

Supply-chain risks

Catalog trust transitivity

Users may trust every app because they trust the platform, even when apps are packaged and maintained by different people.

Mutable image tags

A version or latest tag can point to different bytes later. Record immutable digests for reviewed deployments when practical.

Lifecycle hook privilege

Install and update hooks can execute privileged host mutations outside the normal application runtime boundary.

Broad mount inheritance

Convenient app templates can grant write access to large host directories, Docker sockets, backups, or unrelated application data.

Auto-update blast radius

A compromised publisher account or bad package can spread quickly when catalog changes or mutable tags are promoted automatically.

Backup-hook theater

A backup command existing in packaging does not prove that database, config, uploads and identity can be restored consistently.

Abandoned package

A healthy upstream project can still be unsafe to run through a stale package whose manifests, images or upgrade scripts are no longer maintained.

Uninstall residue

Removing the visible app may leave users, services, scheduled tasks, tokens, firewall rules, data mounts or privileged helper state behind.

Supply-chain review patterns

Publisher map

Record platform, catalog, packager, upstream, image publisher and registry as separate trust actors.

Manifest diff gate

Review changes to mounts, ports, env, capabilities, hooks, image source and dependencies before update promotion.

Digest evidence

Record the immutable image digest or release artifact that was tested, even when user-facing configuration keeps a version tag.

Disposable install test

Install, update, back up, restore and uninstall one app in a disposable host while recording created state and network behavior.

Privilege budget

Treat root, host networking, daemon sockets, devices, broad mounts and unrelated secrets as exceptions requiring written justification.

Catalog incident switch

Maintain a path to disable new installs/updates for one app without breaking unrelated catalog entries or deleting forensic evidence.

FAQ

Short answers for self-hosted catalog operators and users.

Is an official catalog automatically safe?

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.

Why pin container images by digest?

A digest identifies exact image bytes, while tags can move. Digest evidence helps prove which artifact was reviewed and deployed.

Are manifests only metadata?

Often no. Manifests can define ports, mounts, dependencies, environment, image sources and lifecycle behavior, so they are part of the security boundary.

What should be reviewed on every app update?

Manifest changes, lifecycle scripts, image source/digest, new privileges, data migration, backup compatibility and maintainer/repository changes.

What is the biggest app-store risk?

Trust transitivity: users trust a platform and unknowingly extend that trust to every package maintainer, image publisher and update path.

What is the recovery goal after package compromise?

Stop distribution, isolate affected instances, preserve evidence, rotate exposed secrets, restore from clean trusted artifacts and data, then reopen updates deliberately.

Related radar

Self-hosted Apps & Local Infrastructure Radar

Related RepoDaily briefs

Sources

  1. Umbrel App Framework
  2. YunoHost Packaging Apps
  3. YunoHost App Packaging Documentation
  4. CasaOS App Store repository
  5. Docker Pull by Digest
  6. Docker Build Best Practices
  7. Docker Provenance Policy
  8. Docker Image Signatures
  9. RepoDaily Home Server Backup & Recovery Checklist
  10. RepoDaily Reverse Proxy & Public Exposure Checklist

Feedback

Did this page help you make a decision?

Anonymous feedback helps RepoDaily improve what is actually useful.

Report outdated or missing evidence