Import the MetaMesh app family from Worph/AppStore
23 apps (MetaCore, the library/network/client tiers and 13 MetaFeeder*) move out of the general-purpose Worph/AppStore into their own store so the MetaMesh family releases on its own cadence. - asset URLs repointed to cdn.jsdelivr.net/gh/Worph/MetaAppStore@main - store scaffolding added (category/recommend/featured lists, licence, contributing, gitattributes) - psd-source/meta-icons-v2 icon generator follows the apps MetaMCP stays in Worph/AppStore: it is third-party metatool-ai software, not part of MetaMesh.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# MetaFuse — Rationale
|
||||
|
||||
## What deviation / exception is being requested
|
||||
|
||||
1. `metafuse-app` runs `privileged: true`, `user: 0:0`, with `/dev/fuse`,
|
||||
`cap_add: [SYS_ADMIN, DAC_READ_SEARCH, DAC_OVERRIDE]` and `apparmor:unconfined`.
|
||||
2. It mounts `/DATA/MetaFuse/Library`, which is outside both
|
||||
`/DATA/AppData/metafuse/` and the standard user directories, with `shared` mount
|
||||
propagation.
|
||||
3. It mounts `/DATA/AppData/metacore/meta-core` — another app's AppData directory.
|
||||
4. `/webdav*` bypasses the SSO gate.
|
||||
|
||||
## Why it is necessary
|
||||
|
||||
1. MetaFuse *is* a FUSE filesystem. Mounting one from inside a container requires
|
||||
`/dev/fuse`, `SYS_ADMIN`, and an unconfined AppArmor profile; the `DAC_*` caps let the
|
||||
filesystem answer `getattr`/`open` for files owned by other uids. There is no
|
||||
unprivileged path to this feature.
|
||||
2. `shared` propagation is what makes the mount visible on the **host** at
|
||||
`/DATA/MetaFuse/Library` instead of dying inside the container's namespace. That host
|
||||
path is the entire point of the app: it is the directory the user (and Jellyfin, Plex,
|
||||
Samba, …) browse. It is deliberately *not* under `/DATA/AppData/` because it is
|
||||
user-facing content, not application state.
|
||||
3. `/meta-core` is MetaCore's service-discovery and leader-election directory. MetaMesh
|
||||
apps coordinate through it; MetaFuse writes its own service registration there and
|
||||
reads the current leader. MetaCore is a hard prerequisite of this app.
|
||||
4. WebDAV clients (media servers, file managers) authenticate at the WebDAV layer and
|
||||
cannot complete an interactive OIDC redirect.
|
||||
|
||||
## Security mitigations in place
|
||||
|
||||
- The interactive dashboard is behind AppShield + Authelia SSO
|
||||
(`ghcr.io/yundera/appshield:2.0.9`). Only `/health` and `/webdav*` are exempt.
|
||||
- `/DATA/MetaFuse/Library` is a **virtual** view: it projects records already held by
|
||||
MetaCore. It is not a second copy of the user's library and holds no independent data.
|
||||
- Everything MetaFuse persists is under `/DATA/AppData/metafuse/config/`, declared in
|
||||
`x-compose-app.folders`.
|
||||
- Image tags pinned; `cpu_shares` set on both services.
|
||||
|
||||
## Alternatives considered and rejected
|
||||
|
||||
- **Unprivileged FUSE (`fusermount` with `user_allow_other`).** The container still needs
|
||||
`/dev/fuse` and `SYS_ADMIN` to create the mount namespace; dropping `privileged` left
|
||||
the mount failing at startup.
|
||||
- **Mount under `/DATA/AppData/metafuse/Library`.** It would work, but the resulting path
|
||||
is not somewhere a user is expected to browse, and other apps' file pickers hide
|
||||
`AppData`. The whole feature is "a library folder you can open".
|
||||
- **Put `/webdav*` behind the SSO gate.** Every non-browser WebDAV client then fails to
|
||||
authenticate, which removes the reason the endpoint exists.
|
||||
- **Bundle a private MetaCore.** Duplicates the Redis/leader tier per app and breaks the
|
||||
single-source-of-truth model the ecosystem is built on.
|
||||
|
||||
## Data protection
|
||||
|
||||
MetaFuse stores no user media of its own — the library it exposes is a projection of
|
||||
MetaCore's records. Its own configuration lives in `/DATA/AppData/metafuse/config/`, inside
|
||||
the folder Maison archives and restores, so uninstall/reinstall preserves it. The shared
|
||||
`/meta-core` mount is read-mostly: MetaFuse writes only its own service-registration file
|
||||
under `/meta-core/services/`.
|
||||
Reference in New Issue
Block a user