packages/app-core/packaging/flatpak/README.md
Two manifests live in this directory. They produce the same ai.elizaos.App
app-id, but with very different sandbox postures.
| Variant | Manifest | Wrapper | Posture | Distribution |
|---|---|---|---|---|
| Store (Flathub) | ai.elizaos.App.store.yml | elizaos-app-wrapper.store.sh | Locked-down sandbox, no host escape | Flathub |
| Direct (power-user) | ai.elizaos.App.yml | elizaos-app-wrapper.sh | Full $HOME access, host shell reach, EXECUTE_CODE permitted | Self-hosted repo, side-loaded bundles |
Pick the variant that matches the audience. Flathub will reject the direct manifest on review. Power users who want host-Ollama, docker reach, and EXECUTE_CODE want the direct manifest (or, equivalently, the AppImage / .deb / .rpm builds).
The build is selected by the ELIZA_BUILD_VARIANT env var at build time —
see bun run build:flatpak (packages/app-core/scripts/build-flatpak.mjs).
The store manifest grants only the capabilities a managed-cloud Eliza agent needs:
--share=network — cloud APIs, model providers, plugin registry, the
loopback web dashboard.--share=ipc — required for localhost loopback the dashboard binds.--socket=wayland + --socket=fallback-x11 — desktop integration.--filesystem=xdg-documents/Eliza:create — a single user-granted
workspace folder under ~/Documents/Eliza. The user picks (or
confirms) this through the FileChooser portal at first run.--filesystem=xdg-config/elizaos-app:create — config and account
storage under ~/.config/elizaos-app.--persist=.eliza — ~/.eliza is rewritten transparently by
Flatpak to ~/.var/app/ai.elizaos.App/.eliza, surviving upgrades.--talk-name=org.freedesktop.Notifications — desktop notifications.--talk-name=org.kde.StatusNotifierWatcher — system tray.What it explicitly does NOT grant — and what bubblewrap therefore blocks unconditionally:
--filesystem=home / --filesystem=host. No reading or writing
outside the granted folders.--talk-name=org.freedesktop.Flatpak. That D-Bus name is the
host-spawn portal; it is the standard way for sandboxed apps to escape
the sandbox and run host commands. The store posture forbids host
escape, so it is excluded.--device=all. No raw device access.--socket=session-bus / --socket=system-bus. Direct D-Bus
exposure would let the runtime talk to anything; we go through the
portal stack instead.The runtime reads ELIZA_BUILD_VARIANT=store (set by the store wrapper)
and gates off:
bun, python, git, docker, etc. on
the host PATH — they're not in $PATH inside the sandbox anyway, but
the runtime reports the disablement explicitly so users see "local
agent execution disabled in this build" instead of opaque ENOENT).EXECUTE_CODE action.127.0.0.1:11434 reach — the sandbox sees
its own loopback, not the host's, so Ollama-on-host wouldn't work
even if we tried).Hosting flips to the cloud-only routing: the agent talks to Eliza Cloud for inference, plugin registry, app deploys, billing, and any other backend that would otherwise have a local fallback.
The store variant relies on these portals (ambient on the
org.freedesktop.Platform//24.08 runtime — no extra --talk-name=
needed):
| Portal | Purpose |
|---|---|
org.freedesktop.portal.FileChooser | Workspace folder picker (first run + "open in workspace") |
org.freedesktop.portal.OpenURI | Browser launches for OAuth flows (Eliza Cloud sign-in, app domain verification) |
org.freedesktop.portal.Notification | Notification fallback (the older org.freedesktop.Notifications D-Bus name is also granted) |
If a future feature needs camera, microphone, or location, add the
corresponding portal — do NOT add a raw --device= or --socket= rule.
# Install build tooling.
sudo apt install flatpak flatpak-builder # Debian / Ubuntu
sudo dnf install flatpak flatpak-builder # Fedora
# Install the runtime + SDK once.
flatpak install --user flathub org.freedesktop.Platform//24.08
flatpak install --user flathub org.freedesktop.Sdk//24.08
# Build the store variant.
ELIZA_BUILD_VARIANT=store bun run build:flatpak
# Or call flatpak-builder directly.
cd packages/app-core/packaging/flatpak
flatpak-builder --user --install --force-clean build-dir ai.elizaos.App.store.yml
# Run.
flatpak run ai.elizaos.App --version
flatpak run ai.elizaos.App start
# Inspect the granted permissions to confirm the lockdown.
flatpak info --show-permissions ai.elizaos.App
# Expect: shared=network;ipc; sockets=wayland;fallback-x11; filesystems
# limited to xdg-documents/Eliza and xdg-config/elizaos-app; talk-names
# limited to Notifications + StatusNotifierWatcher.
When you're ready to submit the store variant to Flathub:
build. The
test-flatpak.yml CI workflow regenerates node-sources.json on
every run via ./generate-sources.sh and uploads it as the
flatpak-node-sources artifact. To refresh the committed copy
locally (Linux only):
./generate-sources.sh # writes node-sources.json next to this README
Test Flatpak Build workflow run on develop and drop it next to
this README. Once node-sources.json is committed, the manifest can
build offline (npm install -g --offline) and the
build-options.build-args: --share=network shim is no longer needed.ai.elizaos.App.metainfo.xml. Three
placeholder <screenshot> entries currently point at
https://app.elizaos.ai/screenshots/{dashboard,onboarding,plugins}.png
— host the real 1280×720 PNGs at those paths (or update the URLs to
wherever they're served from) before submitting. Flathub fetches the
URLs at review time.appstream-util validate and
flatpak-builder --show-manifest --show-deps.--filesystem=home).github.com/flathub/ai.elizaos.App and applies the manifest +
supporting files.The direct manifest (ai.elizaos.App.yml) keeps the existing
--filesystem=home posture so power users who self-host a Flatpak repo
or side-load a bundle get the same experience as the AppImage / .deb /
.rpm builds. It does NOT set ELIZA_BUILD_VARIANT=store, so the
runtime exposes the full coding-agent surface.
Don't submit this manifest to Flathub. It will fail review.