Harden Gemini CLI container setup

Separate Gemini CLI installation from probing so long installs remain observable. Use Agent Zero secret aliases for GEMINI_API_KEY instead of assuming saved secrets are exported from /a0/usr/.env, with contract coverage.

Alessandro committed Jul 10, 2026 at 18:53 UTC 25d906edb778e280b81ceb1088290c7b7b092587
3 files changed +23 -5
plugins/_orchestrator/skills/orchestrator/AGENTS.md
+1
@@ -22,6 +22,7 @@
22 - `SKILL.md` must tell agents to read only the relevant reference file before acting.
23 - Claude Code reference guidance must avoid plain `claude` and bare `claude auth login` until the user chooses `--claudeai`, `--console`, `--sso`, or external API-key auth.
24 - Claude Code API-key auth must source Agent Zero secrets from `/a0/usr/.env`, not from the workdir.
25 +- Gemini CLI container runs must use `§§secret(GEMINI_API_KEY)` when that key is in Agent Zero secrets; do not assume it is exported from `/a0/usr/.env`.
26 - If a full-screen Claude Code TUI is already open, the Claude reference must reset the terminal session instead of sending Enter or `/login`.
27 - Root shells must not use Claude Code `bypassPermissions`; non-root shells may use it as the default non-interactive mode.
28 - Long-running commands should stay in a shell session and be polled there.
plugins/_orchestrator/skills/orchestrator/references/gemini.md
+19 -5
@@ -4,8 +4,22 @@ Use Gemini CLI for headless Google Gemini coding tasks. Always pass `-p`; bare `
4
5 ## Install And Probe
6
7 +Check first:
8 +
9 +```bash
10 +command -v gemini
11 +```
12 +
13 +If missing, install it as one command and wait or poll that same terminal session until it completes. Do not append version, help, or smoke commands to the install call:
14 +
15 ```bash
8 -command -v gemini >/dev/null || npm install -g @google/gemini-cli
16 +npm install -g @google/gemini-cli --no-progress
17 +```
18 +
19 +Then probe it:
20 +
21 +```bash
22 +command -v gemini
23 gemini --version
24 gemini --help
25 ```
@@ -21,12 +35,10 @@ gemini -p "Respond exactly: TERMINAL_AGENT_SMOKE_OK" --output-format json --appr
35
36 Headless mode uses existing cached Google credentials, a Gemini API key, or Vertex AI credentials. Do not start bare `gemini` through Agent Zero for login; it opens a TUI. For local browser sign-in, ask the user to run `gemini` in their own terminal, select **Sign in with Google**, finish in the browser, and then retry the smoke prompt.
37
24 -For container automation, prefer `GEMINI_API_KEY`. Ask the user to add it through **Settings > External Services > Secrets Management**, then source `/a0/usr/.env` without printing it:
38 +For container automation, prefer `GEMINI_API_KEY`. Ask the user to add it through **Settings > External Services > Secrets Management**. If `GEMINI_API_KEY` is listed in Agent Zero's available secrets, do not source `/a0/usr/.env`; pass the exact secret alias only to the Gemini process:
39
40 ```bash
27 -set -a
28 -. /a0/usr/.env
29 -set +a
41 +GEMINI_API_KEY='§§secret(GEMINI_API_KEY)' gemini -p "Respond exactly: TERMINAL_AGENT_SMOKE_OK" --output-format json --approval-mode=yolo --skip-trust
42 ```
43
44 Vertex AI may instead use `GOOGLE_API_KEY`, `GOOGLE_APPLICATION_CREDENTIALS`, or cached Application Default Credentials. It also requires `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`. Never ask the user to paste keys or service-account JSON into chat.
@@ -39,3 +51,5 @@ gemini -p "$TASK" --output-format json --approval-mode=yolo --skip-trust
51 ```
52
53 Add `-m "$MODEL"` only when the user or settings provide a model override. Use `--approval-mode=plan` instead of `yolo` when the user explicitly asks for read-only analysis.
54 +
55 +When using the saved Gemini secret for a real task, prefix the real-task command with `GEMINI_API_KEY='§§secret(GEMINI_API_KEY)'` in the same way. Never print or probe the expanded value.
plugins/_orchestrator/tests/test_status_adapters.py
+3
@@ -230,6 +230,9 @@ def test_skill_documents_human_setup_loop_and_a0_exception():
230 assert "--approval-mode=yolo" in gemini_text
231 assert "--skip-trust" in gemini_text
232 assert "GEMINI_API_KEY" in gemini_text
233 + assert "§§secret(GEMINI_API_KEY)" in gemini_text
234 + assert "do not source `/a0/usr/.env`" in gemini_text
235 + assert "Do not append version, help, or smoke commands" in gemini_text
236 assert "GOOGLE_APPLICATION_CREDENTIALS" in gemini_text
237 assert "Do not start bare `gemini`" in gemini_text
238