If you are running OpenClaw as a background native systemd user service and using the gog Workspace CLI tool for email automation, you might hit an absolute wall of an error loop. After hours of tearing apart file permissions, process contexts, and encryption trees on a headless VPS, the root architecture of why this happens—and exactly how to permanently fix it—has been solved. Here is the full post-mortem breakdown so nobody else has to waste hours on it. The Symptom Your agent calls a background gog execution hook to search your inbox, list a calendar event, or pull a drive file, and it blows up with this hyper-specific error: Plaintext gmail options: read credentials: read OAuth client secret from keyring: read secret: get secret: read encoded file keyring item: aes.KeyUnwrap(): integrity check failed. No matter how many times you pass GOG_KEYRING_PASSWORD inline or type export in your SSH terminal, the tool inside the agent interface stays completely locked up. The Three Root Causes (The Perfect Storm) 1. Systemd Process Isolation (The Ghost Wall) When you log in via SSH and export an environment variable, it belongs exclusively to your active terminal shell. Because OpenClaw runs as a background service manager (systemctl --user), it is completely blind to your terminal environment. Every time the agent runs a tool command, it passes an empty keying password down to the binary, triggering the AES unwrapping failure. 2. The Literal Quote .env Trap When trying to fix this by appending the password to global daemon configs (~/.openclaw/.env), if you use single or double quotes around your password variable like this: Bash GOG_KEYRING_PASSWORD='your_password_here' The runtime environment parser may swallow those quote marks literally. To the aes.KeyUnwrap() engine, those tick marks completely alter the cryptographic hash. The password becomes a string containing the quotes, mismatched against the raw passphrase used to encrypt the keyring file. 3. The Stray Backtick Link Corruption (%60) When attempting a headless remote handshake (gog auth add --manual), you are forced to copy a redirect URL from your local browser's address bar and paste it into the chat interface. It is incredibly easy for a trailing backtick mark (`) to hitch a ride in the copy-paste action. The browser converts this to URL-encoded %60. Because that extra character exists at the very end of the URL string, gog instantly rejects the authentication pass as a security state mismatch. The Permanent, Bulletproof Fix To resolve this permanently and ensure it survives full server reboots, you must clear the broken cryptographic handles and hardwire the environment straight into the process manager. Step 1: Wipe the Corrupted Keyring Directory Because the keyring has registered multiple conflicting unwrap attempts under mismatched quote environments, you need to flush the slate clean. Run this on your host machine: Bash # Force kill any hung background processes waiting for an interactive browser response pkill -f gog # Tear out the stale, mismatched file-keyring directories completely rm -rf ~/.config/gogcli/keyring ~/.local/share/gogcli/keyring ~/.openclaw/workspace/skills/memory-core/gogcli/keyring Step 2: Establish Systemd Service Environment Overrides To force systemd to pass the decryption keys straight to OpenClaw's core process memory, build a service unit override directory and drop the parameters directly into the manager layout: Bash # Create the dedicated drop-in unit path mkdir -p ~/.config/systemd/user/openclaw-gateway.service.d/ # Inject the environment directly into systemd (Replace 1234567 with your actual numeric passphrase) cat << 'EOF' > ~/.config/systemd/user/openclaw-gateway.service.d/override.conf [Service] Environment="PATH=/home/vps_user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Environment="GOG_KEYRING_PASSWORD=1234567" Environment="GOGCLI_KEYRING_PASSPHRASE=1234567" EOF # Reload the systemd controller memory context systemctl --user daemon-reload Step 3: Authenticate Directly From a Stable Host Shell Instead of trying to let the AI process the multi-step interactive OAuth handshake inside a sandboxed framework session, complete the initialization cleanly from your active SSH session first: Bash # Automatically locate your valid Google Cloud developer credentials JSON file on the server for file in $(find ~ -name "credentials.json" -o -name "client_secret.json" 2>/dev/null); do if GOG_KEYRING_PASSWORD=1234567 gog auth credentials "$file" 2>/dev/null; then echo "--> Success! Master client credentials registered from: $file" break fi done # Initialize a clean manual OAuth token pass GOG_KEYRING_PASSWORD=1234567 gog auth add
[email protected] --services gmail,calendar,drive,contacts --manual Copy the link to your browser, click Allow, copy the resulting blank 127.0.0.1 page URL from your address bar, ensure there are no stray trailing characters at the end, and paste it back into your terminal. Step 4: Intercept and Shadow Commands via Local Binary Priority To protect the tool from future framework sandboxing updates that strip inline execution variables, create a local execution interceptor wrapper: Bash # Locate the path of the genuine global gog binary REAL_GOG=$(which gog) mkdir -p ~/.local/bin # Build the wrapper script to handle the passphrase natively inside a subshell boundary cat << EOF > ~/.local/bin/gog #!/bin/bash export GOG_KEYRING_PASSWORD=1234567 exec $REAL_GOG "\$@" EOF # Grant execute rights to your wrapper script chmod +x ~/.local/bin/gog # Clear OpenClaw's stuck conversation cache to force a fresh tool look up rm -f ~/.openclaw/agents/main/sessions/sessions.json # Hard restart the background daemon service systemctl --user restart openclaw-gateway.service Why this works forever I HOPE!!!! By modifying the systemd unit PATH priority (/home/vps_user/.local/bin is placed first), whenever your AI agent invokes a standard string like gog gmail messages search, the systemd manager bypasses the global environment entirely and hands the execution directly to your local wrapper script. The wrapper instantly loads the raw, quote-free passphrase inside its own isolated subshell boundary before firing the master binary. Your credentials remain perfectly encrypted on disk, the agent can no longer drop or misinterpret the environment variables, and the system is permanently locked down across reboots.