Access to /Users for dotrun snap


The store blocked me here: 'cos I’m trying to give my snap access to /Users. This is because I want my snap to be run on a mac through multipass, and then I want to share the local user’s home folder with multipass mount $HOME.

Would you mind approving this access?


The snap currently has:

    interface: system-files
    - /Users
    - /Users

First off, write implies read so you can drop read.

I’m puzzled by this though. Your snap specifies base: core18 and the core18 snap doesn’t have a /Users directory so even if multipass put /Users from the mac on the host vm in multipass, /Users isn’t available to your snap. /var/lib/snapd/hostfs/Users might be though.

Perhaps multipass could do something so that the home interface just works for your snap?

Ah, so maybe what I want to achieve isn’t possible?

I’ll explain this a bit more. This snap is for using to run our projects for local development. On Ubuntu, the user will simply basically do this:

snap install dotrun
cd ~/Projects/
dotrun serve  # Runs the "serve" script in "package.json" using the snap confinement

We want to provide a similar flow for our macOS users. So the plan is they basically do this:

multipass launch -n dotrun bionic
multipass exec dotrun -- snap install dotrun
multipass mount $HOME dotrun
alias dotrun='multipass exec dotrun -- dotrun -C "$(pwd)"'

(This is documented in the readme)

This will allow them to run dotrun natively on their host system within their project directories and have it work as it would on ubuntu.

Of course we could instead mount their $HOME somewhere else under /home/ubuntu inside the multipass, which will work, but it will be confusing for them because any paths they see in logs won’t match the paths on their host system.

Do you think there’s any way for me to achieve this experience with a strictly confined snap?

Yes but with the caveat that logs will be point to the real place, not /Users. Strict (and devmode) snaps run within a runtime environment that consists of a mount namespace whose root is provided by the base of the snap (eg, the ‘core18’ snap when ‘base: core18’ is specified. In the case of no base, the ‘core’ snap is used). While multipass can easily enough create the /Users directory in the host vm and mount onto it /Users from the mac, when the snap is running, it won’t see it because a) /Users isn’t a directory in the core, core18, etc snaps and b) nothing is putting /Users from the vm host onto /Users in the snap’s runtime environment. There is a special directory, /var/lib/snapd/hostfs that corresponds to the host, so if multipass created /Users in the vm host, it should be visible to the strict mode snap at /var/lib/snapd/hostfs/Users.

Discussion points:

  1. dotrun uses system-files to have write access to /var/lib/snapd/hostfs/Users and then adjusts $HOME to be /var/lib/snapd/hostfs/Users/<user> when it detects /var/lib/snapd/hostfs/Users. This is problematic for a lot of reasons: a) you only get ‘rwk’ for permissions so scripts, etc break (no execute, among other things) b) security policy is weakened due to no ‘owner’ match in the policy and c) the snap now has access to other snap’s data for snaps installed on the vm host. Any logged denials show up as /var/lib/snapd/hostfs/Users/… This is basically a non-starter
  2. multipass mounts /Users from the host onto /home in the vm host. This in theory should work, but I don’t know how much of the /home that is mounted over is required by multipass. Log entries get /home/<user> instead of /Users/<user>, but this isn’t terrible. dotrun only needs to plugs home
  3. multipass mounts /Users/<user> onto /home/<user>. Same as ‘2’, but possibly cleaner (though /Users/<vm existing username> on the mac is the same problem described in ‘2’)
  4. in the vm, symlink /home/<user> to /Users/<user>. Non-starter since the link is dangling in the context of the snap’s runtime. Even if it didn’t dangle, AppArmor would resolve the link and deny the access since no policy allows access to /Users.

I think the path forward is to drop system-files in favor of home, and then do ‘3’ and document that /home/<user> in the logs corresponds to /Users/<user> on the host. It is conceivable that multipass could do a symlink from /User to /home in the vm host to help a logged in user on the vm host feel more at home, but this would have no effect on dotrun’s runtime environment.

For the purposes of this request, NAK for use of system-files (it just won’t work, even if changed to /var/lib/snapd/hostfs/Users)

Okay, thanks for explaining that.

Yeah I think I’ll have to mount it into /home. That’s probably the best I can do. Thanks for your help.

I think I’m gonna make this a classic snap. That will work around this issue and also mean I can include Ruby support - as I can’t find any way to make Ruby work in strict confinement. The Ruby snap itself is classic.

Do note that there is a process for classic. I suggest reading the main topic to make sure your snap fits the criteria.

I am aware it exists. Is this similar to the restrictions for devmode whereby we can publish up to beta channel, but need approval for candidate or stable? 'Cos this snap is really only for internal use by our team. It would be acceptable to simply leave it on the beta channel.

No, approval for classic publishing is required before the snap can be released on the store to any channel.