How Agent-Reach Stores and Protects Credentials: Security Model Explained

Agent-Reach stores API keys and secrets in ~/.agent-reach/config.yaml with strict Unix permissions (0o600 for files and 0o700 for directories), supports environment variable overrides, and automatically masks sensitive values in CLI output to prevent accidental exposure.

Agent-Reach, an open-source automation framework maintained at Panniantong/Agent-Reach, implements a defense-in-depth security model for credential storage that prioritizes file system isolation and user-controlled access. Rather than relying on external secret managers, the codebase enforces strict permission controls, optional transient injection via environment variables, and automatic masking of sensitive data. This article examines the specific implementation details found in the configuration handling and utility modules.

Private Directory and File Permissions

The foundation of Agent-Reach’s security model relies on Unix file permissions to ensure only the owner can access stored credentials.

Secure Directory Creation

When initializing the configuration store, Agent-Reach creates the storage directory using make_private_dir in agent_reach/utils/paths.py (lines 10-16). This helper function explicitly sets the directory mode to 0o700, granting the owner exclusive read, write, and execute permissions while denying all access to group and other users.

Restricted File Access

The Config.save method in agent_reach/config.py (lines 52-73) enforces the same owner-only restriction for the configuration file itself. The implementation uses os.open with flags that atomically create the file with mode 0o600 (owner read/write only). On platforms where these specific flags are unavailable, the code falls back to creating the file normally and immediately applying chmod 0o600 to ensure the permissions are set regardless of umask settings.

Environment Variable Fallback

Agent-Reach provides a transient injection mechanism that bypasses disk storage entirely. The Config.get method in agent_reach/config.py (lines 75-84) implements a two-tier lookup strategy:

  1. First, it checks the YAML configuration file for the requested key.
  2. If not found, it searches for an environment variable matching the uppercase version of the key name.

This allows operators to export OPENAI_API_KEY or EXA_API_KEY in their shell session without ever persisting the value to config.yaml, reducing the attack surface for systems that manage secrets through environment-specific injection rather than files.

Secret Masking in Output

To prevent credential leakage in logs and console output, the Config.to_dict method in agent_reach/config.py (lines 108-130) automatically masks sensitive values. When the configuration is displayed—whether via the CLI or programmatic inspection—any key containing substrings like key, token, password, secret, or cookie is truncated to show only the first eight characters followed by an ellipsis (...). This ensures that even if a user accidentally shares their configuration output, the full secrets remain protected.

Browser cookies extracted for automated sessions receive the same protection as manually entered API keys. The cookie_extract.configure_from_browser function in agent_reach/cookie_extract.py (lines 267-292) extracts session cookies from the browser, converts them into a header string, and stores them via Config.set. Consequently, these cookies inherit the 0o600 file permissions, directory isolation, and masking behavior applied to all other credentials.

Practical Usage Examples

The following examples demonstrate the security model in practice, including permission verification and environment variable overrides.

Initialize the configuration manager and store a secret with automatic permission enforcement:

from agent_reach.config import Config

# Creates ~/.agent-reach with 0o700 and config.yaml with 0o600

cfg = Config()

# Writes to config.yaml with owner-only permissions

cfg.set("openai_api_key", "sk-XXXXXXXXXXXXXXXXXXXXXXXX")

Retrieve credentials using the fallback chain (file first, then environment):


# Checks config.yaml, then checks OPENAI_API_KEY env var

api_key = cfg.get("openai_api_key")

# Verify configuration completeness without exposing secrets

if cfg.is_configured("exa_search"):
    print("Exa Search credentials present")

Use environment variables to avoid disk persistence entirely:


# Set secret in environment (not written to disk)

export OPENAI_API_KEY="sk-YYYYYYYYYYYYYYYYYYYYYYYY"

# Agent-Reach reads this value without touching config.yaml

python -c "from agent_reach.config import Config; print(Config().get('openai_api_key'))"

View the configuration with automatic masking applied:


# Secret values are truncated to prevent exposure

$ agent-reach config view
{
  "openai_api_key": "sk-XXXXXX...",
  "exa_api_key": "XXXXXX..."
}

Remove sensitive data when no longer needed:


# Deletes the key from config.yaml entirely

cfg.delete("openai_api_key")

Summary

  • Private storage location: The ~/.agent-reach directory is created with 0o700 permissions, ensuring only the owner can access the path.
  • Strict file permissions: Configuration files are written with 0o600 permissions via os.open in agent_reach/config.py, preventing group or world access.
  • Environment override: The Config.get method checks environment variables after the file, allowing secrets to be injected without disk persistence.
  • Automatic masking: The Config.to_dict method masks keys containing key, token, password, or cookie to prevent leakage in logs and CLI output.
  • Unified cookie protection: Browser cookies extracted via cookie_extract.configure_from_browser are stored with the same permission and masking rules as API keys.

Frequently Asked Questions

Where does Agent-Reach store API keys?

Agent-Reach stores all credentials in ~/.agent-reach/config.yaml within the user’s home directory. This location is defined in agent_reach/config.py (lines 20-22) and is created with owner-only permissions (0o700 for the directory, 0o600 for the file).

What file permissions does Agent-Reach use for credential storage?

The configuration directory uses mode 0o700 (owner read/write/execute only), and the YAML file uses mode 0o600 (owner read/write only). These permissions are enforced by make_private_dir in agent_reach/utils/paths.py and Config.save in agent_reach/config.py.

Can I use environment variables instead of the config file?

Yes. The Config.get method in agent_reach/config.py (lines 75-84) implements a fallback system: it first checks the YAML file, then searches for an uppercase environment variable with the same name. Setting export OPENAI_API_KEY="..." allows the application to run without writing the secret to disk.

How does Agent-Reach prevent secrets from appearing in logs?

The Config.to_dict method in agent_reach/config.py (lines 108-130) automatically masks any configuration key containing sensitive substrings (key, token, password, cookie, etc.). When displayed, these values show only the first eight characters followed by an ellipsis, preventing accidental exposure in console output or log files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →