Agent Reach Credential Storage Security: How Secrets Are Protected

Agent Reach stores all API keys, OAuth tokens, and browser cookies in a single YAML file at ~/.agent-reach/config.yaml with restrictive 0o600 file permissions, environment variable fallbacks, and automatic masking of sensitive values to prevent leakage.

Agent Reach is an open-source agent framework that handles sensitive authentication credentials for various services. The project implements a comprehensive Agent Reach credential storage security model through a centralized configuration manager that ensures secrets are never world-readable and are masked in diagnostic output.

Core Storage Architecture

The Config Class Centralization

All credential read and write operations are encapsulated in the Config class located in [agent_reach/config.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py). This design ensures that every credential passes through a single, permission-controlled code path regardless of whether it is set via CLI, imported from browser cookies, or configured programmatically.

The configuration file resides at:


~/.agent-reach/config.yaml

The _ensure_dir() method creates this directory on first use with mkdir(parents=True, exist_ok=True), guaranteeing the path exists before any write operation occurs.

Strict File Permissions (0o600)

When saving credentials, the Config.save() method opens the file using low-level os.open() flags:

os.open(path, flags, stat.S_IRUSR | stat.S_IWUSR)

This creates the file with mode 0o600 (read/write for owner only). If the low-level flags are unavailable (e.g., on Windows), the implementation falls back to a standard open() call, but the directory creation still minimizes exposure by ensuring the parent path exists with appropriate restrictions.

Security Mechanisms

Environment Variable Fallback

To support users who prefer not to store secrets on disk, Config.get() implements a priority lookup system:

  1. First checks the YAML configuration file
  2. Then falls back to environment variables via os.environ.get(key.upper())

This allows sensitive values to be injected at runtime without ever touching the filesystem, reducing the attack surface for credential theft.

Sensitive Value Masking

When generating diagnostic output or debugging, Config.to_dict() automatically masks any key containing "key", "token", "password", or "proxy". The masking preserves only the first 8 characters followed by an ellipsis:

cfg = Config()
print(cfg.to_dict())

# Output: {'github_token': 'ghp_XXXX...', 'exa_api_key': 'sk-abc12...'}

This prevents accidental exposure of full secrets in logs, stack traces, or CLI output.

Legacy Sync Protection

When importing Twitter cookies, the helper functions in [agent_reach/cookie_extract.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) write the same credentials to auxiliary third-party tool locations:

  • ~/.config/xfetch/session.json
  • ~/.config/bird/credentials.env

These files are also created with mode 0o600, ensuring consistent security across the credential ecosystem even when syncing to external tool configurations.

Practical Implementation Examples

Storing Credentials via CLI


# Set a GitHub token securely

agent-reach configure github-token ghp_XXXXXXXXXXXXXXXXXXXX

Behind the scenes, the CLI in [agent_reach/cli.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) parses this input and calls config.set("github_token", value), which triggers the secure save routine.

Programmatic Configuration

from agent_reach.config import Config

cfg = Config()                     # loads ~/.agent-reach/config.yaml

cfg.set("exa_api_key", "sk-abc123")   # writes with 0o600 permissions

print(cfg.to_dict())               # => {'exa_api_key': 'sk-abc12...'}

Environment Variable Override

import os
os.environ["EXA_API_KEY"] = "sk-xyz987"

from agent_reach.config import Config
cfg = Config()

# Returns "sk-xyz987" from environment, not from file

key = cfg.get("exa_api_key")

Verifying File Permissions

$ ls -l ~/.agent-reach/config.yaml
-rw------- 1 user user 1234 Jun  6 12:34 /home/user/.agent-reach/config.yaml

The -rw------- permission string confirms that only the file owner can read or write the configuration.

Summary

  • Centralized storage: All secrets reside in ~/.agent-reach/config.yaml managed by the Config class in agent_reach/config.py
  • Strict permissions: Files are created with mode 0o600 using os.open() with stat.S_IRUSR | stat.S_IWUSR flags
  • Flexible input: Config.get() supports both file-based and environment variable sources, checking os.environ as a fallback
  • Leak prevention: Config.to_dict() masks sensitive keys (containing "key", "token", "password", or "proxy") to prevent full secret exposure
  • Third-party sync: Cookie extraction utilities maintain 0o600 permissions when writing to auxiliary files like ~/.config/xfetch/session.json

Frequently Asked Questions

Where does Agent Reach store API keys and tokens?

Agent Reach stores all credentials in a single YAML file located at ~/.agent-reach/config.yaml. The Config class in agent_reach/config.py manages all read and write operations to this file, ensuring consistent security controls.

What file permissions does Agent Reach use for credential storage?

The implementation uses mode 0o600 (owner read/write only) via os.open() with stat.S_IRUSR | stat.S_IWUSR flags. This prevents other users on the system from accessing the configuration file, and unit tests in tests/test_config.py verify these permissions are correctly applied.

How does Agent Reach prevent credentials from appearing in logs?

The to_dict() method automatically masks any configuration key containing "key", "token", "password", or "proxy", showing only the first 8 characters followed by an ellipsis. This ensures that debug output and diagnostic dumps never reveal complete secret values.

Can I use environment variables instead of the config file?

Yes. The Config.get() method checks for environment variables using os.environ.get(key.upper()) before falling back to the YAML file. This allows you to keep secrets exclusively in environment variables if your security policy prohibits on-disk storage.

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 →