feat: Fix keychain issues and add fs fallback#10
Merged
Conversation
- Add missing features for `keyring` to make it actually work instead of being a no-op (grr) - Allow option for storing token in a file as a fallback for keychain issues (disabled by default) - Add ability to get debug logging
There was a problem hiding this comment.
Pull request overview
This PR aims to make PKCE auth token persistence reliable by fixing keychain backend configuration and adding an opt-in file-based fallback for environments where the system keychain is unavailable, along with additional debug/warn logging around keychain operations.
Changes:
- Add
keyringOS-specific feature flags so keychain storage is functional on Linux/macOS/Windows. - Add an opt-in file fallback for token storage when keychain operations fail.
- Add tracing logs around keychain read/write failures and fallback usage.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
src/auth/pkce.rs |
Implements file fallback storage/removal and adds keychain error logging. |
Cargo.toml |
Configures keyring with OS-specific backend features. |
Cargo.lock |
Updates lockfile for new/changed transitive dependencies pulled in by keyring features. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…, fix CI doc tests - delete_token_from_keychain: clone service before closure so the JoinError warning includes the service name; log WARN when Entry::new fails (consistent with read/write helpers) - load_token_from_keychain: best-effort delete the keychain entry when its JSON is corrupt, preventing repeated warnings on every run - ci.yml: add --features pkce-auth to the Doc Tests step so the pkce module's no_run example is compile-checked in CI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
## Summary Addresses all findings and test gaps from the deep review of #10. - **Finding 1** — Log WARN when the best-effort self-heal delete of a corrupt keychain entry fails, matching the diagnostic pattern in `delete_token_from_keychain`. Previously the error was silently discarded, causing the corrupt-entry warning to fire on every subsequent load. - **Finding 2** — Fix `SAFETY` comment in `EnvVarGuard::drop` to state the invariant directly (`XDG_MUTEX is held`) without referencing `with_xdg_config_home` specifically, since the mutex is also acquired directly in some tests. - **Finding 4** — Reject leading space and `DEL` byte (`0x7F`) in `is_safe_path_component`, mirroring the existing trailing-space rejection. A leading space produces an invisible path component in directory listings. - **Finding 5** — Move `json` into the keychain write closure and return it back, so only one serialized copy of the token material is on the heap at a time in the normal path (eliminates the redundant `json.clone()`). On task panic/cancel, re-serialize as a fallback. - **Finding 6** — Update `list_environments` doc comment to explicitly note that file-fallback tokens from a prior session are not enumerated, not just keychain tokens. - **Test gap** — Add `is_safe_path_component_rejects_empty_string`, `is_safe_path_component_rejects_leading_space_and_del`, `list_environments_returns_only_cached_keys`, and `list_environments_returns_empty_without_cache` tests. ## Test plan - [ ] `cargo fmt --all --check` passes - [ ] `cargo clippy --all-targets --features pkce-auth -- -D warnings` passes - [ ] `cargo test --all-targets --features pkce-auth` passes (229 tests) - [ ] `RUSTDOCFLAGS='-D warnings' cargo doc --no-deps --features pkce-auth` passes
jgowdy-godaddy
approved these changes
Jun 1, 2026
## Summary - The `Docs` CI step ran `cargo doc --no-deps` without `--features pkce-auth`. The `Doc Tests` step already ran both; the doc-build step did not. This meant broken intra-doc links or missing-docs violations in feature-gated items would not be caught. - Run the doc build twice: once without and once with `--features pkce-auth`. ## Test plan - [ ] CI Docs step passes with both invocations green
Collaborator
|
Two follow-up branches were pushed to address findings from a deep review: Merged (#11):
Open (#12):
|
jpage-godaddy
pushed a commit
that referenced
this pull request
Jun 1, 2026
🤖 I have created a release *beep* *boop* --- ## [0.1.2](cli-engine-v0.1.1...cli-engine-v0.1.2) (2026-06-01) ### Features * Allow hard-coded redirect URL ([#9](#9)) ([e24dc24](e24dc24)) * Fix keychain issues and add fs fallback ([#10](#10)) ([853a98a](853a98a)) ### Bug Fixes * Allow Ctrl+C to work while waiting on OAuth flow ([#7](#7)) ([2b6d10e](2b6d10e)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
keyringto make it actually work instead of being a no-op (grr)