Secrets for snaps

I have a snap that runs a daemon that needs to encrypt some of its data when stored on the disk. Obviously it’s not a good idea to store the encryption key along with the data.

Currently I get the user to provide a password the first time they interact with the daemon, but that’s not ideal, because it’s one more thing for the user to remember and another interaction in the way.

Is there some feature that allows a snap to get hold of a secret that it can use for this kind of thing, by any chance?

1 Like

It may be done via configuration:

$ snap set yoursnap secret=mys3cr3t

This will fire the configure hook inside the snap, which can do:

$ snapctl get secret

This command also works anywhere else inside the snap. Daemons can call it as well, of course.

You can play with the snapctl command in a shell inside the snap’s environment:

$ snap run --shell yoursnap.yourapp

Thanks. Are the snap configuration values encrypted at rest? If not, I guess this is pretty much equivalent, from a security point of view, to storing the data unencrypted and using password protection to guard access.

A nice property of the scheme I’m using currently is that the data is secure even if someone takes a snapshot of the disk. I realise that I was asking for a lot - doing it differently would probably require access to hardware-encrypted keys made available through the bootstrap process - I don’t even know if that’s possible. :slight_smile:

No, they’re available in plaintext in /var/lib/snapd/state.json. You might look into the brand new password-manager-service interface, but that’s typically session-based so the fact that it’s a daemon might get in the way.

It’s possible the password-manager-service interface might work well for this use case actually. Do you know of any Go packages that provide access to it, by any chance?

Yeah, I threw together a quick example snap for you:

Note that snapd v2.27 or later is required. Build and install that snap, and you’ll notice (by running snap interfaces) that the password-manager-interface is not automatically connected. Indeed, if you run keyring-example it’ll get a permission denied:

$ keyring-example
2017/10/05 08:18:41 dial unix @/tmp/dbus-A3KiI2fhJt: connect: permission denied

Connect that interface:

$ sudo snap connect keyring-example:password-manager-service

And then run the app:

$ keyring-example
2017/10/05 08:18:24 my-secret-password

If you open up “Passwords and Keys” you’ll see it in your Login keyring.