Proposal: /tmp/snapd.public directory

Hello World,

I’d spent the last few days updating one of my snaps that partially works as an HTTP server that requires authentication. The authentication mechanism is to write an .HTML file with a token and redirect setup, and then run xdg-open on the file to get e.g., Firefox to open, grab the key and run the app in the default browser.

Infact, the same app does this in two ways, one for some custom code to that app, and another for Jupyter Notebook that has the exact same mechanism. Both of these are patched in my app to deal with this, in two separate ways:

  1. Jupyter can be configured to effectively run XDG-Open with the token directly. This works great because there’s no sandboxing problem, but as a result the token can be leaked in system logs (e.g., because it’s visible in the DBus messages when portals are being used, which can be logged by other users)

  2. The custom bit of the app wasn’t so easy to patch. On other operating systems it tries to grab a PID handle of the browser and do a lot more manual management. For the Snap, this means the file that gets passed to xdg-open is in /tmp, which we know in a strict snap is a bind mount and private.

For 2), I’d tried to reposition the file in XDG_Runtime_Dir. This is guaranteed to exist due to snaps implicitly requiring systemd, and it solves a lot of problems from the point of view of the host.

However, the default browser in Ubuntu is a snap. And Firefox cannot access my snaps runtime dir due to its own permissions.

In the end, the only valid answer seems to be to place that temporary file in $HOME itself, where both confined browsers can access it and my snap can write it. This leaves the risk that the app doesn’t clean these files up and litters $HOME, but there’s genuinely no other reliable alternative.

Even this comes with problems. If someone configured Firefox to not have the home interface connected, then it’s still not going to work. With prompting support in the future and from what I’ve seen of it, it might not be unusual for users to start imposing limitations on home access without understanding some of the potential consequences.

My idea here is that if we added a new folder, say /tmp/snapd.public/ that has the same path in the mount namespace as the host namespace, we could add this to the base interface template and effectively create an opt-in location where temporary files can be guaranteed to still be temporary and yet are also shared across all snaps and the host. Because this is a subdirectory of tmp, it wouldn’t get used by default but an app with a specific need could recognise it’s existence and choose to actively write into it where a temporary file is being used to share data across apps. By being opt in, we retain the intended privacy/security of the current design of rewriting /tmp to be private in the first place, whilst providing the ability to selectively bypass that where it makes sense.

Would something like this seem appropriate? Functionally whilst this isn’t a blocker for a lot of snaps, there’s a lot of individual functionality in specific snaps this enables and I feel comes at a very minimal implementation cost relatively.