Snapcraft 8.4 fails to refresh credentials
Metadata
Current evaluation
Credential refresh was fixed in canonical/craft-store#212 (commit f2cd40d) by correcting a Pydantic 2 model_copy() alias regression affecting refreshed macaroons.
Resolution: closed resolved
Reason: The issue was resolved by canonical/craft-store#212, with commit f2cd40d restoring refresh-macaroon updates broken by Pydantic 2 model_copy() alias behavior.
Evaluated by: mr-cal-bot
No scores available.
Issue body
### Bug Description
Snapcraft stores a macaroon that has to be refreshed about once a day.
Snapcraft is sending a refresh request but the next API call fails with the same expired macaroon.
Source: https://forum.snapcraft.io/t/snapcraft-login-expiry-issues/41966
### To Reproduce
1. `snapcraft login`
2. `snapcraft whoami`
3. Wait 1.5 days
4. `snapcraft whoami`
### Environment
n/a
### snapcraft.yaml
```yaml
n/a
```
### Relevant log output
```shell
2024-09-18 13:28:12.379 Running snapcraft whoami on host
2024-09-18 13:28:12.380 Storing credentials for 'snapcraft' on 'dashboard.staging.snapcraft.io' in keyring 'auth MemoryKeyring'.
2024-09-18 13:28:12.380 Retrieving credentials for 'snapcraft' on 'dashboard.staging.snapcraft.io' from keyring 'auth MemoryKeyring'.
2024-09-18 13:28:12.381 HTTP 'GET' for 'https://dashboard.staging.snapcraft.io/api/v2/tokens/whoami' with params None and headers ***'Authorization': '<macaroon>', 'User-Agent': 'snapcraft/8.4.0.post6+git71c63082 ubuntu/22.04 (x86_64)'***
2024-09-18 13:28:12.984 Retrieving credentials for 'snapcraft' on 'dashboard.staging.snapcraft.io' from keyring 'auth MemoryKeyring'.
2024-09-18 13:28:12.985 HTTP 'POST' for 'https://login.staging.ubuntu.com/api/v2/tokens/refresh' with params None and headers ***'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'snapcraft/8.4.0.post6+git71c63082 ubuntu/22.04 (x86_64)'***
2024-09-18 13:28:13.555 Storing credentials for 'snapcraft' on 'dashboard.staging.snapcraft.io' in keyring 'auth MemoryKeyring'.
2024-09-18 13:28:13.555 Retrieving credentials for 'snapcraft' on 'dashboard.staging.snapcraft.io' from keyring 'auth MemoryKeyring'.
2024-09-18 13:28:13.556 HTTP 'GET' for 'https://dashboard.staging.snapcraft.io/api/v2/tokens/whoami' with params None and headers ***'Authorization': '<macaroon>', 'User-Agent': 'snapcraft/8.4.0.post6+git71c63082 ubuntu/22.04 (x86_64)'***
2024-09-18 13:28:13.729 snapcraft internal error: StoreServerError('Store operation failed:\n- macaroon-needs-refresh: Expired macaroon (age: 162165 seconds)')
2024-09-18 13:28:13.734 Traceback (most recent call last):
2024-09-18 13:28:13.735 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/ubuntu_one_store_client.py", line 144, in request
2024-09-18 13:28:13.735 response = super().request(method, url, params, headers, **kwargs)
2024-09-18 13:28:13.735 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/base_client.py", line 187, in request
2024-09-18 13:28:13.735 return self.http_client.request(
2024-09-18 13:28:13.735 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/http_client.py", line 165, in request
2024-09-18 13:28:13.735 raise errors.StoreServerError(response)
2024-09-18 13:28:13.735 craft_store.errors.StoreServerError: Store operation failed:
2024-09-18 13:28:13.735 - macaroon-needs-refresh: Expired macaroon (age: 162164 seconds)
2024-09-18 13:28:13.735
2024-09-18 13:28:13.735 During handling of the above exception, another exception occurred:
2024-09-18 13:28:13.735 Traceback (most recent call last):
2024-09-18 13:28:13.735 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_application/application.py", line 540, in run
2024-09-18 13:28:13.735 return_code = dispatcher.run() or os.EX_OK
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_cli/dispatcher.py", line 487, in run
2024-09-18 13:28:13.736 return self._loaded_command.run(self._parsed_command_args)
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/snapcraft/commands/account.py", line 258, in run
2024-09-18 13:28:13.736 whoami = store.StoreClientCLI().store_client.whoami()
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/base_client.py", line 197, in whoami
2024-09-18 13:28:13.736 return dict(self.request("GET", self._base_url + self._endpoints.whoami).json())
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/ubuntu_one_store_client.py", line 148, in request
2024-09-18 13:28:13.736 response = super().request(method, url, params, headers, **kwargs)
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/base_client.py", line 187, in request
2024-09-18 13:28:13.736 return self.http_client.request(
2024-09-18 13:28:13.736 File "/snap/snapcraft/x1/lib/python3.10/site-packages/craft_store/http_client.py", line 165, in request
2024-09-18 13:28:13.736 raise errors.StoreServerError(response)
2024-09-18 13:28:13.736 craft_store.errors.StoreServerError: Store operation failed:
2024-09-18 13:28:13.736 - macaroon-needs-refresh: Expired macaroon (age: 162165 seconds)
2024-09-18 13:28:13.736 Full execution log: '/root/.local/state/snapcraft/log/snapcraft-20240918-132812.377781.log'
```
### Additional context
| snapcraft version | credential type | macaroon refreshes? | logs |
| -- | -- | -- | -- |
| 8.3.4 | ubuntu one | ✅ | [logs](https://github.com/canonical/snapcraft/actions/runs/10922416504/job/30316959740?pr=5046#step:5:159) |
| 8.3.4 | candid | ✅ | |
| 8.3.4 | legacy | ✅ | |
| 8.4.0 | ubuntu one | ❌ | [logs](https://github.com/canonical/snapcraft/actions/runs/10909830059/job/30318978361?pr=5045#step:5:70) |
| 8.4.0 | candid | ✅ | |
| 8.4.0 | legacy | ❌ | |
It looks like this started failing with #4955 when we updated to pydantic 2 and craft-store 3.0.
The pydantic models behind the macaroon were [updated for pydantic 2](https://github.com/canonical/craft-store/pull/193/files#diff-d46cd36c48c9800f7293aa0efd123966e863fac6c2eca80e1e9fc49a6b263481), so it's very possible something has changed when unmarshalling and marshalling the model. I'll have to wait until my credentials expire again before running a debugger on [`_refresh_tokens()`](https://github.com/canonical/craft-store/blob/06a2ae840dab742cb217e35be571809d7ff69058/craft_store/ubuntu_one_store_client.py#L68).
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Credential refresh was fixed in canonical/craft-store#212 (commit f2cd40d) by correcting a Pydantic 2 model_copy() alias regression affecting refreshed macaroons. | |
| stealth/space-bunny-alpha | — | closed resolved | Fixed by canonical/craft-store#212 (commit f2cd40d), which updated refresh macaroons after the Pydantic 2 model_copy() alias regression. | |
| qwen/qwen3.6-35b-a3b | — | — | Abandoned. Snapcraft 8.4 credential refresh failure, caused by pydantic 2 serialization changes, was closed without resolution or a merged fix. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed without resolution after identifying a regression in pydantic 2 and craft-store 3.0 that broke Ubuntu One and legacy credential refresh. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed without resolution. The 8.4.0 credential refresh regression from pydantic 2 and craft-store 3.0 updates remains unaddressed with zero comments, indicating the issue was abandoned. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed without resolution. Snapcraft 8.4 fails to refresh Ubuntu One credentials due to a suspected pydantic 2 bug from PR #4955. Closure after 670 days with zero comments indicates the issue was abandoned. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Closed without resolution, likely abandoned. The author identified a pydantic 2 regression causing credential refresh failures but deferred debugging until credentials expire again. |
Update history
No update history recorded yet.
Related work
-
Likely Fixed By:
canonical/craft-store#212
(confidence 99%)
Merged as commit f2cd40d to fix the macaroon refresh regression.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #212 fix: update discharge macaroons | craft-store | merged | Merged craft-store#212 as f2cd40d, updating discharge macaroons for Pydantic 2 alias behavior and fixing Snapcraft credential refresh (#5048). | |
| #1621171 snapcraft doesn't refresh the macaroon | snapcraft (launchpad) | closed | Merged snapcore/snapcraft PR #805 as commit 60b7ef044, adding discharge-macaroon refresh so expired credentials are renewed and authorization errors are reduced. |