We have a collection of tools and utilities for managing openstack clouds that are built by Juju, and one of the things we wish to do is backup the Juju client configuration - which is hosted in ~/.local/share/juju. This is only available to us if we use classic confinement.
Can we please allow classic for the bootstack-ops snap?
Talked to @xavpaice on IRC, the only reason why this snap needs classic confinement is because it wants read-only access to ~/.local/share/juju to perform backups which is a location that the non-snap juju and juju client charm uses.
While the backup scenario is understood (eg, Classic Confinement Request for Restic snap), in this case it is only one particular directory in the userās home. There was some talk of extending the home interface to accommodate situations like this. @niemeyer - do you have thoughts on this? Shall I grant classic in the meantime (Iāve vetted the publisher).
It would be a shame to lose strict confinement just because it cannot load those files. I think we need a better plan here.
We might extend the home interface to support generic request of specific paths, but thereās a relevant issue: we donāt yet have a way to communicate to the user that these paths are required, which means someone connecting it by hand would not know what they are actually allowing. So a no go for now.
On a different thread, we are also working on a more general solution to support that kind of use case, that could enable the juju snap to request access to those bits. But that will also take a little while.
So we will need a third option here if we want to avoid classic on this snap, which again seems reasonable.
Can we please dig a bit further into the use case for that?
Towards that goal, a first question might be: why do we have a third-party snap fiddling with juju configuration? That doesnāt sound like a good idea in principle.
@niemeyer - AIUI (Iām unfamiliar with this snap), only read-only access is required to this directory since the snap attempts to backup those files. AIUI, there is no restore operation or other functionality that requires write access. @xavpaice, can you confirm?
I understand your point, however to backup the juju client we need to access those files, and thatās one of the tools Iām trying to implement here. These files are created by the juju client snap, which is classic, so weāre following an existing precedent. If the juju snap were to write itās client config somewhere more accessible, that woudnāt be an issue.
The other aspect of this is that there are several tools we use as operators that make use of the Juju client. In order for that to work, it has to be able to read itās config files, which are ~/.local/share/juju. If we canāt do that, then a snap is the wrong approach to distribute these tools and weād need to go about finding a way to build and package all the Python deps we need, which is a pain for sites that have limited Internet access and no way to use Pypi.
@xavpaice Have you considered using a ācontentā interface with the juju snap? It sounds reasonable to have that data being exposed by juju itself, if it wants its data to be accessible for backups or arbitrary tools.
That seems much more reasonable than making what is today a strict snap become a classic one merely to poke at a different snapās private data. The strictness there precisely intended to limit that sort of access, and force the snap to request data appropriately instead, so itās really a feature in this case.
This sounds great. Iām struggling a bit to find the right documentation - but as I understand it, youāre suggesting:
change the juju snap to provide a ācontentā interface, with a read slot for ~/.local/share/juju (dir in home, not in the snap directories). The current implementation of āhomeā doesnāt allow hidden files/dotfiles.
add the plug to my snap
That sounds ideal, however is it possible for a classic snap (Juju) to add plugs for something outside of $SNAP (or at all)?
Juju uses the config in ~/.local because the client is configured per user. Of course, if the client config wasnāt a dotfile, it would be fine to use the āhomeā interface and I suspect the Juju snap wouldnāt need classic either. I donāt fully understand why dotfiles under the home directory are not allowed to be accessed, surely a snap that allows access to home would still be restricted by the permissions of the filesystem and therefore whether the files are dotfiles or not is irrelevant? Regardless, is it better to raise a bug report requesting a new interface for access to files like this so that users would be well informed (e.g. āhome-hiddenā)?
Given that the Juju snap itself is classic, and I donāt expect for this bootstack-ops snap to be useful to people outside the Bootstack team, nor ever installed on core, Iād like it if we can get some movement soon even if it does mean allowing classic until we can either move the Juju client config to somewhere accessible, or make dotfiles in home accessible. Weāre currently shipping utilities in an unsustainable way and the benefits of using snaps is immense. The limitations weāre facing with our current methods affect current, paying customers and our ability to scale, which is becoming more of a problem as we become more successful. Once weāve overcome the limitations weāre facing right now, Iād love to switch to strict confinement.
If thatās the reason juju is using classic, it would be a misuse of classic. Thereās no reason for juju to store its data in that specific location. There must other reasons though, given the sort of work juju needs to do for system management?
The problem is that we need a line to guide ourselves in terms of what is or is not reasonable. Having one snap becoming classic because it needs to access private data from another snap is specifically a case we need to avoid. Itās the very reason why dot files are not accessible for strict snaps in the first place.
Here is a suggestion that can get you going quickly if there are no other alternatives in sight: letās introduce a juju-client-observe interface that explicitly allows accessing its data. Or perhaps juju-observe, if the snap contains both the client and its daemons.
That works for me. I can even write the interface and get it up quickly. @xavpaice, if you are agreeable, please reaffirm that it is only read-only access to ~/.local/share/juju you are interested in. Please consider future cases where you may want read-only access to other things juju (and what those paths are) so we can decide on juju-client-observe vs juju-observe.
Before reading this larger response, please see my question about ājuju-observe/juju-client-observeā since that is the immediate path forward. Answering your questions here for completeness.
Note that today classic snaps cannot use āplugsā for various reasons. We could certainly lift that for the content interface (ie, we only add apparmor policy/etc if confinement != classic), but this would require some work to detangle applying various security backends except mount when using classic confinement.
Itās also interesting to think about exporting per-user content via the content interface. Normally we export content from the SNAP, SNAP_COMMON or SNAP_DATA. Yours would be the first use case for this (and likely have to build on the per-user work that was recently done for portals).
Gustavo mentioned why we donāt allow access to dot files and Iāll expand on that. It is important to note that traditional desktops have the concept of a trusted session where each user runs a login session and anything that the user runs is considered trusted by the user. Snaps change that and snaps are considered untrusted by the user session and from each other so we donāt allow snaps to access each other or anything outside the snap by default. We then have interfaces that expand that access in controlled ways. The home interface is a so-called transitional interface (because the access it grants is so broad) to enable existing software to access non-hidden data. We could allow accessing hidden data, but then weād expose potentially very sensitive data to all snaps using the home interface-- eg, ssh and gpg keys (it is natural to then say āwell, just block thoseā but a blacklist approach is never complete-- we might add ssh and gpg, but forget .fetchmailrc, for example). It is important to also keep in mind the dot directories are used by the userās trusted session applications that typically come from debs/etc (ie, not snaps) and these files are often incompatible with snaps that have different versions of the same software installed or use different underlying libs (eg, gtk). If the snap had read or write access to arbitrary dot files, then the snap may not function correctly (eg, since the dot files use an old format) or the snap might break the userās session (eg, since the snap migrates from the old format to the new and now the user session is broken; Iāve personally seen someoneās desktop session get completed hosed because he (on his own, not because it was advised!) bind mounted his home into the snap and the snap made a bunch of incompatible changes).
Finally, it was my understanding that the juju snap could move to strict confinement after we introduced one of the ssh-keys or gpg-keys interfaces (I canāt remember which otoh), and Nicholas said heād move juju to strict confinement. I realize he has moved on, but if there are still things keeping juju classic, please review those and perhaps introduce a new topic so we can work through any remaining issues.
@jdstrand, @niemeyer, yes itās read-only access to ~/.local/share/juju that Iām looking for - no write required. Having a juju-client-observe interface would be absolutely perfect for my use case, I hadnāt even considered that adding an interface might be an option. I might need a little advice on how to access the directory since $HOME is specific to the snap, but thereās an env var I can use for juju client config which can remap me back to the right place. Currently, if I add JUJU_DATA=${HOME}/.local/share/jujuā to the env from which I call the snap (i.e. before $HOME is remapped), I seem to get the right result. If thereās a way to trigger the interface to avoid having to edit .bashrc that would be ideal, but not essential.
We will also want access to the juju binary, which is in the path via /snap/bin but might also be from a .deb, depending on the history of the machine.
Thanks so much for the detailed information here, itās something I think a number of folks might find useful.
It turns out there were a number of items that meant the Juju client snap needed classic, from the README in the repo:
Needed for confinement
To enable strict mode, the following bugs need to be resolved, and the snap updated accordingly.
āMissing support for abstract unix sockets (https://bugs.launchpad.net/snappy/+bug/1604967 )ā
There is an open question on this in the bug. The last time I talked to Nicholas I was under the impression this was no longer needed. Also note new support for socket, socket-mode and listen stream (Snapcraft.yaml reference) that may help you in this area
āJuju plugin support (https://bugs.launchpad.net/juju/+bug/1628538 )ā
This doesnāt seem to be a snapd deficiency (please correct if Iām wrong). We now have a content interface (The content interface) that should allow the juju snap to āslotā a read/write area and for plugins to āplugā this slot and write data to it. How you organize it, do registration, etc is completely up to you
Can you verify the above and confirm if anything else is still needed?
The Juju plugin protocol requires the ājujuā command line tool to execute arbitrary programs on $PATH that begin with ājuju-ā. It seems incompatible with confined snaps, and changing it would technically be a backwards incompatible change and shouldnāt be done until Juju 3.0 (to eg. require plugins to be installed in /snap somewhere, or be distributed as snaps that are plugged into the Juju snap)
Iām not familiar with the juju plugin protocol (maybe @niemeyer should weigh in on design for strictly confined juju), but it seems like the juju snap could provide a read-only slot that plugin snaps could consume which allows use of the ājujuā command (additional interfaces might need to be developed) and the juju snap could provide a read/write slot that plugin snaps could consume to write to. The juju snap is updated to add the read/write area to its PATH. Non-snap juju plugins write to wherever the juju command expects to find them (again, another interface might be needed for the juju snap to have this access, perhaps ājuju-supportā).
I am certainly missing details and donāt have the full pictureā¦ but it seems based on my limited understanding that juju could plausibly be strictly confined. @niemeyer - help!
Now that we have the 2.33 released, I tried to use the new interface to hook up the juju client and get confinement working, but when uploading to the store I get the following:
Error while processing...
The store was unable to accept this snap.
- interface 'juju-client-observe' not found in base declaration
- interface 'juju-client-observe' not found in base declaration
- interface 'juju-client-observe' not found in base declaration
- unknown plugs interface name reference 'juju-client-observe'
- unknown plugs interface name reference 'juju-client-observe'
- unknown plugs interface name reference 'juju-client-observe'
Is there something obvious that Iām missing here? Iāve added the following to the snapcraft.yaml: