Govern Gemini CLI with DVARA
Gemini CLI sends its model calls straight to Google. From 1.9.0 DVARA serves
Gemini's generateContent API under /v1/gemini. Point Gemini CLI at the
DVARA AI governance platform and every model call it makes is governed and billed to one DVARA workspace.
Tested with Gemini CLI 0.63.0.
What DVARA governs
Each model call runs the same controls as /v1/chat/completions: policy, PII
rules, guardrails (on the system instruction too), budgets, rate limits, cost
records and the audit chain. Tool calls the model asks for, and the results
Gemini CLI sends back, are checked like any other text.
Point Gemini CLI at DVARA
You need:
- A running DVARA 1.9.0 Gateway that Gemini CLI can reach.
- A provider for the model you pick. For Gemini models, set
GEMINI_API_KEYon the Gateway, or route the model name to another provider. - A DVARA workspace API key. If the key has scopes, it needs
completions:write. - Gemini CLI 0.63 or later. Very old releases (0.1.x) send their first request straight to Google, whatever base URL you set. Do not use them.
1. Set the base URL and the key where Gemini CLI runs:
export GOOGLE_GEMINI_BASE_URL=https://gateway.acme.example.com/v1/gemini
export GEMINI_API_KEY=<dvara-workspace-key> # a DVARA key, not a Google key
Gemini CLI sends the key in the x-goog-api-key header. DVARA never reads a
key from the URL, because URLs end up in logs.
2. Tell Gemini CLI to use an API key. In ~/.gemini/settings.json:
{
"security": {
"auth": {
"selectedType": "gemini-api-key"
}
}
}
Without it, a headless run (gemini -p) stops with "Invalid auth method
selected".
3. Deny Gemini CLI's web search and web fetch tools. Add a policy file,
for example ~/.gemini/policies/dvara.toml:
[[rule]]
toolName = ["google_web_search", "web_fetch"]
decision = "deny"
priority = 100
These two tools ask Google to search or fetch the web for the model. DVARA refuses those requests (see below), so deny the tools and the model will not try them.
4. Start Gemini CLI with a model your Gateway routes:
gemini -m <gemini-model-id>
For a headless run in a folder Gemini CLI has not seen before, also set
GEMINI_CLI_TRUST_WORKSPACE=true, or it asks whether to trust the folder.
What happens on each route
On a route to Gemini, DVARA sends the request on as Gemini CLI sent it: every field and part, including thinking settings and thought signatures. It changes only what governance changes, such as redacted text. Gemini's answer, plain or streamed, comes back the same way. Usage and cost come from Gemini's own figures, including thinking and cached tokens.
On a route to another provider, DVARA translates: the system instruction,
the function declarations, and the calls and their results become what that
provider understands, and the answer is written back in Gemini's shape.
Settings that only tune Gemini, such as thinking settings, topK and safety
settings, are left out.
When a PII rule or guardrail changes or holds an answer, parts DVARA does not read, such as code or inline data, are still delivered.
What DVARA refuses
| Refused | Why | What to do |
|---|---|---|
| Tools Google runs itself: Google Search, URL context, code execution | What they fetch or run is never checked | Add the policy file in step 3 |
cachedContent | The content lives at Google, outside the Gateway | — |
| More than one candidate | — | — |
A key in the URL (?key=) | URLs end up in logs | Send the key in a header |
Every refusal, including one Gemini makes before its stream starts, comes back as an HTTP error with JSON in Google's error shape, so Gemini CLI shows the reason. For example:
{"error": {"code": 403, "message": "API key is not scoped for this endpoint. ...", "status": "PERMISSION_DENIED"}}
Known limits
- Long turns can stop at the response cap. Gemini CLI sends no output
limit, so DVARA's default response cap becomes the limit. Gemini counts its
thinking inside that limit. If long agent turns stop with
MAX_TOKENS, ask your operator to raise the Gateway's default response cap. - A Google sign-in cannot be routed. Gemini CLI signed in with a Google account does not use a custom base URL. Use a DVARA key as above.
- Gemini CLI's local actions are not governed. File edits and shell commands run on the developer's machine.
Troubleshooting
- Gemini CLI prints
[object Object]and stops. The model provider answered with a rate-limit or quota error (HTTP 429). Gemini CLI retries it ten times ("Retrying with backoff...") and then prints the error without formatting it. This is how Gemini CLI reports the error, not a DVARA fault. Wait and try again, or ask your operator to check the provider's quota.
Where to go next
- Gemini generateContent API for the endpoints and what each accepts.
- Agent sessions to tie a session's calls together.