New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interfaces/gpg-keys: Allow access to gpg-agent and creation of lockfiles #7366
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ | |
|
||
package builtin | ||
|
||
const gpgKeysSummary = `allows reading gpg user configuration and keys and updating gpg's random seed file` | ||
const gpgKeysSummary = `allows limited access to gpg-agent, reading gpg user configuration and keys and updating gpg's random seed file` | ||
|
||
const gpgKeysBaseDeclarationSlots = ` | ||
gpg-keys: | ||
|
@@ -49,6 +49,15 @@ deny @{HOME}/.gnupg/trustdb.gpg w, | |
# trust to access the user's keys and the level of trust for the random_seed | ||
# is commensurate with accessing the private keys. | ||
owner @{HOME}/.gnupg/random_seed wk, | ||
|
||
# allow access to gpg-agent's extra socket for passphrase entry. | ||
# This socket exposes a very limited subset of gpg-agent's functionality and | ||
# only allows the confined application to use gpg's cryptographic functions | ||
# but not anything related to managing the keys (adding, trusting etc). | ||
owner /run/user/[0-9]*/gnupg/S.gpg-agent.extra wr, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally speaking, the original intent of this interface is to allow access to the keys, not the agent, which is why the interface is named 'gpg-keys', not 'gpg', 'gpg-support' or similar. This is for several reasons:
For the first point, when keys are protected by a passphrase, this is a surprising amount of access to give to the snap. While trust needs to be given to a snap to access and unlock a key (ie, the current For the second point, allowing access to the gpg agent would allow bypassing the protections afforded by disconnecting the ssh-keys interface for systems with the gpg agent configured for ssh. While newer gpg-agents use Some of the problems due to the third point are described at length in @oSoMoN's initial post in https://forum.snapcraft.io/t/signing-files-with-gpg-from-within-a-snap/5566. The gpg-agent, tools and libraries are generally designed to work with matching versions of each other. Some older distributions will use gnupg while newer ones use gnupg2, Ubuntu Core itself doesn't ship the gpg-agent at all and Ubuntu 16.04 ships both gnupg and gnupg2 but with the gpg-agent from gnupg2, but in all cases, the snap may use either the gpg{,2} from the base runtime or whatever it ships (v1 for core/core16 and v2 for core18+). There are a number of important differences between v1 and v2 and while gnupg is generally expected to work with a gnupg2 agent, the extra socket is not available with gnupg, so if we add the extra socket to this interface, users would then expect As with the ssh-agent (eg, https://forum.snapcraft.io/t/ssh-agent-plug-request/1250/3), it was always expected for gpg access that a snap would start its own agent. In this manner, snaps are free to unlock the keys they need (which could even be snap-specific) without having to worry about exposing those keys to other snaps since the sockets would (well, at least should) be placed in the snap-specific areas of the filesystem. As mentioned elsewhere, expected use of this interface (and ssh-keys for that matter) should be documented. @degville or the snap advocacy team could probably help here (perhaps this should even be a snapcraft part). If agent access (ie, gpg or ssh) were going to be added to snapd, then I strongly feel it should be done in a separate interface, not the existing 'gpg-keys' interface and that interface would grant full use of the agent. That said, I'm quite concerned about the robustness of this new interface considering the above. All considered and since the existing interfaces are expected to work with a snap-specific agent, I'd prefer this scenario be properly documented and then what and see if there are legitimate use cases for the session-wide host agent (but I'll defer to @mvo5 and @pedronis on if a separate agent interface should wait or not). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely stunning elaboration, thank you @jdstrand. I agree that a separate interface is likely the way to go if full access is something that is desirable. To start an agent specific to the snap is a good solution if no external interfaces (besides the keyboard) are required. My concern here is stuff like Smartcards (
I feel that's a good solution for a decent chunk of interface users. This could maybe even be implemented as a snapcraft extension. |
||
|
||
# gpg creates lockfiles on every invocation | ||
owner @{HOME}/.gnupg/.#lk* rwk, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was not required for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I looked at this and found that the core18 base snap only contains gpgv. So I copied gpg and various libs it needed to SNAP_COMMON of a snap with this interface connected and did:
As such, if this rule were to be added, I think it should be:
but this exercise reminded me that gpg v2 always must be able to talk to the agent. Per the man page:
As such, there is no point adding these lockfiles to this interface since they are for use with the agent. The above rule would need to be in the new agent interface, if it was created. As mentioned, none of this is needed by consumers of this interface. I created a test-gnupg2 snap (it is not production; obtaining a tty is non-trivial and so there are limitations) and can demonstrate that everything works[1]:
[1]gpg unconditionally tries to create the /run/user/id/gnupg/d.... directory but falls back to GNUPGHOME if it is unable to, so there is a spurious AppArmor noisy denial: |
||
` | ||
|
||
func init() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't list what the extra socket can do. The comment should probably instead say:
That said, see my other comment.