Skip to content

fix(auth): keep credentials.enc when it cannot be decrypted - #973

Open
curtisholtt wants to merge 1 commit into
googleworkspace:mainfrom
curtisholtt:fix/886-preserve-credentials
Open

curtisholtt wants to merge 1 commit into
googleworkspace:mainfrom
curtisholtt:fix/886-preserve-credentials

Conversation

@curtisholtt

Copy link
Copy Markdown

Description

Fixes #886.

When credentials.enc can't be decrypted, load_credentials_inner currently deletes it, along with token_cache.json and sa_token_cache.json, and then reports "No credentials found". This PR keeps those files. Other credential sources (plaintext, ADC) are still tried in the same order as before. If none is found, the error now names the decryption failure and the keyring backend setting:

Could not decrypt saved credentials at ~/.config/gws/credentials.enc: OS keyring failed: Platform secure storage failure: ...
The file was left in place. If it was saved with GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file, set that variable to `file` and retry. Otherwise run `gws auth login` to replace it.

Why deleting is the wrong recovery: the most common cause isn't a stale file. The key is simply unreadable from the current process. I hit this on macOS with a login saved under GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file: any process that started gws without that variable (a launchd job, a zsh or non-login shell, an MCP server) used the Keychain backend, hit "Platform secure storage failure", and deleted a login that still worked everywhere else. It recurred several times a day until I traced it. The comments on #886 describe the same deletion from other triggers: a changed install path, several clients sharing one config directory, and a process denied Keychain interaction. In each case the credentials are still valid. Since gws auth login overwrites the file, nothing needs cleaning up here.

Reproduction against a real login (a copy of the config directory, macOS, backend unset):

  • Before: Warning: removing undecryptable credentials file ..., then 401 "No credentials found", and credentials.enc is gone.
  • After: the error above. credentials.enc and token_cache.json are still there, and the same directory works with GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file.

Tests:

  • test_load_credentials_corrupt_encrypted_file_is_removed is now ..._is_preserved. It asserts the file is kept and the error mentions the decryption failure and the backend variable.
  • test_load_credentials_corrupt_encrypted_falls_through_to_plaintext still checks the plaintext fallback, now with the file kept.
  • New: test_load_credentials_decryption_failure_keeps_token_caches.

Dry Run Output:

// Not applicable: no API request changes

Checklist:

  • My code follows the AGENTS.md guidelines (no generated google-* crates).
  • I have run cargo fmt --all to format the code perfectly.
  • I have run cargo clippy -- -D warnings and resolved all warnings. No new warnings. With the current stable toolchain (rustc 1.99.1), clippy reports two lints that already fail on main without this change (auth.rs:140 must_use and helpers/script.rs:173 collapsible if), so I left them out of this PR.
  • I have added tests that prove my fix is effective or that my feature works. cargo test --workspace: 702 passed.
  • I have provided a Changeset file (e.g. via pnpx changeset) to document my changes.

@changeset-bot

changeset-bot Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2063544

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@google-cla

google-cla Bot commented Oct 31, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

A decryption failure no longer deletes credentials.enc, token_cache.json
or sa_token_cache.json. Other credential sources are still tried. If none
is found, the error now explains the decryption failure and points at
GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND instead of "No credentials found".

The common trigger is a process that cannot read the key, for example the
macOS Keychain being unavailable to a launchd job, or a login saved with
the file backend being read by a process that uses the keyring backend.
Deleting the file there destroys a login that still works elsewhere, and
a later `gws auth login` overwrites the file anyway.

Fixes googleworkspace#886
@curtisholtt
curtisholtt force-pushed the fix/886-preserve-credentials branch from 8f8c176 to 2063544 Compare October 31, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Credentials file is silently deleted when decryption fails — user is logged out with no error explaining why

1 participant