[BUG] Desktop Linux on ChromeOS/Crostini: silent fallback to unencrypted storage — "sign-in won't be saved" despite working gnome-keyring

Open 💬 0 comments Opened Jul 15, 2026 by pipedreambomb

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

NB: I have been in the backseat for this thing. The issue is definitely real, and the solution has definitely been working as I've restarted Claude Desktop quite a few times. But it's been Claude Code fixing itself this entire time, including this bug report. I'm just the supervisor, I guess! I can't vouch for all of it... or understand it.

On ChromeOS Crostini, AKA Linux on ChromeOS, (official claude-desktop .deb, Debian 13 container), every launch shows:

⚠️ Your sign-in won't be saved on this device. Install and unlock a system keyring (such as GNOME Keyring), then restart the app.

The warning is misleading: GNOME Keyring is installed, running, and unlocked. The app's session token is stored unencrypted and sign-in does not persist.

Root cause: Chromium's os_crypt backend auto-detection picks the portal backend (org.freedesktop.impl.portal.Secret). On Crostini this D-Bus name is activatable but has no working implementation — neither xdg-desktop-portal-gtk nor ChromeOS's desktop.cros portal backend provides the Secret interface. Init fails (Local State records "os_crypt":{"portal":{"prev_init_success":false}}) and the app silently falls back to unencrypted storage instead of trying the functional gnome-libsecret backend. A contributing factor is that Crostini sets XDG_CURRENT_DESKTOP=X-Generic, which defeats desktop-environment-based detection.

Launching with claude-desktop --password-store=gnome-libsecret fully resolves it: a Claude Safe Storage item (schema chrome_libsecret_os_crypt_password_v2) appears in the default keyring collection, the warning stops, and sign-in survives app/VM restarts.

Given ChromeOS's Linux environment is a large population of Debian-based desktop Linux users, this likely affects most Chromebook installs of the official .deb. Independent report of the same issue + same fix: https://note.com/sho_ai_magic3975/n/n410966a4f543

What Should Happen?

When the portal Secret backend fails to initialize, the app should fall back to probing org.freedesktop.secrets directly (gnome-libsecret) before resorting to unencrypted storage — or the launcher/.desktop file should detect Crostini (e.g. SOMMELIER_VERSION env var, or XDG_CURRENT_DESKTOP=X-Generic combined with a functioning org.freedesktop.secrets) and pass --password-store=gnome-libsecret.

At minimum, the warning should be actionable: tell the user which backend was tried and that --password-store=gnome-libsecret exists. The current message sends users hunting for a keyring they already have installed and unlocked.

Error Messages/Logs

UI warning: "Your sign-in won't be saved on this device. Install and unlock a system keyring (such as GNOME Keyring), then restart the app."

~/.config/Claude/"Local State" after failed init:
{"os_crypt":{"portal":{"prev_desktop":"X-Generic","prev_init_success":false}},...}

Keyring is demonstrably healthy (daemon running, default collection unlocked):
$ gdbus call --session --dest org.freedesktop.secrets --object-path /org/freedesktop/secrets/collection/Default_5fKeyring --method org.freedesktop.DBus.Properties.Get string:org.freedesktop.Secret.Collection string:Locked
(<false>,)

After launching with --password-store=gnome-libsecret, the safe-storage key is created and persists:
Item label: 'Claude Safe Storage'
Attributes: {'application': 'Claude', 'xdg:schema': 'chrome_libsecret_os_crypt_password_v2'}

Steps to Reproduce

  1. On a Chromebook with Linux (Crostini) enabled — Debian 12/13 container — install the official package: sudo apt install claude-desktop (from the downloads.claude.ai apt repo)
  2. Ensure gnome-keyring is installed and unlocked (sudo apt install gnome-keyring; default collection unlocked — verifiable via the gdbus call in the logs section)
  3. Launch Claude Desktop (launcher icon or claude-desktop in the terminal) and sign in
  4. Observe the "Your sign-in won't be saved on this device" warning banner despite the working keyring; note "prev_init_success":false under os_crypt.portal in ~/.config/Claude/"Local State", and no Claude Safe Storage item in the keyring
  5. Quit, relaunch as claude-desktop --password-store=gnome-libsecret
  6. Warning is gone; Claude Safe Storage item now exists in the keyring; sign-in persists across app and VM restarts

Claude Model

Sonnet (default)

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

Claude Desktop 1.21459.0 (Electron 42.5.1), official .deb

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Other

Additional Information

Workaround for affected users until patched:

Override the desktop entry so launcher launches carry the flag:

cp /usr/share/applications/com.anthropic.Claude.desktop ~/.local/share/applications/
sed -i 's|^Exec=claude-desktop|Exec=env XDG_CURRENT_DESKTOP=GNOME claude-desktop --password-store=gnome-libsecret|' ~/.local/share/applications/com.anthropic.Claude.desktop
update-desktop-database ~/.local/share/applications

And for terminal launches, a wrapper in ~/.bashrc:

claude-desktop() {
    command claude-desktop --password-store=gnome-libsecret "$@"
}

Environment: ChromeOS Crostini (termina VM / penguin container), Debian 13 trixie, Wayland via sommelier, XDG_CURRENT_DESKTOP=X-Generic, gnome-keyring 0.21.7 (libsecret 0.21.7).

(Related but separate ChromeOS-side issue, being reported to Google: on a cold Crostini VM start, the ChromeOS launcher's app-launch request is dropped by vm_cicerone — "Garcon channel not connected after 5 seconds" — and never retried, so the app doesn't open even once storage is fixed. Not an Anthropic bug; noted so Chromebook users finding this issue have the complete picture.)

View original on GitHub ↗