Security Model for Credential Storage Using 0o600 File Permissions in Agent-Reach

Agent-Reach stores sensitive configuration data in a YAML file at ~/.agent_reach.yaml and automatically applies 0o600 permissions (owner-only read/write) via os.chmod in the save_config() function, ensuring that only the file owner can access stored credentials.

Agent-Reach implements a strict security model for credential storage that leverages Unix file permissions to protect sensitive data. By default, the framework writes configuration values—including API keys and authentication tokens—to a user-specific YAML file and restricts access using 0o600 permissions. This approach, implemented in agent_reach/config.py, ensures that credentials remain inaccessible to other users on the same system through explicit permission enforcement.

How Agent-Reach Implements the 0o600 Security Model

Configuration File Location and Environment Setup

The system determines the configuration file path using the AGENT_REACH_CONFIG environment variable, defaulting to ~/.agent_reach.yaml if not set. As shown in .env.example, users can override this path to store credentials in custom locations while maintaining the same security guarantees.

Permission Enforcement in save_config()

The core security logic resides in the save_config() function at lines 22-31 of agent_reach/config.py. After writing YAML data to disk, the function explicitly calls os.chmod(CONFIG_PATH, 0o600) to strip all permissions for group and other users, leaving only read and write access for the file owner.

Core Functions for Secure Credential Management

The agent_reach/config.py module provides four key functions that handle configuration with security-conscious defaults:

  • load_config(): Reads the YAML configuration file if it exists, returning an empty dictionary otherwise. This function does not modify permissions but validates YAML integrity.
  • save_config(): Writes configuration data to disk and immediately applies 0o600 permissions using os.chmod at line 30. This ensures every write operation reaffirms the security boundary.
  • get(): Retrieves specific configuration values by key, providing a simple API for credential access without exposing file handling details.
  • set(): Updates configuration values and persists them to disk through save_config(), automatically triggering the permission lockdown on every save.

Practical Implementation Examples

When storing an API key, the permission restriction happens automatically through the set() function:

from agent_reach.config import set, get

# Store credential (file created with 0o600 permissions automatically)

set("api_key", "sk-secret-token-12345")

# Retrieve credential later

token = get("api_key")
print(token)  # Output: sk-secret-token-12345

The internal implementation in agent_reach/config.py demonstrates the exact security mechanism:

import os
import yaml
from pathlib import Path

CONFIG_PATH = Path(os.getenv("AGENT_REACH_CONFIG", "~/.agent_reach.yaml")).expanduser()

def save_config(data):
    """Save configuration with 0o600 file permissions."""
    # Ensure parent directory exists

    CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    
    # Write configuration data

    with open(CONFIG_PATH, "w") as f:
        yaml.safe_dump(data, f)
    
    # Enforce owner-only access (octal 0600)

    os.chmod(CONFIG_PATH, 0o600)

Security Benefits of the 0o600 Permission Model

The 0o600 permission model follows the principle of least privilege. By setting permissions to rw-------, Agent-Reach ensures that:

  1. The file owner retains full read and write access to manage credentials.
  2. Group members are explicitly denied read, write, and execute permissions.
  3. Other system users cannot access the file contents, even if they have system access to the physical storage.

This model is particularly critical on multi-user systems where world-readable files (default 0o644) would expose API keys and tokens to any authenticated user on the machine.

Summary

  • Agent-Reach stores credentials in ~/.agent_reach.yaml by default, configurable via the AGENT_REACH_CONFIG environment variable.
  • The save_config() function in agent_reach/config.py automatically applies 0o600 permissions using os.chmod immediately after writing data.
  • The set() and get() functions provide a secure key-value API that maintains these permission guarantees through every write operation.
  • This security model ensures only the file owner can access sensitive configuration data, preventing unauthorized access on shared systems.

Frequently Asked Questions

What does 0o600 mean in Unix file permissions?

0o600 represents octal notation for file permissions where the owner has read and write access (6), while group and others have no permissions (0). This translates to rw------- in symbolic notation, meaning only the file owner can read or modify the file. According to the Agent-Reach source code, this is enforced at line 30 of agent_reach/config.py immediately after file creation.

Where does Agent-Reach store credentials by default?

By default, Agent-Reach stores credentials in ~/.agent_reach.yaml in the user's home directory. This path is determined by the CONFIG_PATH constant defined at line 7 of agent_reach/config.py, which uses Path.expanduser() to resolve the tilde symbol to the absolute home directory path.

How can I change the credential storage location?

Set the AGENT_REACH_CONFIG environment variable to an absolute path before importing the config module. For example, export AGENT_REACH_CONFIG=/path/to/secure/config.yaml will redirect all credential storage operations to that location. The .env.example file demonstrates this pattern, and the save_config() function will create the new directory structure and apply 0o600 permissions regardless of the custom path.

Is the credential file encrypted or just permission-restricted?

The current implementation in agent_reach/config.py uses permission-based security (0o600) rather than encryption. While the file is inaccessible to other users through filesystem permissions, the contents are stored as plain YAML text. Users requiring additional security should implement encryption at the application level or use encrypted filesystems, as the current security model relies solely on operating system access controls.

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 →