Install
gog ships as a single binary. The visible version is injected at build time: release builds use the tag, while local builds use git describe.
#Homebrew (macOS, Linux)
Prebuilt macOS binaries require macOS 15 or later on both Apple Silicon and Intel.
brew install openclaw/tap/gogcli
gog --version
The Homebrew formula lives in openclaw/homebrew-tap and installs the gog binary. Release verification should run:
brew test openclaw/tap/gogcli
gog --version
#Docker / GHCR
The separate Docker workflow publishes a non-root GitHub Container Registry image. Tags created by the unified release workflow do not trigger it automatically; maintainers dispatch Docker after release publication. Once the Docker workflow succeeds:
docker run --rm ghcr.io/openclaw/gogcli:latest version
docker run --rm ghcr.io/openclaw/gogcli:v0.43.0 version
Authenticated container runs should mount a persistent GOG_HOME directory and use the encrypted file keyring:
docker volume create gogcli-state
docker run --rm -it \
-e GOG_HOME=/persist/gogcli \
-e GOG_KEYRING_BACKEND=file \
-e GOG_KEYRING_PASSWORD \
-v gogcli-state:/persist/gogcli \
ghcr.io/openclaw/gogcli:latest \
auth add you@gmail.com --services gmail,calendar,drive
The image pre-creates /persist/gogcli owned by its non-root gog user (uid 10001), and Docker seeds an empty named volume from the image, so the volume is writable on the first run. Two cases keep their existing ownership and need a one-time fix before authenticating: a bind-mounted host directory, and a non-empty volume that was first used with an image older than this change. Give the whole tree to the runtime user (swap in -v /path/on/host:/persist/gogcli for a bind mount):
docker run --rm --user 0 --entrypoint chown \
-v gogcli-state:/persist/gogcli \
ghcr.io/openclaw/gogcli:latest -R 10001:10001 /persist/gogcli
Keep GOG_KEYRING_PASSWORD in the shell session or your CI secret store. Do not bake it into images, scripts, or checked-in profiles. See Paths and State for GOG_HOME, per-kind GOG_*_DIR overrides, and legacy path compatibility.
#Headless agents and systemd
For headless agents, configure gog with the encrypted file keyring and pass the same environment to the process that will actually invoke gog. A command working in your login shell only proves that shell has the password; it does not prove a systemd service, gateway, or agent subprocess inherited it.
Use this as the minimum runtime environment:
Environment=GOG_KEYRING_BACKEND=file
Environment=GOG_KEYRING_PASSWORD=replace-with-secret-manager-injection
Environment=GOG_HOME=/var/lib/gogcli
Environment=HOME=/home/openclaw
Then reload and restart the service before testing the OAuth-backed file-keyring setup from the same entrypoint the agent uses:
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
systemctl --user show openclaw-gateway.service \
--property=Environment
openclaw agent --agent main --message \
'Run: doctor_json="$(gog --no-input --json auth doctor --check)" &&
printf "%s\n" "$doctor_json" | jq -se "length == 1 and .[0].status == \"ok\"" >/dev/null &&
gog gmail search "newer_than:1d" --max 1 --json'
If the shell command succeeds but the agent still reports keyring.password, fix the agent or service environment first. Re-authenticating usually does not help when gog auth doctor --check already shows readable tokens in the shell. The JSON predicate is required for gating: auth doctor exits successfully when it emits a diagnostic report, even if that report has failed checks. For service accounts, Application Default Credentials, or GOG_ACCESS_TOKEN, use a least-privilege service read instead; doctor does not validate those authentication routes.
#Windows
Download the matching ZIP from the latest release:
gogcli_<version>_windows_amd64.zipgogcli_<version>_windows_arm64.zip
Extract gog.exe and put its directory on PATH.
#GitHub releases (raw binaries)
Release assets are uploaded by GoReleaser:
gogcli_<version>_darwin_amd64.tar.gzgogcli_<version>_darwin_arm64.tar.gzgogcli_<version>_linux_amd64.tar.gzgogcli_<version>_linux_arm64.tar.gzgogcli_<version>_windows_amd64.zipgogcli_<version>_windows_arm64.zipchecksums.txt
Browse the releases page for the latest tag and the full asset list.
#Build from source
git clone https://github.com/openclaw/gogcli.git
cd gogcli
make
./bin/gog --version
Source builds require at least the go version declared in go.mod (Go 1.26.0). The toolchain directive recommends Go 1.27.3 for normal builds and CI; Docker uses the same preferred toolchain. Environments with GOTOOLCHAIN=local, including CodeQL default setup, can use their installed Go 1.26 toolchain; CI tests that minimum series on Go 1.26.10.
#Safety-profile binaries
When gog is going to be invoked by an agent, sandbox, or other caller that should not be able to broaden its own permissions, build a safety-profile binary instead of the default one. See Safety Profiles.
./build-safe.sh safety-profiles/agent-safe.yaml -o bin/gog-agent-safe
./build-safe.sh safety-profiles/readonly.yaml -o bin/gog-readonly
#Verify the install
gog --version
gog auth keyring # report current keyring backend
gog --help # discover top-level commands
After running gog auth credentials and gog auth add, gog auth doctor --check reports keyring health, refresh-token validity, and Workspace-specific failure modes.
#Updating
- Homebrew:
brew upgrade openclaw/tap/gogcli. - Docker: pull a new tag (
ghcr.io/openclaw/gogcli:vX.Y.Z). - GitHub release archives: download the new tarball/ZIP and replace the
- Source builds:
git pull && make— the version string comes from
binary.
git describe.
Refresh tokens and OAuth clients are forward-compatible across point releases; no migration step is required for normal upgrades.