Secure Storage of Credentials in Agent-Reach: Protecting Cookies and Tokens in `~/.agent-reach/config.yaml`
Agent-Reach stores API keys, OAuth tokens, and browser cookies in ~/.agent-reach/config.yaml with strict 0o600 file permissions, automatic secret masking, and environment-variable fallbacks to prevent credential exposure.
The Panniantong/Agent-Reach repository implements a hardened configuration system that balances security with usability for storing sensitive authentication data. By centralizing credential management through a dedicated Config class, the tool ensures that tokens and cookies extracted from browsers remain protected on the local filesystem while remaining accessible to the application.
Strict File Permissions and Secure Creation
The Config class in agent_reach/config.py implements defense-in-depth for the secure storage of credentials by ensuring the configuration file is created with restrictive permissions from the very first write operation.
When instantiating Config(), the constructor checks for the existence of the ~/.agent-reach directory and creates the config.yaml file with owner-only permissions (0o600). This prevents any brief window where credentials could be world-readable during initial setup.
The implementation uses low-level file operations to guarantee atomic creation with correct permissions:
from agent_reach.config import Config
cfg = Config() # Creates ~/.agent-reach/config.yaml with 600 permissions if missing
Inside Config.save(), the code calls os.open() with stat.S_IRUSR | stat.S_IWUSR to ensure the file is readable and writable only by the owner. This permission model applies to all subsequent writes, including when storing cookies and tokens extracted from browser sessions.
Masking Secrets in Output
To prevent accidental credential leakage in logs or CLI output, the Config class implements automatic masking through the to_dict() method. When displaying configuration values, keys containing sensitive patterns—specifically those matching *key*, *token*, *password*, or *proxy*—are truncated to the first eight characters followed by ….
cfg.set("twitter_auth_token", "ABCD1234EFGH5678")
print(cfg.to_dict())
# Output: {'twitter_auth_token': 'ABCD1234…'}
This masking ensures that even if a user prints the configuration object or logs it for debugging, the full secret values remain concealed while still allowing partial identification of which credential is configured.
Environment Variable Fallback
The credential system supports secure overrides through environment variables. The Config.get() method implements a lookup hierarchy that first checks the in-memory YAML cache, then falls back to uppercase environment variables with the same name.
token = cfg.get("twitter_auth_token") # Returns $TWITTER_AUTH_TOKEN if not in YAML
This design allows users to inject credentials through secure environment variable mechanisms (such as CI/CD secrets managers) without ever writing sensitive values to disk, providing an additional layer of security for production deployments.
Browser Cookie Extraction and Storage
The configure_from_browser() helper in agent_reach/cookie_extract.py automates the extraction of authentication cookies from Chrome and other browsers, then persists them securely through the Config class.
from agent_reach.cookie_extract import configure_from_browser
from agent_reach.config import Config
cfg = Config()
results = configure_from_browser("chrome", cfg)
for platform, ok, msg in results:
print(f"{platform}: {'✅' if ok else '❌'} – {msg}")
When cookies are extracted, they are written to the YAML file using Config.set(), which ensures the 0o600 permissions are maintained. This bridges the gap between browser-based authentication and secure local storage without requiring manual copying of cookie strings.
Feature Configuration Validation
The Config.is_configured(feature) method provides feature-specific validation to verify that all required credentials for optional integrations (such as Twitter X or Exa Search) are present before attempting to use them.
if cfg.is_configured("twitter_xreach"):
print("Twitter X is ready")
else:
print("Missing auth_token or ct0")
This validation checks for the presence of specific key combinations required for each feature, allowing the CLI to warn users about missing credentials early in the execution flow rather than failing during API calls.
Summary
- File permissions: The
Configclass creates~/.agent-reach/config.yamlwith strict0o600permissions usingos.open()withstat.S_IRUSR | stat.S_IWUSRinagent_reach/config.py. - Secret masking: The
to_dict()method automatically truncates sensitive values (keys matching*token*,*key*,*password*,*proxy*) to prevent log leakage. - Environment fallback:
Config.get()checks uppercase environment variables before reading from the YAML file, enabling secure credential injection. - Browser integration:
configure_from_browser()inagent_reach/cookie_extract.pyextracts cookies and stores them viaConfig.set()with maintained permissions. - Feature validation:
is_configured()verifies complete credential sets for specific integrations before execution.
Frequently Asked Questions
What file permissions does Agent-Reach use for the config file?
Agent-Reach creates and maintains ~/.agent-reach/config.yaml with 0o600 permissions (owner read/write only). According to the source code in agent_reach/config.py, the Config.save() method uses os.open() with stat.S_IRUSR | stat.S_IWUSR to ensure no other users can read the file containing your cookies and tokens.
How does Agent-Reach prevent secrets from appearing in logs?
The Config.to_dict() method in agent_reach/config.py automatically masks any configuration keys containing key, token, password, or proxy by truncating their values to the first eight characters followed by an ellipsis. This ensures that even if you print the configuration object or enable debug logging, the full credential values remain hidden.
Can I use environment variables instead of the config file?
Yes. The Config.get() method implements a fallback mechanism that checks for uppercase environment variables before reading from ~/.agent-reach/config.yaml. For example, if you set TWITTER_AUTH_TOKEN in your environment, calling cfg.get("twitter_auth_token") will return that value without requiring the token to be stored on disk.
How are browser cookies securely transferred to the config file?
The configure_from_browser() function in agent_reach/cookie_extract.py extracts cookies from browsers like Chrome and immediately writes them to the config using Config.set(). Because the Config class maintains 0o600 permissions on the underlying file throughout this process, the credentials are never stored in a world-readable location, even during the extraction and writing phase.
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 →