Security Best Practices for Storing Cookies and API Keys in config.yaml
Agent-Reach stores sensitive credentials in ~/.agent-reach/config.yaml with 600 permissions, masks secrets in logs, and falls back to environment variables to keep API keys and browser cookies secure.
Agent-Reach is an open-source automation framework that manages user-specific secrets through a centralized YAML configuration. Understanding how to securely store cookies and API keys in config.yaml is essential to prevent credential leakage and unauthorized access. The repository implements several defensive patterns in agent_reach/config.py that you should follow when handling sensitive data.
Store Secrets in a Private User Directory
The Config class isolates sensitive data by storing the config.yaml file inside a hidden directory under the user's home folder. According to the source code in agent_reach/config.py (line 18), Config.CONFIG_DIR points to Path.home() / ".agent-reach", ensuring that credentials are never stored in the project repository or shared locations.
This design prevents accidental commits to version control. You should ensure that ~/.agent-reach/config.yaml remains excluded from any Git tracking and resides only in the current user's home directory.
Create the File with Restrictive Permissions
When saving configuration data, the Config.save() method enforces strict file permissions using low-level OS flags. As implemented in agent_reach/config.py (lines 49-60), the method opens the file with os.O_WRONLY | os.O_CREAT | os.O_TRUNC and applies mode stat.S_IRUSR | stat.S_IWUSR (octal 0o600), granting read and write access exclusively to the file owner.
from agent_reach.config import Config
cfg = Config()
cfg.set("openai_api_key", "sk-...")
On Unix systems, verify the permissions manually:
chmod 600 ~/.agent-reach/config.yaml
The code includes an OSError fallback (lines 64-67) for Windows environments where os.open flags are not fully supported. On Windows, manually restrict access using ACLs:
icacls ~/.agent-reach/config.yaml /grant %USERNAME%:R
Never Log or Print Raw Secrets
The Config class prevents accidental secret exposure through the to_dict() method. Before returning configuration data, it masks any key containing "key", "token", "password", or "proxy" by truncating the value and appending an ellipsis, as implemented in agent_reach/config.py (lines 101-110).
Always use to_dict() for debugging output instead of accessing config.data directly:
# Safe: masks sensitive values
print(cfg.to_dict())
# Unsafe: exposes raw credentials
print(cfg.data)
Prefer Environment Variables as a Fallback
The Config.get() method implements a secure fallback chain that prioritizes the YAML file but automatically checks environment variables. As shown in lines 70-78 of agent_reach/config.py, the method first attempts to retrieve the key from the config, then falls back to os.environ.get(key.upper()).
This pattern allows you to store short-lived secrets in environment variables while maintaining persistent configuration in the YAML file:
export OPENAI_API_KEY="sk-..."
# Checks config.yaml first, then $OPENAI_API_KEY
api_key = cfg.get("openai_api_key")
Validate Required Keys Per Feature
Before enabling functionality that requires credentials, use the is_configured() method to verify that all necessary secrets exist. The FEATURE_REQUIREMENTS dictionary (lines 22-28 in agent_reach/config.py) maps each feature to its required configuration keys.
This validation prevents runtime errors and ensures that sensitive operations only execute when properly authenticated:
if cfg.is_configured("twitter"):
# Safe to proceed with Twitter automation
pass
Separate Cookie Handling from Generic Storage
Browser cookies receive special handling in agent_reach/cookie_extract.py. The configure_from_browser function (lines 260-284) writes cookie strings to dedicated keys such as xhs_cookie, xueqiu_cookie, or twitter_cookies, keeping them isolated from other configuration entries.
When using the CLI to store cookies, the input is parsed but never logged in full. The cli._parse_twitter_cookie_input method (lines 51-58) only reports the count of extracted cookies rather than the raw content, preventing credential leakage in shell history or log files.
# Stores cookies without echoing values to stdout
agent-reach configure twitter-cookies "auth_token=AAA; ct0=BBB"
Summary
- Isolate credentials: Store
config.yamlin~/.agent-reach/outside version control. - Restrict permissions: The
Config.save()method automatically applies0o600permissions; manually verify withchmod 600on Unix. - Mask secrets: Use
Config.to_dict()to safely display configuration without exposing API keys or passwords. - Use environment fallbacks: Leverage
Config.get()to check environment variables when YAML values are missing. - Validate requirements: Call
is_configured()before accessing features that depend on sensitive keys. - Isolate cookies: Store browser cookies in dedicated keys and avoid logging raw cookie strings.
Frequently Asked Questions
How does Agent-Reach protect against accidental credential commits?
The framework stores all secrets in ~/.agent-reach/config.yaml within the user's home directory, not the project repository. This path is defined in Config.CONFIG_DIR (agent_reach/config.py line 18) and automatically created at runtime, ensuring sensitive files never reside in Git-tracked directories.
What permissions should the config.yaml file have?
The file should have 600 (octal 0o600) permissions, meaning only the owner can read and write. The Config.save() method enforces this by opening the file with os.O_WRONLY | os.O_CREAT and stat.S_IRUSR | stat.S_IWUSR flags. On Windows, you should manually set ACLs to restrict access to the current user.
How can I safely display configuration values for debugging?
Call Config.to_dict() rather than accessing the raw data dictionary. This method automatically masks values for keys containing "key", "token", "password", or "proxy", preventing secret leakage in logs or console output.
Does Agent-Reach support environment variables for secrets?
Yes. The Config.get() method checks the YAML file first, then falls back to an uppercase environment variable (e.g., OPENAI_API_KEY). This allows temporary overrides without modifying the persistent configuration file, useful for CI/CD pipelines or shared environments.
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 →