Snapcraft authentication options

Breaking so many existing workflows with no warning for people who publish snaps is unacceptable. At the very least I would expect existing workflows using $SNAPCRAFT_LOGIN with a reasonable expiry date (<1 year) to continue for working for a while. I’ve dropped support for snaps in my project for now. Hopefully snapcraft will be more developer-friendly in the future.

This is unfortunate, 7.0.6 should work with no changes

I see what is going on there; in order to preserve existing workflows, we added a check to see if the plain text credentials were on the file system and loaded another implementation for how credentials are managed, this takes precedence when exporting too; for now, snapcraft logout would clear those credentials and allow you to export (fix upcoming).

1 Like

With v7.0.7 available, reverting to v7.0.5 is no longer an option. I was able to work around this with snap refresh snapcraft --channel=6.x/stable

This should be fixed in 7.0.8 now on latest/candidate and 7.x/candidate

I will be posting small asciinema videos during the course of tomorrow (Friday) on all the login scenarios. Since 7.0.6 we addionally supported “login --with” but since then I saw folks use the “login --with” value with the new environment variable, so added a new code path to support that scenario as well.

1 Like

A couple of things to add @degville

Snapcraft 7 login --with using exported credentials from Snapcraft 6

asciicast

Snapcraft 7 login --with using exported credentials from Snapcraft 6

asciicast

Snapcraft 7 register-key

asciicast

1 Like

I’ll add them - thanks for the excellent demos!

If I am running 22.04, and I start some 22.04 LXD containers which I want to use as snapcraft build containers, should I do an independent “export-login” and credentials file creation, both on my host and in each LXD container, so that they all have distinct credentials? Or would it be sufficient to do that once on my host, then just share that credentials file with each LXD container?

I’ve just tested this and the credentials are identical with each export (at least currently), so it seems sharing credentials is sufficient.

It was totally unacceptable to ONLY find out it was going on when we had to install a new instance of services, you guys SHOULD HAVE NOTIFIED it in a better way like keeping this new login procedure as a future option while showing a deprecating message on the actual usage and later on transition to it in a more organised and professional way. Now we have a whole ecosystem of developers having all sort of problems for snapping and doing their job. And this weird and silly behaviour of turning a FORUM into a documentation is nothing but amateur, since we can not trust on everything we read and sometimes it is really difficult to distinguish between what is good and what is bad. I am totally frustrated, this is not what a linux community should be about.

Hm, login not working for me. In snapcarft 7.1.4 still not fixed.

Deployer# snapcraft login 
Cannot login with 'SNAPCRAFT_STORE_CREDENTIALS' set.                           
Recommended resolution: Unset 'SNAPCRAFT_STORE_CREDENTIALS' and try again.     
Full execution log: '/root/.cache/snapcraft/log/snapcraft-20221018-182645.670336.log'                                                                          
root@linuxHostBuildersUbuntu20:~/worker/cmake/LinuxCMakeBuilderQt6/QuasarApp/CQtDeployer# snapcraft --version 
snapcraft 7.1.4  

Full log

root@linuxHostBuildersUbuntu20:~/worker/cmake/LinuxCMakeBuilderQt6/QuasarApp/CQtDeployer# cat /root/.cache/snapcraft/log/snapcraft-20221018-182645.670336.log
2022-10-18 18:26:45.673 Starting Snapcraft 7.1.4
2022-10-18 18:26:45.678 Storing credentials for 'snapcraft' on 'dashboard.snapcraft.io' in keyring 'auth MemoryKeyring'.
2022-10-18 18:26:45.678 Cannot login with 'SNAPCRAFT_STORE_CREDENTIALS' set.
2022-10-18 18:26:45.679 Recommended resolution: Unset 'SNAPCRAFT_STORE_CREDENTIALS' and try again.
2022-10-18 18:26:45.679 Full execution log: '/root/.cache/snapcraft/log/snapcraft-20221018-182645.670336.log'
root@linuxHostBuildersUbuntu20:~/worker/cmake/LinuxCMakeBuilderQt6/QuasarApp/CQtDeployer# 

Note

I deploy on my build machine inner the lxd container

Hi, just tried with latest snapcraft 7.x, for me it is still working only with this:

Mind trying Snapcraft 7.2.0; the error message should at least be different and helpful for this situation; 7.2.0 is currently on candidate

1 Like

In clean ubuntu:20.04 and ubuntu:22.04 lxd containers, using snapcraft 7.2.10 (revision 8674) the “Using a keyring on a headless Linux system” instructions do not work. In the fresh container, after installing snapcraft I initially get

ubuntu@snapcraft-login-test-3:~$ snapcraft login
craft-store error: No keyring found to store or retrieve credentials from.                                                                                                       
Recommended resolution: Ensure the keyring is working or SNAPCRAFT_STORE_CREDENTIALS is correctly exported into the environment                                                  
For more information, check out: https://snapcraft.io/docs/snapcraft-authentication                                                                                              
Full execution log: '/home/ubuntu/.cache/snapcraft/log/snapcraft-20230125-203430.755481.log' 

as you would expect. I then install gnome-keyring. Then running

ubuntu@snapcraft-login-test-3:~$ dbus-run-session -- sh
$ gnome-keyring-daemon --unlock

gives no output at all, instead of prompting for a passphrase. I can then do one of two things, each which gives the same result: 1) I can leave the above command hanging and open a new shell in the same LXD container or 2) I can just press ctrl+D, which drops me back into my dbus-run-session -- sh shell.

In either scenario, when I then try to run snapcraft login, I get the normal prompt for my email, enter it, get a prompt for my password, enter it and press enter, and then snapcraft throws an exception and I get a whole bunch of stacktraces, as seen below:

ubuntu@snapcraft-login-test-3:~$ snapcraft login
Enter your Ubuntu One e-mail address and password.                                                                                                                               
If you do not have an Ubuntu One account, you can create one at https://snapcraft.io/account                                                                                     
Email: <redacting my email>
Password: 
Traceback (most recent call last):
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/util.py", line 48, in send_and_get_reply
    raise DBusErrorResponse(resp_msg)
jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.UnknownMethod] ('No such interface “org.freedesktop.DBus.Properties” on object at path /org/freedesktop/secrets/collection/login',)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 177, in get_default_collection
    return Collection(connection)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 45, in __init__
    self._collection.get_property('Label')
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/util.py", line 67, in get_property
    (signature, value), = self.send_and_get_reply(msg)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/util.py", line 52, in send_and_get_reply
    raise ItemNotFoundException('Item does not exist!') from resp
secretstorage.exceptions.ItemNotFoundException: Item does not exist!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/keyring/backends/SecretService.py", line 61, in get_preferred_collection
    collection = secretstorage.get_default_collection(bus)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 179, in get_default_collection
    return create_collection(connection, 'Default', 'default', session)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 159, in create_collection
    raise PromptDismissedException('Prompt dismissed.')
secretstorage.exceptions.PromptDismissedException: Prompt dismissed.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/snap/snapcraft/8674/bin/snapcraft", line 8, in <module>
    sys.exit(run())
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/cli.py", line 228, in run
    _run_dispatcher(dispatcher)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/cli.py", line 204, in _run_dispatcher
    dispatcher.run()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_cli/dispatcher.py", line 448, in run
    return self._loaded_command.run(self._parsed_command_args)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/commands/account.py", line 113, in run
    store.StoreClientCLI().login()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/store/client.py", line 216, in login
    credentials = self.store_client.login(
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_store/base_client.py", line 130, in login
    self._auth.ensure_no_credentials()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_store/auth.py", line 131, in ensure_no_credentials
    if self._keyring.get_password(self.application_name, self.host) is not None:
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/keyring/backends/SecretService.py", line 78, in get_password
    collection = self.get_preferred_collection()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/keyring/backends/SecretService.py", line 63, in get_preferred_collection
    raise InitError("Failed to create the collection: %s." % e)
keyring.errors.InitError: Failed to create the collection: Prompt dismissed..

Alternatively, if (similarly to the first route above) I leave gnome-keyring-daemon --unlock hanging in the first shell and open a new shell in the same lxd container but instead of directly running snapcraft login I run dbus-run-session -- sh and then snapcraft login, I get the following, with the stacktrace only coming after 2 minutes of nothing

ubuntu@snapcraft-login-test-3:~$ dbus-run-session -- sh
$ snapcraft login
dbus-daemon[3014]: [session uid=1000 pid=3014] Activating service name='org.freedesktop.systemd1' requested by ':1.0' (uid=1000 pid=3016 comm="snapcraft login " label="unconfined")
dbus-daemon[3014]: [session uid=1000 pid=3014] Activated service 'org.freedesktop.systemd1' failed: Process org.freedesktop.systemd1 exited with status 1
Enter your Ubuntu One e-mail address and password.                                                                                                                               
If you do not have an Ubuntu One account, you can create one at https://snapcraft.io/account                                                                                     
Email: <redacting my email>
Password: 
dbus-daemon[3014]: [session uid=1000 pid=3014] Activating service name='org.freedesktop.secrets' requested by ':1.5' (uid=1000 pid=3016 comm="/snap/snapcraft/8674/bin/python /snap/snapcraft/86" label="snap.snapcraft.snapcraft (complain)")
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
dbus-daemon[3014]: [session uid=1000 pid=3014] Failed to activate service 'org.freedesktop.secrets': timed out (service_start_timeout=120000ms)
Traceback (most recent call last):
  File "/snap/snapcraft/8674/bin/snapcraft", line 8, in <module>
    sys.exit(run())
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/cli.py", line 228, in run
    _run_dispatcher(dispatcher)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/cli.py", line 204, in _run_dispatcher
    dispatcher.run()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_cli/dispatcher.py", line 448, in run
    return self._loaded_command.run(self._parsed_command_args)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/commands/account.py", line 113, in run
    store.StoreClientCLI().login()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/snapcraft/store/client.py", line 216, in login
    credentials = self.store_client.login(
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_store/base_client.py", line 130, in login
    self._auth.ensure_no_credentials()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/craft_store/auth.py", line 131, in ensure_no_credentials
    if self._keyring.get_password(self.application_name, self.host) is not None:
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/keyring/backends/SecretService.py", line 78, in get_password
    collection = self.get_preferred_collection()
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/keyring/backends/SecretService.py", line 61, in get_preferred_collection
    collection = secretstorage.get_default_collection(bus)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 177, in get_default_collection
    return Collection(connection)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/collection.py", line 45, in __init__
    self._collection.get_property('Label')
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/util.py", line 67, in get_property
    (signature, value), = self.send_and_get_reply(msg)
  File "/snap/snapcraft/8674/lib/python3.8/site-packages/secretstorage/util.py", line 48, in send_and_get_reply
    raise DBusErrorResponse(resp_msg)
jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.TimedOut] ("Failed to activate service 'org.freedesktop.secrets': timed out (service_start_timeout=120000ms)",)
$ 

Also, as a nitpick it looks like there’s an extra closed parenthesis in the hyperlinks at the top of the post

Could you verify if running eval $(echo password | gnome-keyring-daemon --daemonize --unlock) inside the dbus session shell and before running snapcraft login works for you? When you run it with --unlock it waits for the password in stdin.

Mentioning it here in case it helps anyone else - when using Snapcraft 7 or later, it seems the SNAPCRAFT_STORE_CREDENTIALS env var and the snapcraft login command are mutually exclusive forms of authentication. In other words, if you’ve exported your credentials via snapcraft export-login and have set the env var with those contents, then you do not need to run snapcraft login (in fact you shouldn’t, because you’ll get the

Cannot login with 'SNAPCRAFT_STORE_CREDENTIALS' set.
Recommended resolution: Unset 'SNAPCRAFT_STORE_CREDENTIALS' and try again.

error if you try to).

In my case, I was adapting a previous login flow that used to work for Snapcraft 6, where the credentials were exported to a file and then passed to the snapcraft login command via the --with flag. For Snapcraft 7, at first I was under the impression that I needed to change that to export SNAPCRAFT_STORE_CREDENTIALS=$(cat <credentials-filename>) and then run snapcraft login without the --with flag. But that was wrong and led to the error above; in fact I needed to set the env var and get rid of the snapcraft login command altogether.

The docs here do technically say that (“There are currently two ways to use previously exported snapcraft credentials, either via an environment variable or by using snapcraft login --with.”); however, further down is phrased a bit ambiguously: “In addition to the above, the snapcraft login command accepts an additional --with argument to reference a login credentials file” - this makes it sound like snapcraft login accepts --with in addition to the env var, which is not the case.

It might be worth explicitly clarifying on this page that the env var and snapcraft login are two separate forms of authentication and only one should be used at a time (and perhaps the error message could call this out as well).

2 Likes

Thanks so much for letting us know, and for such a detailed report. I’ll give this a go and update the documentation to make it clearer.

Is this out of date now? git-ubuntu CI broke recently with authentication issues. When I re-issue the credentials, --with no longer works. It’s not clear to me if this is because --with is no longer supported (as opposed to deprecated), or my saved CI credentials were forced expired and renewing them requires the new mechanism. Anyway, for me, the following therefore seems out date:

There are currently two ways to use previously exported snapcraft credentials, either via an environment variable or by using snapcraft login --with.

and

Warning: The login --with argument is not supported in Snapcraft 7 and is currently included to help users migrate from the old authentication method to the new.

Hi there, if you want to keep using --with you need to generate your credentials with Snapcraft 6.

Thanks for the update (and @rbasak). I’ve updated the doc to hopefully make it clear.