Skip to main content
The Config system provides flexible configuration management with environment variable overrides, YAML persistence, and secure secret storage.

Overview

Goose’s configuration system supports:
  • Dynamic configuration keys
  • Type-safe value retrieval via serde
  • Environment variable overrides
  • YAML-based persistence (~/.config/goose/config.yaml)
  • Secure secret storage in system keyring
  • File-based secret fallback
  • Configuration migrations

Configuration Precedence

Values are loaded in order:
  1. Environment variables (exact key match, e.g., OPENAI_API_KEY)
  2. Configuration file (~/.config/goose/config.yaml)
  3. Default values (from defaults.yaml or built-in defaults)

Secret Precedence

  1. Environment variables (exact key match)
  2. System keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
  3. Secrets file (~/.config/goose/secrets.yaml, if keyring disabled via GOOSE_DISABLE_KEYRING)

Config Struct

pub struct Config {
    config_path: PathBuf,
    defaults_path: Option<PathBuf>,
    secrets: SecretStorage,
    guard: Mutex<()>,
    secrets_cache: Arc<Mutex<Option<HashMap<String, Value>>>>,
}
Source: crates/goose/src/config/base.rs:103-109

Constructor Methods

global()

Get the global Config instance.
pub fn global() -> &'static Config
Returns: Reference to the global singleton Config Source: crates/goose/src/config/base.rs:237-239 Example:
let config = Config::global();
let api_key: String = config.get_param("OPENAI_API_KEY")?;

new()

Create a Config with custom paths (primarily for testing).
pub fn new<P: AsRef<Path>>(config_path: P, service: &str) -> Result<Self, ConfigError>
config_path
P: AsRef<Path>
required
Path to YAML config file
service
&str
required
Keyring service name
Source: crates/goose/src/config/base.rs:245-255

new_with_file_secrets()

Create Config using file-based secrets.
pub fn new_with_file_secrets<P1: AsRef<Path>, P2: AsRef<Path>>(
    config_path: P1,
    secrets_path: P2,
) -> Result<Self, ConfigError>
config_path
P1: AsRef<Path>
required
Path to config YAML
secrets_path
P2: AsRef<Path>
required
Path to secrets YAML
Source: crates/goose/src/config/base.rs:261-274

Reading Configuration

get_param()

Get a configuration parameter with type inference.
pub fn get_param<T: DeserializeOwned>(&self, key: &str) -> Result<T, ConfigError>
key
&str
required
Configuration key (e.g., “openai_api_key”)
Returns: Deserialized value of type T Errors:
  • ConfigError::NotFound - Key not found in config, env, or defaults
  • ConfigError::DeserializeError - Value cannot be deserialized to type T
Example:
use goose::config::Config;

let config = Config::global();

// Get string
let api_key: String = config.get_param("OPENAI_API_KEY")?;

// Get number
let max_retries: u32 = config.get_param("max_retries")?;

// Get complex type
#[derive(serde::Deserialize)]
struct ServerConfig {
    host: String,
    port: u16,
}
let server: ServerConfig = config.get_param("server")?;

all_values()

Get all configuration values as a HashMap.
pub fn all_values(&self) -> Result<HashMap<String, Value>, ConfigError>
Returns: All config keys and values Source: crates/goose/src/config/base.rs:338-347

Writing Configuration

set_param()

Set a configuration parameter.
pub fn set_param<T: Serialize>(&self, key: &str, value: &T) -> Result<(), ConfigError>
key
&str
required
Configuration key
value
&T
required
Value to store (must be Serialize)
Example:
let config = Config::global();

// Set string
config.set_param("model_name", &"gpt-4o")?;

// Set number
config.set_param("timeout_seconds", &30)?;

// Set complex type
#[derive(serde::Serialize)]
struct Settings {
    enabled: bool,
    threshold: f64,
}
config.set_param("my_settings", &Settings {
    enabled: true,
    threshold: 0.95,
})?;

remove_param()

Remove a configuration parameter.
pub fn remove_param(&self, key: &str) -> Result<(), ConfigError>
key
&str
required
Configuration key to remove

Secret Management

set_secret()

Store a secret securely.
pub fn set_secret(&self, key: &str, value: &str) -> Result<(), ConfigError>
key
&str
required
Secret key
value
&str
required
Secret value
Storage: Uses system keyring by default, falls back to encrypted file if keyring unavailable. Example:
config.set_secret("OPENAI_API_KEY", "sk-...")?;

get_secret()

Retrieve a secret.
pub fn get_secret(&self, key: &str) -> Result<String, ConfigError>
key
&str
required
Secret key
Returns: Secret value Example:
let api_key = config.get_secret("OPENAI_API_KEY")?;

remove_secret()

Delete a secret.
pub fn remove_secret(&self, key: &str) -> Result<(), ConfigError>
key
&str
required
Secret key to remove

all_secrets()

Get all secret keys (not values).
pub fn all_secrets(&self) -> Result<Vec<String>, ConfigError>
Returns: Vector of secret key names

File Operations

path()

Get the config file path.
pub fn path(&self) -> String
Returns: Path to config.yaml Source: crates/goose/src/config/base.rs:300-302

exists()

Check if config file exists.
pub fn exists(&self) -> bool
Source: crates/goose/src/config/base.rs:292-294

clear()

Delete the config file.
pub fn clear(&self) -> Result<(), ConfigError>
Source: crates/goose/src/config/base.rs:296-298

Built-in Configuration Keys

Goose recognizes several standard configuration keys:

get_goose_mode()

Get the operating mode.
pub fn get_goose_mode(&self) -> Result<GooseMode, ConfigError>
Returns: GooseMode::Auto, GooseMode::Chat, or GooseMode::Agentic

GooseMode

pub enum GooseMode {
    Auto,    // Automatically choose based on context
    Chat,    // Chat mode (no autonomous tool execution)
    Agentic, // Agentic mode (autonomous tool execution)
}
Source: crates/goose/src/config/goose_mode.rs

Other Built-in Keys

  • GOOSE_DISABLE_SESSION_NAMING - Disable auto-generated session names
  • GOOSE_TOOL_CALL_CUTOFF - Max tool calls before summarization (default: 10)
  • GOOSE_AUTO_COMPACT_THRESHOLD - Context percentage to trigger auto-compaction (default: 0.8)

Error Types

ConfigError

pub enum ConfigError {
    NotFound(String),
    DeserializeError(String),
    FileError(std::io::Error),
    DirectoryError(String),
    KeyringError(String),
    LockError(String),
    FallbackToFileStorage,
}
Source: crates/goose/src/config/base.rs:21-37
NotFound
String
Configuration key not found
DeserializeError
String
Value cannot be deserialized to requested type
FileError
std::io::Error
I/O error reading/writing config file
KeyringError
String
Error accessing system keyring

Naming Conventions

Goose recommends:
  • Use snake_case for configuration keys
  • Prefix Goose-specific keys with goose_ (e.g., goose_mode)
  • Environment variables use UPPERCASE (e.g., OPENAI_API_KEY)
  • The system automatically converts snake_caseUPPERCASE when checking environment variables
Example:
// Config file: openai_api_key: "sk-..."
// Environment: OPENAI_API_KEY="sk-..."
// Both work:
let key: String = config.get_param("openai_api_key")?;
  • Agent - Uses Config for provider settings
  • Session - Session-specific configuration

Build docs developers (and LLMs) love