CredentialsUnavailable error when getting credentials from SecretService
Metadata
Current evaluation
HTTPX authentication looks up Charmhub credentials under the full URL instead of the host name, causing a reproducible SecretService CredentialsUnavailable failure; host validation or normalization is needed.
Suggested action: keep open
Reason: The maintainer confirmed the diagnosis in the follow-up comment: hosts containing a scheme should be rejected, and the supplied steps reproduce the lookup mismatch. BaseClient already derives the keyring host with urlparse(base_url).netloc, so the fix should ensure PublisherGateway's Auth construction follows the same convention and add validation and regression tests.
Evaluated by: mr-cal-bot
Impact:
55
Quick Win:
36
Complexity:
22
Confidence:
91
Actionability:
83
Issue body
### Bug Description
For some reason I can't use my Charmcraft login from the secret service in the HTTPX Authentication.
Based on the logs I think it might be that we're asking for the credentials on `https://api.charmhub.io` rather than `api.charmhub.io`
### To Reproduce
1. `charmcraft logout`
2. Ensure that no password for api.charmhub.io exists for charmcraft in secret service
3. `charmcraft login`
4. Ensure that a password does exist (password is a base64 encoded macaroon)
5. `charmcraft promote --name=anything --from-channel=stable --to-channel=stable --yes`
### part yaml
```shell
```
### Relevant log output
```shell
2025-01-22 11:09:10.553 Setting up StoreService
2025-01-22 11:09:10.628 Getting token from keyring
2025-01-22 11:09:10.628 Getting candid from credential storage
2025-01-22 11:09:10.628 Retrieving credentials for 'charmcraft' on 'https://api.charmhub.io' from keyring 'SecretService Keyring'.
2025-01-22 11:09:10.631 Credentials not found in the keyring 'SecretService Keyring'
2025-01-22 11:09:10.631 charmcraft internal error: CredentialsUnavailable("No credentials found for 'charmcraft' on 'https://api.charmhub.io'.")
2025-01-22 11:09:10.632 Traceback (most recent call last):
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_application/application.py", line 673, in run
2025-01-22 11:09:10.632 return_code = self._run_inner()
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_application/application.py", line 654, in _run_inner
2025-01-22 11:09:10.632 return_code = dispatcher.run() or os.EX_OK
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_cli/dispatcher.py", line 494, in run
2025-01-22 11:09:10.632 return self._loaded_command.run(self._parsed_command_args)
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/charmcraft/application/commands/store.py", line 905, in run
2025-01-22 11:09:10.632 package_metadata = store.get_package_metadata(name)
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/charmcraft/services/store.py", line 216, in get_package_metadata
2025-01-22 11:09:10.632 return self._publisher.get_package_metadata(name)
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_store/publisher/_publishergw.py", line 90, in get_package_metadata
2025-01-22 11:09:10.632 response = self._client.get(
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1053, in get
2025-01-22 11:09:10.632 return self.request(
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/httpx/_client.py", line 825, in request
2025-01-22 11:09:10.632 return self.send(request, auth=auth, follow_redirects=follow_redirects)
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/httpx/_client.py", line 914, in send
2025-01-22 11:09:10.632 response = self._send_handling_auth(
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/httpx/_client.py", line 939, in _send_handling_auth
2025-01-22 11:09:10.632 request = next(auth_flow)
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/httpx/_auth.py", line 75, in sync_auth_flow
2025-01-22 11:09:10.632 request = next(flow)
2025-01-22 11:09:10.632 ^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_store/_httpx_auth.py", line 49, in auth_flow
2025-01-22 11:09:10.632 self._token = self.get_token_from_keyring()
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_store/_httpx_auth.py", line 82, in get_token_from_keyring
2025-01-22 11:09:10.632 return creds.unmarshal_candid_credentials(self._auth.get_credentials())
2025-01-22 11:09:10.632 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-01-22 11:09:10.632 File "/home/lengau/Work/Code/charmcraft/.venv/lib/python3.11/site-packages/craft_store/auth.py", line 290, in get_credentials
2025-01-22 11:09:10.632 raise errors.CredentialsUnavailable(self.application_name, self.host)
2025-01-22 11:09:10.632 craft_store.errors.CredentialsUnavailable: No credentials found for 'charmcraft' on 'https://api.charmhub.io'.
2025-01-22 11:09:10.632 Full execution log: '/home/lengau/.local/state/charmcraft/log/charmcraft-20250122-110910.550494.log'
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha |
Impact:
55
Quick Win:
36
Complexity:
22
Confidence:
91
Actionability:
83
|
keep open | HTTPX authentication looks up Charmhub credentials under the full URL instead of the host name, causing a reproducible SecretService CredentialsUnavailable failure; host validation or normalization is needed. | |
| qwen/qwen3.6-35b-a3b |
Impact:
70
Quick Win:
50
Complexity:
20
Confidence:
85
Actionability:
90
|
keep open | Credentials lookup fails because keyring service name includes URL scheme (https://api.charmhub.io) but credentials are stored under bare domain (api.charmhub.io). Root cause identified and confirmed by maintainer. | |
| qwen/qwen3.8-27b |
Impact:
50
Quick Win:
35
Staleness:
75
Complexity:
30
Confidence:
85
Support Request:
0
|
close stale | Charmcraft store commands failed with CredentialsUnavailable because keyring lookups used the full URL https://api.charmhub.io instead of the bare host api.charmhub.io. Root cause confirmed by reporter; current code now uses urlparse().netloc for keyring host references, so the mismatch appears fixed. | |
| qwen/qwen3.6-35b-a3b |
Staleness:
85
Complexity:
20
Confidence:
80
Support Request:
5
|
needs triage | Bug where credential lookup fails because the host string includes the https:// scheme instead of just the domain name, causing a CredentialsUnavailable error. Currently unlabelled and inactive for over a year. | |
| qwen3.6-35b-a3b-mtp-q6 |
Staleness:
85
Complexity:
15
Confidence:
70
Support Request:
0
|
keep open | Bug where charmcraft queries the keyring using 'https://api.charmhub.io' instead of the domain, causing credential lookup failures. Root cause identified by maintainer. |
Update history
No update history recorded yet.
Related issues
No related issues found above the similarity threshold.