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