7 min read

Gemini CLI: Google's Coding Agent for the Terminal (GitHub, Scanned)

Google's open-source terminal agent for Gemini models, now for paid API keys and enterprise licences.

Gemini CLI logo
✅
Scan: safe. Nothing malicious, and well run. The notes: it no longer serves free or consumer accounts, and it ships five prebuilt ripgrep binaries plus two runtime dependencies with open critical advisories. Scanned Sep 25, 2026; the full report is below.

Gemini CLI is Google's open-source coding agent for the terminal: it reads and edits your code, runs shell commands, fetches web pages, grounds answers in Google Search, and connects to MCP servers, all driven by Gemini models with a context window of up to a million tokens. It runs interactively or headless with JSON output for scripts, keeps project instructions in GEMINI.md files, and has a GitHub Action for reviews and issue triage.

The context around it has changed. In May 2026 Google announced that personal use moves to a new, separate Antigravity CLI, and since June 18, 2026 Gemini CLI no longer serves the free tier or Google AI Pro and Ultra subscribers. It still works with paid Gemini API keys, Vertex AI, and Gemini Code Assist Standard or Enterprise licences, and the repository is still active, with weekly releases under Apache-2.0. The README's free-tier section predates the change.

Who it is for

Teams on Google Cloud or a Gemini Code Assist licence who want an open-source agent in the terminal or in CI, and developers with a paid Gemini API key who want to read and control the agent they run.

Getting started

1. Install with npm (or brew install gemini-cli; npx @google/gemini-cli runs it without installing)

npm install -g @google/gemini-cli

2. Give it a paid Gemini API key, or sign in with a Code Assist licence or Vertex AI

export GEMINI_API_KEY="YOUR_API_KEY"

3. Start it in a project

cd your-project && gemini

Since June 18, 2026 personal Google accounts, the free tier and AI Pro and Ultra plans no longer work here; Google points those users to Antigravity CLI. A paid API key, Vertex AI or a Code Assist Standard or Enterprise licence still does.

Safety scan

We cloned google-gemini/gemini-cli at commit 2fe7c2d on Sep 25, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secrets: all 29 candidates are fake tokens and keys in tests, most of them in the tests for the environment sanitizer that strips real credentials before the agent runs commands. The bare IPs are test cases for its private-address check (CGNAT and benchmark ranges, 8.8.8.8).
  • The pattern hits are the Antigravity banner, which prints Google's curl | bash install command for the Antigravity CLI and does not run it, and a comment in shell-utils.ts about passing the CLI's own parser script to PowerShell with -EncodedCommand.
  • Five committed binaries: ripgrep builds for macOS, Linux and Windows in packages/core/vendor/ripgrep, about 21 MB, used by the search tool. They carry ripgrep's own project strings, but they are prebuilt files you take on trust rather than code you can read. The one installer script deploys an internal maintenance agent to a Google-internal host.
  • Known advisories: 135, 5 critical, all in the main lockfile. Two are runtime dependencies pinned in the CLI and core packages: simple-git 3.28.0 (an unsafe-operations guard bypass) and shell-quote 1.8.3 (newlines not escaped in quote()). Both need hostile input to reach; the other critical ones are Vitest and tar in the build tooling.
  • 47 workflows. Three use pull_request_target; the eval job checks out the pull request only after manual approval through a protected environment, and the other two do not run PR code. All 31 third-party actions pinned to a commit. Security policy, Dependabot and CodeQL all present.

What the scanner counted

CheckResult
Secrets29 candidates found and read; see the notes above.
Suspicious code8 pattern hits found and read; every one is listed under the raw findings.
Install-time code2 npm lifecycle scripts. 1 installer script
Committed binaries5 executable or compiled objects committed; listed under the raw findings.
CI workflows47 workflows. 3 use pull_request_target, none check out the pull request head. 0 of 31 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often auth.example.com, github.com, goo.gle, google.com. 9 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities135 advisories across 1,526 pinned packages: 5 critical, 72 high, 50 moderate, 8 low. package-lock.json: 1,513 packages, 127 advisories; tools/caretaker-agent/cloudrun/egress-service/package-lock.json: 271 packages, 7 advisories; tools/caretaker-agent/cloudrun/ingestion-service/package-lock.json: 313 packages, 9 advisories.
Project hygieneHas security policy, automated dependency updates, CodeQL, licence file, contributing guide.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (29, redacted)
WhereRuleMatch
packages/cli/src/utils/gitUtils.test.ts:84github-tokenghp_xx…xxx (40 chars)
packages/cli/src/utils/gitUtils.test.ts:91github-tokengithub…xxx (93 chars)
packages/core/src/agents/browser/browserAgentInvocation.test.ts:632private-key-----B…--- (31 chars)
packages/core/src/services/environmentSanitization.test.ts:107private-key-----B…--- (31 chars)
packages/core/src/services/environmentSanitization.test.ts:108private-key-----B…--- (35 chars)
packages/core/src/services/environmentSanitization.test.ts:109private-key-----B…--- (30 chars)
packages/core/src/services/environmentSanitization.test.ts:110private-key-----B…--- (31 chars)
packages/core/src/services/environmentSanitization.test.ts:123github-tokenghp_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:124github-tokengho_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:125github-tokenghu_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:126github-tokenghs_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:127github-tokenghr_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:128github-tokengithub…xxx (47 chars)
packages/core/src/services/environmentSanitization.test.ts:130google-api-keyAIzaSy…xxx (39 chars)
packages/core/src/services/environmentSanitization.test.ts:136stripe-live-keysk_liv…xxx (32 chars)
packages/core/src/services/environmentSanitization.test.ts:141slack-tokenxoxb-x…xxx (39 chars)
packages/core/src/services/environmentSanitization.test.ts:142slack-tokenxoxa-x…xxx (39 chars)
packages/core/src/services/environmentSanitization.test.ts:143slack-tokenxoxp-x…xxx (39 chars)
packages/core/src/services/environmentSanitization.test.ts:144slack-tokenxoxr-x…xxx (39 chars)
packages/core/src/services/environmentSanitization.test.ts:221github-tokenghp_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:238github-tokenghp_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:248private-key-----B…--- (31 chars)
packages/core/src/services/environmentSanitization.test.ts:257github-tokenghp_xx…xxx (40 chars)
packages/core/src/services/environmentSanitization.test.ts:270github-tokenghp_xx…xxx (40 chars)
and 5 more
Pattern hits (8)
WhereRuleMatch
packages/cli/src/ui/commands/helpCommand.test.ts:62download-piped-to-shelltext: `To install the Antigravity CLI on macOS, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`,
packages/cli/src/ui/commands/helpCommand.test.ts:75download-piped-to-shelltext: `To install the Antigravity CLI on Linux, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`,
packages/cli/src/ui/hooks/useBanner.test.ts:160download-piped-to-shell`Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`,
packages/cli/src/ui/hooks/useBanner.test.ts:171download-piped-to-shell`Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`,
packages/cli/src/ui/utils/antigravityUtils.test.ts:25download-piped-to-shellinstallCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
packages/cli/src/ui/utils/antigravityUtils.test.ts:36download-piped-to-shellinstallCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
packages/cli/src/ui/utils/antigravityUtils.ts:10download-piped-to-shell'curl -fsSL https://antigravity.google/cli/install.sh | bash';
packages/core/src/utils/shell-utils.ts:195powershell-encoded// Encode the parser script as UTF-16LE base64 so we can pass it via PowerShell's -EncodedCommand flag;
URLs to bare IP addresses (9)
WhereRuleMatch
packages/core/src/utils/fetch.spec.ts:211ip-literal-url'http://100.64.0.1:8080/',
packages/core/src/utils/fetch.spec.ts:212ip-literal-url'http://100.127.255.254/',
packages/core/src/utils/fetch.spec.ts:213ip-literal-url'http://198.18.0.1:8080/',
packages/core/src/utils/fetch.spec.ts:214ip-literal-url'http://198.19.255.254/',
packages/core/src/utils/fetch.spec.ts:389ip-literal-urlexpect(await isPrivateIp('http://8.8.8.8/')).toBe(false);
packages/core/src/utils/fetch.spec.ts:390ip-literal-urlexpect(await validateUrlDestination('http://8.8.8.8/')).toBe(true);
packages/core/src/utils/fetch.spec.ts:391ip-literal-urlexpect(await isPrivateIp('http://93.184.216.34/')).toBe(false);
packages/core/src/utils/fetch.spec.ts:392ip-literal-urlexpect(await validateUrlDestination('http://93.184.216.34/')).toBe(true);
packages/core/src/utils/fetch.test.ts:144ip-literal-urlexpect(await isPrivateIp('http://8.8.8.8/')).toBe(false);
npm lifecycle scripts (2)
  • package.json prepare: husky && npm run bundle
  • packages/vscode-ide-companion/package.json prepare: npm run generate:notices
Installer scripts (1)
Committed binaries (5)
  • packages/core/vendor/ripgrep/rg-linux-x64: ELF, 5 MB
  • packages/core/vendor/ripgrep/rg-win32-x64.exe: PE (Windows executable), 5 MB
  • packages/core/vendor/ripgrep/rg-darwin-x64: Mach-O, 4 MB
  • packages/core/vendor/ripgrep/rg-linux-arm64: ELF, 4 MB
  • packages/core/vendor/ripgrep/rg-darwin-arm64: Mach-O, 3 MB
Worst known vulnerabilities (24 of 135)
AdvisorySeverityPackageSummary
GHSA-w7jw-789q-3m8pcriticalshell-quote@1.8.3shell-quote quote() does not escape newlines in object .op values
GHSA-r275-fr43-pm7qcriticalsimple-git@3.28.0simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key enables RCE
GHSA-5xrq-8626-4rwpcriticalvitest@3.2.4When Vitest UI server is listening, arbitrary file can be read and executed
GHSA-23hp-3jrh-7fpwcriticaltar@7.5.11node-tar: Decompression/parse DoS via unlimited input
GHSA-5xrq-8626-4rwpcriticalvitest@3.1.1When Vitest UI server is listening, arbitrary file can be read and executed
GHSA-3jxr-9vmj-r5cphighbrace-expansion@1.1.14brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups
GHSA-mh99-v99m-4gvghighbrace-expansion@1.1.14brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
GHSA-rgw5-rvv9-x895highbrace-expansion@1.1.14brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
GHSA-5375-pq7m-f5r2high@grpc/grpc-js@1.14.3@grpc/grpc-js: A malformed request can cause a server crash
GHSA-99f4-grh7-6pcqhigh@grpc/grpc-js@1.14.3@grpc/grpc-js: An incoming malformed compressed message can cause a client or server crash
GHSA-345p-7cg4-v4c7high@modelcontextprotocol/sdk@1.23.0@modelcontextprotocol/sdk has cross-client data leak via shared server/transport instance reuse
GHSA-8r9q-7v3j-jr4ghigh@modelcontextprotocol/sdk@1.23.0Anthropic's MCP TypeScript SDK has a ReDoS vulnerability
GHSA-w48q-cv73-mx4whigh@modelcontextprotocol/sdk@1.23.0Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protection by default
GHSA-45rx-2jwx-cxfrhigh@opentelemetry/propagator-jaeger@2.7.1OpenTelemetry JavaScript: Denial of service in `JaegerPropagator` via unhandled exception on a malformed header
GHSA-2883-xcg3-v3hhhighjs-yaml@3.14.2js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources
GHSA-52cp-r559-cp3mhighjs-yaml@3.14.2js-yaml: YAML merge-key chains can force quadratic CPU consumption
GHSA-5p4m-2wfm-xmqjhighjs-yaml@3.14.2JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) - CVE-2026-59870 fix not backported
GHSA-hmw2-7cc7-3qxxhighform-data@2.5.5form-data: CRLF injection in form-data via unescaped multipart field names and filenames
GHSA-3jxr-9vmj-r5cphighbrace-expansion@5.0.5brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups
GHSA-mh99-v99m-4gvghighbrace-expansion@5.0.5brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
GHSA-rgw5-rvv9-x895highbrace-expansion@5.0.5brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
GHSA-3jxr-9vmj-r5cphighbrace-expansion@2.1.0brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups
GHSA-mh99-v99m-4gvghighbrace-expansion@2.1.0brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
GHSA-rgw5-rvv9-x895highbrace-expansion@2.1.0brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
Workflows worth a look

By the numbers

Stars107.2K
Forks14.6K
Contributors699
Commits6,443
Open issues529
Open pull requests278
Releases640
Latest releasev0.61.0
LicenceApache-2.0
Main languageTypeScript
Project age1 year
Last pushSep 26, 2026
Tracked files3,017
Lines of code751.5K
Checkout size108 MB

Lines by language: TypeScript 678.9K, Markdown 32.4K, JavaScript 13.1K, JSON 9,231, YAML 9,029, Python 5,905.

Questions

Is Gemini CLI free?

The software is Apache-2.0 and free, but free use of the model ended on June 18, 2026: Gemini CLI no longer serves the free tier, personal Google sign-in, or Google AI Pro and Ultra. It works with a paid Gemini API key billed per token, Vertex AI, or a Gemini Code Assist Standard or Enterprise licence.

What is Antigravity CLI, and is Gemini CLI going away?

Antigravity CLI is Google's new terminal agent, written in Go, which takes over personal and consumer-plan use. Gemini CLI remains for paid API keys, Vertex AI and enterprise Code Assist licences, and the repository is still releasing weekly. If you signed in with a personal Google account, you have to move to Antigravity CLI or a paid key.

Does Gemini CLI run commands without asking?

Not by default: it asks before shell commands and file changes, and a trusted-folders setting controls where it may act at all. A --yolo flag approves everything, and optional sandboxing runs tools in a container or under macOS Seatbelt. Either way, the files it reads are sent to Gemini as context.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.