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:
- First checks the YAML configuration file
- 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.yamlmanaged by theConfigclass inagent_reach/config.py - Strict permissions: Files are created with mode 0o600 using
os.open()withstat.S_IRUSR | stat.S_IWUSRflags - Flexible input:
Config.get()supports both file-based and environment variable sources, checkingos.environas 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →