Skip to content

Goose -- Sandbox Analysis Report

Analysis Date: 2026-02-12 Repository: https://github.com/block/gooseGit Commit: ac0ceddf88d3b8eb993825147b0b308cb81318fdLatest Version: 1.23.0 License: Apache-2.0 Source Availability: Open source


1. Overview

Goose is an open-source AI coding agent built in Rust. It is published as a workspace containing multiple crates: goose (core library with agents, providers, config, session management, OAuth, security, telemetry), goose-cli (CLI binary goose), goose-server (server binary goosed with REST/WebSocket API), goose-mcp (MCP extension servers for developer tools, computer controller, memory, tutorial), goose-acp (Agent Communication Protocol server), and test infrastructure crates. It also ships a desktop UI (Electron app, version 1.23.0) in ui/desktop/.

Goose supports many LLM providers including OpenAI, Anthropic, Google/Gemini, Databricks, Ollama, OpenRouter, Azure OpenAI, AWS Bedrock, AWS SageMaker, GCP Vertex AI, GitHub Copilot, Venice, xAI, LiteLLM, Snowflake, Tetrate, and more. It can also delegate to external CLI agents (Claude Code, Gemini CLI, Cursor Agent, Codex).


2. UI & Execution Modes

CLI Interface (Interactive Terminal)

Goose has an interactive terminal CLI using these libraries:

  • rustyline (15.0.0) -- line editing and input history
  • cliclack (0.3.5) -- interactive prompts (confirm, select, multi-select)
  • console (0.16.1) -- terminal colors and styling
  • bat (0.26.1) -- syntax-highlighted code output
  • indicatif (0.18.1) -- progress bars
  • anstream (0.6.18) -- ANSI stream handling

There is no TUI framework (no ratatui, tui-rs, crossterm widget layers). The CLI is a traditional REPL-style interface with syntax-highlighted output.

The CLI stores readline history:

rust
// crates/goose-cli/src/session/mod.rs:116
history_file: Paths::state_dir().join("history.txt"),
old_history_file: Paths::config_dir().join("history.txt"),

Desktop Application (Electron)

The desktop app is in ui/desktop/ and is a full Electron application:

  • Electron 40.1.0
  • React 19.2.4 with React Router
  • Vite as build tool
  • Tailwind CSS 4.1.18 for styling
  • Electron Forge for packaging and distribution
  • Uses electron-updater for auto-updates
  • Has react-markdown, react-syntax-highlighter, katex for rich content rendering

The desktop app communicates with the Rust backend (goosed) via HTTP/WebSocket.

Web UI Mode (goose web)

The CLI can launch a web server mode that serves a bundled frontend:

rust
// crates/goose-cli/src/commands/web.rs:283
let listener = tokio::net::TcpListener::bind(addr).await?;

Uses:

  • axum (0.8) with WebSocket support for real-time communication
  • tower-http for CORS, static file serving, and auth middleware
  • Opens the browser automatically: webbrowser::open(&url)

Server Mode (goosed)

The goose-server crate (goosed binary) runs a standalone HTTP/WebSocket server:

  • Default bind: 127.0.0.1:3000
  • Configurable via GOOSE_HOST and GOOSE_PORT environment variables
  • Full REST API with OpenAPI spec (via utoipa)
  • WebSocket support for streaming agent responses

3. Authentication & Credentials

3.1 Credential Storage (System Keyring)

Goose uses the keyring crate (3.6.2) with the apple-native feature for macOS Keychain integration:

rust
// crates/goose/src/config/base.rs:4
use keyring::Entry;

// crates/goose/src/config/base.rs:17-18
const KEYRING_SERVICE: &str = "goose";
const KEYRING_USERNAME: &str = "secrets";

Keyring features enabled:

toml
keyring = { version = "3.6.2", features = [
    "apple-native",       # macOS Keychain via Security.framework
    "windows-native",     # Windows Credential Manager
    "sync-secret-service", # Linux Secret Service (D-Bus)
    "vendored",
] }

All secrets (API keys, OAuth tokens) are stored as a single JSON blob in the keychain under service goose, username secrets.

3.2 API Key Sources and Priority Order

All config and secrets check environment variables first (uppercase):

rust
// crates/goose/src/config/base.rs:666
let env_key = key.to_uppercase();
if let Ok(val) = env::var(&env_key) { ... }

Fallback to file-based secrets if keyring unavailable or explicitly disabled:

rust
// crates/goose/src/config/base.rs:124
let secrets = match env::var("GOOSE_DISABLE_KEYRING") {
    Ok(_) => SecretStorage::File {
        path: config_dir.join("secrets.yaml"),
    },
    Err(_) => SecretStorage::Keyring {
        service: KEYRING_SERVICE.to_string(),
    },
};

Fallback file: ~/.config/goose/secrets.yaml (plaintext YAML)

The system auto-detects keyring availability errors and falls back:

rust
// crates/goose/src/config/base.rs:900
fn is_keyring_availability_error(&self, error_str: &str) -> bool {
    error_str.contains("keyring")
        || error_str.contains("DBus error")
        || error_str.contains("org.freedesktop.secrets")
        || error_str.contains("couldn't access platform secure storage")
}

Provider-specific credentials read from environment or keyring:

  • OPENAI_API_KEY, OPENAI_HOST
  • ANTHROPIC_API_KEY
  • DATABRICKS_HOST, DATABRICKS_TOKEN
  • OPENROUTER_API_KEY, OPENROUTER_HOST
  • OLLAMA_HOST, OLLAMA_TIMEOUT
  • SNOWFLAKE_HOST, SNOWFLAKE_TOKEN
  • GOOGLE_API_KEY
  • GitHub Copilot token cache: Paths::in_config_dir("githubcopilot/info.json")
  • AWS credentials (via aws-config crate for Bedrock/SageMaker)
  • GCP credentials (via jsonwebtoken for Vertex AI)
  • Azure credentials (via az CLI: tokio::process::Command::new("az"))

3.3 OAuth Flows

Goose implements OAuth for multiple providers:

  1. MCP OAuth (crates/goose/src/oauth/mod.rs):

    • Starts local callback server on 127.0.0.1:0 (random port)
    • Opens browser for authorization
    • Stores credentials via GooseCredentialStore (which uses the Config secret system -> keychain)
  2. Databricks OAuth (crates/goose/src/providers/oauth.rs):

    • Binds to 127.0.0.1:<bind_port>
    • Opens browser for authorization
    • Stores tokens at Paths::in_config_dir("databricks/oauth")
  3. ChatGPT/Codex OAuth (crates/goose/src/providers/chatgpt_codex.rs):

    • Binds to 127.0.0.1:16372 (fixed port)
    • PKCE flow
    • Stores tokens at Paths::in_config_dir("chatgpt_codex/tokens.json")
  4. OpenRouter signup (crates/goose/src/config/signup_openrouter/):

    • Binds to 127.0.0.1:3000
    • Opens browser for authentication
  5. Tetrate Agent Router (crates/goose/src/config/signup_tetrate/):

    • Binds to 127.0.0.1:3000
    • Opens browser for authentication

3.4 Credential File Locations and Formats

PathPurpose
System keyring (service: goose, user: secrets)Primary secret storage (JSON blob)
{config_dir}/secrets.yamlFallback plaintext secret storage
{config_dir}/githubcopilot/info.jsonGitHub Copilot token cache
{config_dir}/chatgpt_codex/tokens.jsonChatGPT/Codex OAuth tokens
{config_dir}/databricks/oauth/Databricks OAuth token storage

4. Configuration & Filesystem

4.1 User-Level Config Paths

Goose uses the etcetera crate for XDG-compliant path resolution:

rust
// crates/goose/src/config/paths.rs
let strategy = choose_app_strategy(AppStrategyArgs {
    top_level_domain: "Block".to_string(),
    author: "Block".to_string(),
    app_name: "goose".to_string(),
})

On macOS:

Directory TypemacOS Path
Config~/Library/Application Support/Block.goose/
Data~/Library/Application Support/Block.goose/
State~/Library/Application Support/Block.goose/

On Linux (XDG):

Directory TypeLinux Path
Config~/.config/goose/
Data~/.local/share/goose/
State~/.local/state/goose/

Can be overridden with GOOSE_PATH_ROOT environment variable.

Config Files

PathPurpose
{config_dir}/config.yamlMain configuration file
{config_dir}/config.yaml.bakConfig backup (rotated up to .bak.5)
{config_dir}/config.yaml.tmpAtomic write temp file
{config_dir}/secrets.yamlFallback secret storage (when keyring disabled)
{config_dir}/.bash_envBash environment file (server mode)
{config_dir}/custom_providers/Declarative provider definitions
{config_dir}/prompts/Custom prompt templates
{config_dir}/permissions/tool_permissions.jsonTool permission records
{config_dir}/recipes/Global recipe library
{config_dir}/memory/Global memory store (category files)
{config_dir}/tunnel.lockTunnel lock file
{config_dir}/.gooseignoreGlobal ignore patterns
{config_dir}/.goosehintsGlobal hints file

4.2 Project-Level Config Paths

PathPurpose
.goosehintsProject-specific hints (read from CWD and parent dirs)
.gooseignoreProject-specific ignore patterns
.goose/memory/Project-local memory storage
.goose/recipes/Project-local recipe library
AGENTS.mdAgent instructions file (read from CWD)
recipe.yamlDefault recipe save location
init-config.yamlInitial config (in workspace root)

4.3 System/Enterprise Config Paths

N/A

4.4 Data & State Directories

PathPurpose
{data_dir}/sessions/sessions.dbSQLite database for session storage
{data_dir}/sessions/*.jsonlLegacy session files (migrated to SQLite)
{data_dir}/schedule.jsonScheduled jobs storage
{data_dir}/scheduled_recipes/Scheduled recipe YAML files
{data_dir}/models/Downloaded Whisper model files
{data_dir}/projects.jsonProject tracking data
{data_dir}/goose_apps/Goose apps directory
{state_dir}/logs/cli/{date}/CLI log files (JSON, date-rotated)
{state_dir}/logs/server/{date}/Server log files
{state_dir}/logs/debug/Debug log files
{state_dir}/history.txtReadline history
{state_dir}/telemetry_installation.jsonTelemetry installation ID
{state_dir}/codex/images/Codex image storage

Log cleanup: files older than 14 days are automatically removed.

4.5 Workspace Files Read

PathPurpose
.goosehintsProject-specific hints (read from CWD and parent dirs)
.gooseignoreProject-specific ignore patterns
AGENTS.mdAgent instructions file
.env, .env.*Ignored by default
.gitignoreRespected for file operations

4.6 Temp Directory Usage

tempfile Crate Usage

Goose uses the tempfile crate (3) extensively, primarily in test code. The tempfile crate uses std::env::temp_dir() which respects the TMPDIR environment variable on macOS/Linux.

Explicit /tmp Usage

The computer controller macOS platform uses a hardcoded /tmp:

rust
// crates/goose-mcp/src/computercontroller/platform/macos.rs:19
fn get_temp_path(&self) -> PathBuf {
    PathBuf::from("/tmp")
}

Atomic Config Writes

Config file saves use a .tmp extension sibling file for atomic writes:

rust
// crates/goose/src/config/base.rs:452
let temp_path = self.config_path.with_extension("tmp");

5. Tools Available to the LLM

Goose provides tools to the LLM through its built-in MCP extension servers:

Developer Extension (goose-mcp/src/developer/):

  • text_editor -- File reading and editing
  • write_file -- File writing/creation
  • patch_file -- Fuzzy patch application
  • Shell execution via user's $SHELL (defaults to bash)
  • Screen capture (xcap crate for screenshots)
  • Memory storage (project-local and global)

Computer Controller Extension (goose-mcp/src/computercontroller/):

  • AppleScript execution (macOS automation via osascript)
  • Shell automation
  • Platform-specific automation (X11/Wayland on Linux, PowerShell on Windows)

Memory Extension:

  • Project-local and global memory storage and retrieval

Document Processing:

  • PDF reading (lopdf crate)
  • DOCX reading (docx-rs crate)
  • Excel reading (umya-spreadsheet crate)
  • Image processing (image crate)

Tools respect .gooseignore and .gitignore patterns. The developer extension uses tree-sitter for code parsing (Python, Rust, JavaScript, Go, Java, Kotlin, Swift, Ruby). Files matching .env and .env.* are ignored by default.


6. Host System Interactions

6.1 Subprocess Execution

Shell Execution (Developer Extension)

The primary mechanism for the agent to interact with the system:

rust
// crates/goose-mcp/src/developer/shell.rs:114
let mut command_builder = tokio::process::Command::new(&shell_config.executable);
  • Uses user's $SHELL (defaults to bash)
  • Sets GOOSE_TERMINAL=1, AGENT=goose
  • Disables interactive Git: GIT_TERMINAL_PROMPT=0, GIT_EDITOR=<error script>
  • Creates new process group on Unix for proper cleanup
  • This is the primary way the agent runs arbitrary commands

Specific External Commands

CommandLocationPurpose
osascriptcomputercontroller/platform/macos.rsExecute AppleScript for macOS automation
bash -cMultipleShell command execution
sh -cMultipleShell command execution
powershell / cmdWindows pathsWindows shell execution
gh (GitHub CLI)recipes/github_recipe.rsGitHub operations (auth, repos, PRs)
gitrecipes/github_recipe.rsGit operations
curlcommands/update.rsDownload update script
docker execagents/extension_manager.rsRun extensions in Docker containers
docker runagents/extension_manager.rsStart containerized extensions
uvxagents/extension_manager.rsRun Python MCP servers via uv
azproviders/azureauth.rsAzure CLI for authentication
sw_versposthog.rsGet macOS version (telemetry)
goosecommands/project.rsSelf-invocation for project management
claudeProvider: claude_codeClaude Code CLI invocation
geminiProvider: gemini_cliGemini CLI invocation
cursor-agentProvider: cursor_agentCursor Agent CLI invocation
codexProvider: codexCodex CLI invocation
python3computercontroller/platform/linux.rsLinux automation scripts
xdotool / wmctrlcomputercontroller/platform/linux.rsX11 automation
wtype / wl-paste / wl-copycomputercontroller/platform/linux.rsWayland automation
xclipcomputercontroller/platform/linux.rsX11 clipboard
taskkillWindows pathsProcess termination
whichcomputercontroller/platform/linux.rsCheck for dependencies

Extension Launching

MCP extensions are started as child processes:

rust
// crates/goose/src/agents/extension_manager.rs:571
Command::new(cmd).configure(|command| {
    command.args(args).envs(all_envs);
})

Extensions can be launched via:

  • Direct command execution (stdio MCP)
  • uvx for Python-based MCP servers
  • docker exec for containerized extensions
  • Built-in extensions (in-process via tokio::io::duplex)
  • HTTP-based MCP connections

6.2 Network Requests

LLM Provider API Endpoints

ProviderDefault Endpoint
OpenAIhttps://api.openai.com
AnthropicAnthropic API
Google/GeminiGoogle Generative Language API
DatabricksUser-configured DATABRICKS_HOST
Ollamalocalhost:11434
OpenRouterhttps://openrouter.ai/api
Azure OpenAIUser-configured
AWS BedrockVia AWS SDK
AWS SageMakerVia AWS SDK
GCP Vertex AI{location}-aiplatform.googleapis.com
GitHub Copilothttps://api.github.com/copilot_internal/v2/token
VeniceUser-configured
xAIUser-configured
LiteLLMUser-configured
SnowflakeUser-configured SNOWFLAKE_HOST
TetrateUser-configured

Telemetry

PostHog analytics (opt-in):

rust
// crates/goose/src/posthog.rs:17
const POSTHOG_API_KEY: &str = "phc_RyX5CaY01VtZJCQyhSR5KFh6qimUy81YwxsEpotAftT";
  • Sends to PostHog cloud API
  • Controlled by GOOSE_TELEMETRY_ENABLED config or GOOSE_TELEMETRY_OFF env var
  • Currently only session_started events are active (error/other events disabled)
  • Sanitizes PII (paths, emails, tokens) before sending

Observability

  • Langfuse integration (optional, via LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY)
    • Default URL: http://localhost:3000
  • OpenTelemetry OTLP export (optional)

Whisper Model Downloads

Downloads from HuggingFace:

rust
// crates/goose/src/dictation/whisper.rs:61-79
url: "https://huggingface.co/oxide-lab/whisper-tiny-GGUF/resolve/main/model-tiny-q80.gguf"
url: "https://huggingface.co/oxide-lab/whisper-base-GGUF/resolve/main/whisper-base-q8_0.gguf"
url: "https://huggingface.co/oxide-lab/whisper-small-GGUF/resolve/main/whisper-small-q8_0.gguf"
url: "https://huggingface.co/oxide-lab/whisper-medium-GGUF/resolve/main/whisper-medium-q8_0.gguf"

Tunnel (Remote Access)

Cloudflare tunnel proxy for remote access:

rust
// crates/goose-server/src/tunnel/lapstone.rs:32
const WORKER_URL: &str = "https://cloudflare-tunnel-proxy.michael-neale.workers.dev";

Update Mechanism

Self-update via download script:

rust
// crates/goose-cli/src/commands/update.rs:13-14
Command::new("curl")
    .args(["-fsSL", "https://github.com/block/goose/raw/main/download_cli.sh"])

6.3 Port Binding

PortContextPurpose
3000goosed defaultHTTP/WebSocket API server
3000OpenRouter/Tetrate signupOAuth callback server
0 (random)MCP OAuthOAuth callback server
0 (random)Databricks OAuthOAuth callback server
16372ChatGPT/Codex OAuthFixed OAuth callback port
Configurablegoose webWeb UI server
0 (random)TestsTest servers

6.4 Browser Launching

Multiple locations open the system browser:

rust
webbrowser::open(authorization_url)  // OAuth flows
webbrowser::open(&url)               // Web UI auto-open
open::that(url)                      // Recipe deep links

6.5 Clipboard Access

  • Linux X11: xclip -selection clipboard
  • Linux Wayland: wl-paste / wl-copy
  • macOS: Via AppleScript (osascript)
  • Windows: Via PowerShell
  • Desktop app requests clipboard-write permission

6.6 File System Watchers

None identified.

6.7 Other

  • Screen Capture via xcap crate (0.4.0):

    rust
    // crates/goose-mcp/src/developer/rmcp_developer.rs:52
    use xcap::{Monitor, Window};
    • Captures full display screenshots
    • Captures specific window screenshots
    • Lists available windows
  • macOS AppleScript: The computer controller can execute arbitrary AppleScript:

    rust
    // crates/goose-mcp/src/computercontroller/platform/macos.rs:9
    Command::new("osascript").arg("-e").arg(script).output()?;

    This provides deep system integration: window management, application control, file operations, browser automation, etc.

  • SQLite Database: Session data stored in SQLite ({data_dir}/sessions/sessions.db) using sqlx with WAL journal mode. Stores sessions, messages, metadata with schema migrations.

  • Document Processing: Can read PDF (lopdf), DOCX (docx-rs), Excel (umya-spreadsheet), and images (image crate).


7. Extension Points

7.1 Hook/Lifecycle System

None identified (no hook/lifecycle events system).

7.2 Plugin/Extension Architecture

Extensions are managed through the Extension Manager:

  • Builtin extensions: Run in-process via duplex streams
    • Developer (file editing, shell, screen capture, memory)
    • Computer Controller (AppleScript, shell automation)
    • Memory (project-local and global memory storage)
    • Tutorial
    • Auto-visualiser
  • Stdio extensions: Launched as child processes
  • HTTP extensions: Connected via HTTP/SSE
  • Docker extensions: Launched inside Docker containers
  • Platform extensions: Pre-registered definitions

7.3 MCP Integration

Goose is deeply integrated with MCP (Model Context Protocol):

  • Acts as both an MCP client (connecting to external MCP servers) and hosts built-in MCP servers (developer, computer controller, memory, tutorial)
  • Supports stdio, HTTP, and Docker transport types
  • Extension configuration in config.yaml
  • uvx support for Python-based MCP servers
  • Docker-based MCP server isolation

7.4 Custom Commands/Skills/Agents

  • Recipes: Reusable task definitions stored in {config_dir}/recipes/ (global) and .goose/recipes/ (project-local)
  • Scheduled recipes: {data_dir}/scheduled_recipes/
  • Custom prompt templates: {config_dir}/prompts/
  • Custom providers: {config_dir}/custom_providers/ for declarative provider definitions

7.5 SDK/API Surface

  • REST API with OpenAPI spec (via utoipa) on goosed
  • WebSocket support for streaming agent responses
  • ACP (Agent Communication Protocol) server (goose-acp crate)

8. Sandbox & Security Model

8.1 Built-in Sandboxing

None. The agent runs directly on the host with the user's full permissions.

8.2 Permission System

  • Tool permission records stored at {config_dir}/permissions/tool_permissions.json
  • No tiered autonomy system like some other agents

8.3 Safety Mechanisms

  • Disables interactive Git prompts: GIT_TERMINAL_PROMPT=0, GIT_EDITOR=<error script>
  • Respects .gooseignore and .gitignore patterns
  • Ignores .env, .env.* files by default
  • Telemetry sanitizes PII before sending

8.4 Known Vulnerabilities

None identified.

8.5 Enterprise/Managed Security Controls

N/A


9. Key Dependencies

DependencyVersionImpact
keyring3.6.2macOS Keychain, Windows Credential Manager, Linux Secret Service
xcap0.4.0Screen capture (uses platform-specific APIs)
reqwest0.12.28HTTP client with system proxy support, rustls TLS
sqlx0.8SQLite database (runtime-tokio-rustls)
candle-core/nn/transformers0.9Local ML inference (Metal on macOS, CUDA optional)
tokio1.49Async runtime (full features)
axum0.8HTTP server framework
webbrowser1.0System browser launching
open5.3.2Open URLs/files with default handler
libc0.2Direct Unix system calls (process group kill)
socket20.6.1Low-level socket options (TCP keepalive)
fs20.4File locking (exclusive locks for config)
which8.0.0Command resolution on PATH
shellexpand3.1Tilde expansion in paths
ignore0.4.25Gitignore-style pattern matching
tree-sitter + parsersVariousCode parsing (7+ languages)
lopdf0.36.0PDF reading
docx-rs0.4.7DOCX reading
umya-spreadsheet2.2.3Excel reading
aws-config/aws-sdk-*VariousAWS service access
posthog-rs0.3.7Telemetry (PostHog)
mpatch0.2.0Fuzzy patch application
sys-info0.9System information
rustls0.23TLS (ring backend)
hf-hub0.4.3HuggingFace model downloads
winapi0.3Windows credential access (wincred)

10. Environment Variables

Configuration Variables (via GOOSE_ prefix)

VariablePurpose
GOOSE_PROVIDERActive LLM provider
GOOSE_MODELActive model name
GOOSE_MODEOperating mode
GOOSE_HOST / GOOSE_PORTServer bind address
GOOSE_DISABLE_KEYRINGDisable keychain, use file-based secrets
GOOSE_TELEMETRY_ENABLEDTelemetry opt-in config key
GOOSE_TELEMETRY_OFFEnvironment-level telemetry disable
GOOSE_PATH_ROOTOverride all base directories
GOOSE_SEARCH_PATHSAdditional PATH entries for commands
GOOSE_MAX_TOKENSMax tokens for responses
GOOSE_TEMPERATURELLM temperature
GOOSE_CONTEXT_LIMITContext window limit
GOOSE_TOOLSHIMEnable tool shim
GOOSE_TOOLSHIM_OLLAMA_MODELOllama model for tool shim
GOOSE_PREDEFINED_MODELSPredefined model list
GOOSE_EMBEDDING_MODELEmbedding model name
GOOSE_AUTO_COMPACT_THRESHOLDAuto-compaction threshold
GOOSE_DESKTOPIndicates desktop app context
GOOSE_TERMINALSet in spawned shells to indicate agent context
GOOSE_RECIPE_PATHAdditional recipe search paths
GOOSE_RECIPE_RETRY_TIMEOUT_SECONDSRecipe retry timeout
GOOSE_RECIPE_ON_FAILURE_TIMEOUT_SECONDSRecipe failure timeout
GOOSE_PROVIDER_SKIP_BACKOFFSkip provider backoff
GOOSE_MCP_CLIENT_VERSIONMCP client version
GOOSE_DISABLE_SESSION_NAMINGDisable auto session naming
GOOSE_MAX_ACTIVE_AGENTSMax concurrent agents
GOOSE_CLAUDE_CODE_DEBUGDebug logging for Claude Code provider
GOOSE_CODEX_DEBUGDebug logging for Codex provider
GOOSE_CURSOR_AGENT_DEBUGDebug logging for Cursor Agent provider
GOOSE_LEAD_MODEL / GOOSE_LEAD_PROVIDER / etc.Lead-worker agent config

Provider API Key Variables

VariableProvider
OPENAI_API_KEYOpenAI
ANTHROPIC_API_KEYAnthropic
DATABRICKS_HOST / DATABRICKS_TOKENDatabricks
OPENROUTER_API_KEYOpenRouter
OLLAMA_HOSTOllama
SNOWFLAKE_HOST / SNOWFLAKE_TOKENSnowflake
GOOGLE_API_KEYGoogle
Various AWS varsAWS Bedrock/SageMaker
Various GCP varsGCP Vertex AI

Tracing/Observability Variables

VariablePurpose
LANGFUSE_PUBLIC_KEYLangfuse tracing
LANGFUSE_SECRET_KEYLangfuse tracing
LANGFUSE_URLLangfuse endpoint
RUST_LOGLog level filter

11. Summary Tables

11.1 All Filesystem Paths Accessed

PathAccessPurposeCreated by Agent?
~/Library/Application Support/Block.goose/ (macOS)R/WConfig, data, state rootYes
~/.config/goose/ (Linux)R/WConfig rootYes
~/.local/share/goose/ (Linux)R/WData rootYes
~/.local/state/goose/ (Linux)R/WState rootYes
{config}/config.yamlR/WMain configYes
{config}/config.yaml.bak*R/WConfig backups (up to 6)Yes
{config}/secrets.yamlR/WFallback secret storageYes
{config}/custom_providers/RCustom provider definitionsNo (user-created)
{config}/prompts/RCustom prompt templatesNo (user-created)
{config}/permissions/tool_permissions.jsonR/WTool permissionsYes
{config}/recipes/R/WGlobal recipe libraryYes
{config}/memory/R/WGlobal memory categoriesYes
{config}/githubcopilot/info.jsonR/WGitHub Copilot cacheYes
{config}/chatgpt_codex/tokens.jsonR/WChatGPT/Codex OAuth tokensYes
{config}/databricks/oauth/R/WDatabricks OAuth tokensYes
{config}/tunnel.lockR/WTunnel lock fileYes
{config}/.gooseignoreRGlobal ignore patternsNo (user-created)
{config}/.goosehintsRGlobal hintsNo (user-created)
{config}/.bash_envRBash environment (server)No (user-created)
{data}/sessions/sessions.dbR/WSQLite session databaseYes
{data}/schedule.jsonR/WScheduled jobsYes
{data}/scheduled_recipes/R/WScheduled recipe filesYes
{data}/models/R/WDownloaded ML modelsYes
{data}/projects.jsonR/WProject trackingYes
{data}/goose_apps/R/WGoose appsYes
{state}/logs/cli/{date}/*.logWCLI log filesYes
{state}/logs/server/{date}/*.logWServer log filesYes
{state}/history.txtR/WReadline historyYes
{state}/telemetry_installation.jsonR/WTelemetry IDYes
{state}/codex/images/R/WCodex imagesYes
{cwd}/.goosehintsRProject hintsNo (user-created)
{cwd}/.gooseignoreRProject ignore patternsNo (user-created)
{cwd}/.goose/memory/R/WProject-local memoryYes
{cwd}/.goose/recipes/RProject-local recipesNo (user-created)
{cwd}/AGENTS.mdRAgent instructionsNo (user-created)
{cwd}/recipe.yamlR/WDefault recipe fileYes
/tmpR/WmacOS temp (computer controller)Yes
System keychainR/WmacOS Keychain via Security.frameworkYes

11.2 All Network Endpoints

EndpointPurposeWhen Triggered
https://api.openai.comLLM inferenceWhen OpenAI provider selected
Anthropic APILLM inferenceWhen Anthropic provider selected
Google Generative Language APILLM inferenceWhen Gemini provider selected
DATABRICKS_HOSTLLM inferenceWhen Databricks configured
localhost:11434LLM inferenceWhen Ollama configured
https://openrouter.ai/apiLLM inferenceWhen OpenRouter configured
Azure OpenAILLM inferenceWhen Azure configured
AWS Bedrock/SageMakerLLM inferenceWhen AWS configured
{location}-aiplatform.googleapis.comLLM inferenceWhen Vertex AI configured
https://api.github.com/copilot_internal/v2/tokenLLM inferenceWhen GitHub Copilot configured
PostHog cloud APITelemetry (opt-in)Session start
Langfuse endpointObservability (optional)When Langfuse configured
https://huggingface.co/oxide-lab/whisper-*Whisper model downloadsWhen dictation enabled
https://cloudflare-tunnel-proxy.michael-neale.workers.devTunnel proxyWhen remote access enabled
https://github.com/block/goose/raw/main/download_cli.shSelf-updateOn goose update command

11.3 All System Interactions

TypeMechanismDetails
Arbitrary shell executiontokio::process::Command via user's $SHELLCritical -- agent can run any command
File read/writestd::fs / tokio::fs in working directoryCritical -- agent reads/writes project files
AppleScript executionosascript -eCritical -- full macOS automation
Screen capturexcap crateHigh -- captures screen contents
Browser launchwebbrowser::open / open::thatMedium -- opens URLs
HTTP port bindingtokio::net::TcpListenerMedium -- binds local ports (3000, random)
Clipboard accessPlatform-specific CLI toolsMedium -- read/write clipboard
Keychain accesskeyring crate (Security.framework)Medium -- stores/reads secrets
Docker controldocker exec/runHigh -- container management
Network HTTP requestsreqwestMedium -- API calls to LLM providers
Telemetryposthog-rsLow -- opt-in analytics
Git operationsgit CLI via shellMedium -- repository access
GitHub CLIgh CLIMedium -- GitHub API access
Azure CLIaz CLIMedium -- Azure auth
System version querysw_vers / /etc/os-releaseLow -- system info
ML model downloadreqwest to HuggingFaceLow -- model files
SQLite databasesqlxLow -- local DB file
File lockingfs2Low -- config atomicity
Process group managementlibc::kill with process groupsMedium -- signal handling
MCP extension spawningChild process or DockerHigh -- runs arbitrary MCP servers
UV package executionuvxHigh -- runs arbitrary Python packages
Self-updatecurl + bashHigh -- downloads and executes scripts

12. Sandboxing Recommendations

Critical restrictions needed:

  1. Shell execution -- The agent can run arbitrary commands via the user's shell. This is the primary attack surface and should be sandboxed.
  2. AppleScript -- osascript provides full macOS automation capabilities (window management, app control, file operations).
  3. Screen capture -- The xcap crate can capture full display and individual window screenshots.
  4. File system access -- The agent reads/writes files in the working directory with no OS-level restriction.

What to allow:

  • Network access to configured LLM provider endpoints
  • Read/write access to the working directory (scoped)
  • Read/write access to ~/Library/Application Support/Block.goose/ (macOS) for config/state
  • Keychain access for secret storage
  • Localhost port binding for OAuth callbacks and server mode

Known gaps:

  • No built-in sandboxing whatsoever -- the agent runs with full user permissions
  • osascript provides essentially unrestricted macOS automation
  • MCP stdio extensions run as child processes with full user permissions
  • uvx can install and execute arbitrary Python packages
  • Self-update mechanism (curl | bash) downloads and runs scripts from GitHub
  • Docker extensions can manage containers on the host

Recommended isolation strategy:

  • Container-based isolation (Docker/Podman) with restricted filesystem mounts
  • Network egress filtering to only allow configured LLM endpoints
  • Disable osascript and screen capture in sandboxed environments
  • Use HTTP-based MCP servers instead of stdio to maintain isolation boundaries

Open source under the Apache 2.0 License.