Permanently punching through Flatpak Sandbox (how do you get "dynamic" read/write access?)

Hi,

I am developing a mod manager app for Linux, developed with Python and GTK4.

I wanted my app to be available as a Flatpak, and seeing as the whole point is to sandbox the app, I want to try and do this as much as possible to reassure the user.

My app needs access to a few very specific paths which are defined in my finish-args like so:

  # Heroic
  - --filesystem=~/.config/heroic:ro # Standard
  - --filesystem=~/.var/app/com.heroicgameslauncher.hgl/config/heroic:ro # Flatpak
  # Steam
  - --filesystem=~/.local/share/Steam:ro # Standard
  - --filesystem=~/.var/app/com.valvesoftware.Steam:ro # Flatpak

These work just fine!

However, during the app’s first startup I also want the user to define two paths which are custom and can be set wherever they want.

After the user has selected those paths, I need read/write access to them.

To do this, I am using a standard Gtk.FileDialog which from what I understood is meant to punch through the flatpack sandbox, which it doesn’t do. Or at the very least not in the way I expected?

Here’s a snippet of what I currently do:

def on_select_downloads_folder_clicked(self, btn):
    dialog = Gtk.FileDialog(title=_("Select Mod Downloads Folder"))
    dialog.select_folder(self.win, None,  self.on_downloads_folder_selected_callback)

My problem here is twofold:

  1. This returns an internal flatpak sandboxed path, which is unuseable for me (run/user/1000/...) → this is my biggest problem
  2. This does not actually give me write or even read access to that path (at least it’s not visible when I check with Flatseal).
    • This I could potentially find a way to workaround by generating a command for the user to execute in their terminal that will give me read/write access to the path they have provided

After a bit more research I’ve come to understand that the file picker only temporarily punches through the portal to get access to a single file, and then the access is immediately lost or some such.

Then how am I supposed to do what I’m trying to?

am I forced to simply have - --filesystem=host ?

This seems to defeat the entire purpose of sandboxing…

Is there any way to just ask the user to confirm that I should have access to a specific path?

Thank you for any help.

The paths selected by the Gtk.FileDialog are not using the same system as the filesystem permissions you set in your manifest.

Filesystem permissions are set before an application is run and their paths are bind-mounted into the sandbox on startup.
Gtk.FileDialog however uses the Document portal, which can grant access to paths during runtime. However, these files are mounted in the Document portal path run/user/1000/....

Paths granted over the Document portal using the file dialog stay accessible over this path, even over restarts of the application. But since they are dynamic permissions managed over the portal, they do not show up in the static filesystem permissions. And Flatseal only shows the static filesystem permissions.
If you wish to check what paths your application has been granted access to over the Document portal, you can use flatpak documents $APP_ID.

There is an API you can use to retrieve the host path for paths accessed over the Document portal as well. See a previous comment I made about it for more details.

I hope that clears things up a bit.