SafetyCard Request a review

goose

Extensible open-source AI agent (CLI + desktop) that installs, executes, edits and tests

github.com/aaif-goose/goose · 2026-10-03 · 591edd4

Defense-in-depth score

2.1 / 10

goose ships in Auto mode, which runs every shell command, file write and extension call without asking, directly on the host with the user's full environment and credentials. A per-call Approve mode exists but is opt-in, and its enforcement does not cover every path. The most serious issue is that plugins committed to a repository's .agents/plugins folder are auto-enabled, so opening goose in a cloned repo can launch that repo's MCP servers and hook scripts with no prompt. Run it in a disposable VM or container and switch to Approve mode before pointing it at untrusted code.

Safest setup

goose keeps provider keys in the OS keychain, records every session to a local database, and caps each run at a fixed number of turns. As shipped it runs every shell command and file write without asking, directly on your machine with your full credentials, so the safest setup turns on per-call approval and builds the boundaries around goose yourself.

SetupHowWhat it gives you
A separate, narrow identityRun goose as its own OS user, or in an environment holding only the keys and logins this task needs, read-only where the provider allowsWhatever a command does, it reaches only the accounts and access you chose, not everything your shell is logged into C1
Reviewed project filesBefore starting goose in a cloned repository, read its .agents/plugins folder, .goosehints and AGENTS.md, or start in a directory without themPlugins, hooks and instructions that load with the project are ones you have read C6
Per-call approvalGOOSE_MODE=approve in the environment, or GOOSE_MODE: approve in the config fileYou see the exact tool and arguments before each call runs C2
Only the extensions neededIn goose configure, use Toggle Extensions to keep on only the extensions the task usesThe model is offered fewer tools, with shell and write access only where you chose them C3
The injection scannerSECURITY_PROMPT_ENABLED: true in the config fileTool calls that look like a prompt injection pause for your decision C5
A lower turn capGOOSE_MAX_TURNS: <n> in the config file, below the default 1000Each run stops after a number of turns that fits the task C10
Its own container or VMRun goose itself in a disposable container or VM with outbound access limited to your model provider and the hosts the task needsAn outer boundary around model-written commands, extensions and hooks, and a narrow path for data to leave C4

Approving with confidence

  • Read each prompt and approve calls one at a time; Always Allow covers every later call to that tool, the whole shell included.
  • Approve mode does not cover every path, so keep the container or VM in place as well.

Handling data

  • The session database and the CLI's request logs keep tool arguments, results and model requests unredacted; store them like the data goose read.
  • Stopping a session ends the shell but not processes it started in the background, so check for leftovers after a stop.

Key gaps (5)

  1. Plugins under the working directory's .agents/plugins are auto-enabled, and their hook commands (including SessionStart) and MCP servers run on the host with no trust prompt. C6 · Memory, context & configuration integrity
  2. A cloned repo's plugin MCP servers and hooks are launched by default without user consent. C7 · Third-party extensions
  3. In the default Auto mode a hijacked session can exfiltrate secrets and take irreversible actions with no human in the loop. C5 · Untrusted input blast radius
  4. Model-written shell commands run unsandboxed on the host with the full inherited environment. C4 · Code-execution isolation
  5. Every tool runs with the user's ambient credentials; nothing narrows or checks authority. C1 · Identity & least privilege

Criteria

C1 Identity & least privilege

0.00 / 1.00

goose runs as the logged-in user with no narrowing of that authority. The shell tool starts bash with the full inherited environment, so every API key, cloud credential chain, SSH agent socket and gh/git login available to the user is available to model-written commands, and no subprocess anywhere clears its environment. There is no per-tool identity or authorization layer; in the default Auto mode every tool call is allowed. A hijacked session therefore holds the user's entire account across every service they are logged into.

C2 Approval gates

0.38 / 1.00

Approval is off by default: goose's default mode is Auto, which approves every tool call (shell, file writes, extension tools) without asking, and the first-run setup preselects Auto. An Approve mode exists that shows the exact tool name and arguments for each call and offers Allow, Always Allow, Deny and Cancel, with user-set per-tool permission levels. Even in Approve mode, the gate does not cover every path, plugin hooks run outside it, and Always Allow covers a whole tool such as the shell. Nothing in goose offers checkpoints or undo for shell side effects.

C3 Tool & action scoping

0.13 / 1.00

The default tool set is as broad as it gets: an arbitrary shell command string, file write/edit that accepts any absolute path on the machine, and an image reader that fetches any http(s) URL. There is no path containment, URL allowlist, or command allowlist on any built-in tool. Extensions can be toggled off as a whole, but the Developer extension with shell and write tools is on by default.

C4 Code-execution isolation

0.20 / 1.00

Model-written shell commands run directly on the host as the user through bash -c, with no container, OS sandbox or filtering. A --container flag can run stdio and built-in MCP extensions through docker exec in a container the user provides, but it does not cover every execution path. Repo-supplied plugin hooks and MCP servers also execute on the host.

C5 Untrusted input blast radius

0.15 / 1.00

goose reads untrusted content routinely (repository files, shell and web output, MCP tool results, and MCP server instructions that are placed in the system prompt) and nothing structural limits what a hijacked session can do. In the default Auto mode the agent can read secrets, send them anywhere through the shell or the URL-fetching image tool, and take irreversible actions with no human involved. An optional prompt-injection pattern scanner exists but is off by default and only detects; the egress inspector only logs.

C6 Memory, context & configuration integrity

0.05 / 1.00

A cloned repository can change goose's behavior with no prompt. Plugins placed under .agents/plugins in the working directory are discovered and auto-enabled, their MCP servers are launched, and their hooks.json commands (including SessionStart) run through sh on the host. .goosehints and AGENTS.md from the project are loaded silently into the system prompt, and the model can write those files (or a new plugin) with its unrestricted write and shell tools, so an injection can persist into later sessions and to anyone else who clones the repo.

C7 Third-party extensions

0.07 / 1.00

Third-party code runs with the agent's full access and little verification. User-configured MCP extensions are typically npx/uvx packages launched unpinned; goose checks them against the OSV malicious-package list, but that check only covers npx/uvx and fails open otherwise. Worse, plugins committed to a project's .agents/plugins directory are enabled on discovery, so opening goose in a cloned repo launches that repo's MCP servers and hook scripts without consent. Extension processes run as the same user with the inherited environment.

C8 Secrets & sensitive-data protection

0.20 / 1.00

Provider API keys go to the OS keychain by default, falling back to an owner-only (0600) file. Beyond that there is little protection: shell commands inherit every environment secret and their output goes to the model, nothing redacts secrets from tool results, logs or saved transcripts (the only redaction is for telemetry error strings), and the CLI writes full LLM request payloads to local log files by default. Telemetry is opt-in.

C9 Audit & traceability

0.50 / 1.00

Every message, including tool calls with arguments and results, is written per message to a SQLite session database in the user's data directory, and sub-agent sessions are linked to their parent. That gives a usable local transcript. It is not tamper-evident: the agent's own shell runs as the same user and can edit or delete it, and there is no actor attribution separating approver from agent or standard audit export by default.

C10 Limits & kill switch

0.40 / 1.00

The main loop stops after 1,000 turns and shell commands get a 300-second default timeout, but the model sets timeout_secs itself and a value of 0 disables the timeout. Sub-agents get a fresh 25-turn budget each (model-adjustable), cannot delegate further, and at most 5 run in the background. There is no cost or token cap. Ctrl-C cancels the loop and kills the shell process, but not its process group, so backgrounded children can survive.