How Agent Reach Stores and Secures Credentials Like Cookies and Tokens
Agent Reach isolates sensitive credentials in a private YAML file at ~/.agent-reach/config.yaml with strict Unix permissions (0o600), supports environment variable overrides for CI/CD workflows, and validates browser cookie imports before persisting them to disk.
The Panniantong/Agent-Reach repository implements a unified credential management system that keeps authentication material—cookies, API tokens, and OAuth secrets—out of the source tree while providing a secure, programmatic interface for channel modules. This design follows security-by-default principles: least-privilege file access, explicit secret loading, and clear audit boundaries between user data and application code.
The Centralized Config Architecture
All credential storage flows through a single abstraction point defined in agent_reach/config.py. This module creates a hidden directory in the user’s home folder and enforces OS-level permissions that prevent other system users from reading authentication material.
File Structure and Permissions
When the Config class initializes, it ensures the storage location exists with owner-only access:
- Directory:
~/.agent-reach/created with mode0o700(rwx------) - File:
~/.agent-reach/config.yamlwritten with mode0o600(rw-------)
The helper make_private_dir establishes these constraints immediately upon instantiation, eliminating the risk of accidental world-readable credential files.
The Config Class Interface
The Config class provides three primary methods for secret management:
get(key, default=None): Retrieves a value by key, first checking an uppercase environment variable of the same name, then falling back to the YAML file. This enables operators to inject secrets viaexport KEY=valuewithout touching the disk.set(key, value): Persists a key-value pair toconfig.yamlusing an atomic write-and-replace strategy, ensuring data integrity even if the process crashes mid-write.delete(key): Removes a secret and rewrites the file, guaranteeing that revoked credentials leave no residual data in the storage medium.
Cookie Handling and Validation
Browser cookies represent a high-risk credential type because they often contain session tokens with extended lifetimes. Agent Reach handles these through a dedicated validation layer before storage.
Browser Cookie Import
The [cookie_extract.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) module accepts cookie exports from Chrome, Firefox, or manual textual formats. It validates required fields—name, value, domain, and path—then concatenates entries into platform-specific strings (e.g., the cookie header format expected by Twitter).
# agent_reach/cookie_extract.py (conceptual flow)
from agent_reach.config import Config
def import_cookies(platform: str, cookie_file: Path):
config = Config()
validated = validate_cookie_format(cookie_file)
cookie_string = format_for_header(validated)
config.set(f"{platform.upper()}_COOKIE", cookie_string)
This approach ensures that malformed or incomplete cookie dumps never reach the persistent store.
Storage Format and Access
Once validated, cookies are stored as plain key-value pairs in the YAML file. Channels retrieve them at runtime via the standard Config interface:
# Example: Retrieving Twitter cookies in a channel implementation
from agent_reach.config import Config
def make_authenticated_request():
cfg = Config()
cookie = cfg.get("TWITTER_COOKIE")
headers = {"Cookie": cookie}
# ... proceed with HTTP request
The credential string never appears in source control, logs, or error traces; it exists only in the private config file and the transient memory of the requesting process.
Token and API Key Management
Beyond browser cookies, Agent Reach stores API keys and OAuth secrets using identical primitives. The repository designates conventional uppercase keys for each platform:
TWITTER_COOKIE/TWITTER_CSRF_TOKENREDDIT_CLIENT_ID/REDDIT_CLIENT_SECRETGITHUB_TOKENOPENAI_API_KEY
Environment Variable Fallback
The Config.get method implements a precedence hierarchy that prioritizes environment variables over file storage:
# agent_reach/config.py (simplified)
def get(self, key: str, default: Any = None) -> Any:
env_key = key.upper()
return os.getenv(env_key) or self._data.get(key, default)
This design supports containerized deployments and CI/CD pipelines where operators inject secrets via orchestration secrets rather than mounting host files.
Channel Integration
Each platform channel (located in agent_reach/channels/) imports the Config class and requests only the specific keys it requires. For example, a Reddit channel would access credentials like this:
from agent_reach.config import Config
config = Config()
client_id = config.get("REDDIT_CLIENT_ID")
client_secret = config.get("REDDIT_CLIENT_SECRET")
# Use credentials in OAuth flow
This compartmentalization ensures that a compromise in one channel module does not automatically grant access to unrelated platform credentials.
Security Implementation Details
Permission Hardening
The atomic write mechanism in Config._save explicitly sets file permissions before moving the temporary file into place:
# agent_reach/config.py
def _save(self):
tmp = self.config_path.with_suffix(".tmp")
with open(tmp, "w", encoding="utf-8") as f:
yaml.safe_dump(self._data, f)
os.chmod(tmp, stat.S_IRUSR | stat.S_IWUSR) # 0o600
tmp.replace(self.config_path)
This guarantees that even if the default umask is permissive, the resulting config.yaml remains readable only by the file owner.
Isolation from Source Code
No credential values are hard-coded in the repository. The Config constructor raises sensible defaults (empty dictionaries) if the file is missing, and the doctor diagnostic tool (in agent_reach/doctor.py) can report which expected keys are absent without exposing the values of present keys. This architecture satisfies the principle that credentials are data, not code, keeping secrets out of Git history and package distributions.
Practical Usage Examples
Storing a Twitter Cookie via CLI
After exporting cookies from your browser to a text file, import them securely:
python -m agent_reach.cli cookie-import \
--platform twitter \
--file ~/Downloads/twitter_cookies.txt
Behind the scenes, this invokes cookie_extract.py, validates the format, and executes Config.set("TWITTER_COOKIE", ...) with the resulting string.
Retrieving a GitHub Token
from agent_reach.config import Config
cfg = Config()
token = cfg.get("GITHUB_TOKEN")
import requests
response = requests.get(
"https://api.github.com/user",
headers={"Authorization": f"Bearer {token}"}
)
Removing a Revoked Credential
from agent_reach.config import Config
cfg = Config()
cfg.delete("OLD_API_KEY")
# The file is immediately rewritten without the deleted entry
Summary
- Storage Location: Credentials reside in
~/.agent-reach/config.yaml, isolated from the application source tree. - Permission Model: Directory
0o700and file0o600ensure only the owner can read or write secrets. - Access Pattern: The
Configclass inagent_reach/config.pyprovidesget,set, anddeletewith environment variable fallback. - Cookie Workflow:
agent_reach/cookie_extract.pyvalidates browser exports before persisting them viaConfig.set. - Security Guarantees: Atomic writes, explicit permission setting, and no hard-coded defaults prevent accidental credential exposure.
Frequently Asked Questions
Where does Agent Reach store my API keys and cookies?
Agent Reach stores all credentials in a YAML file located at ~/.agent-reach/config.yaml. The Config class in agent_reach/config.py manages this path, ensuring the directory is created with 0o700 permissions and the file itself is written with 0o600 permissions, making it accessible only to your user account.
Can I use environment variables instead of the config file?
Yes. The Config.get() method checks for an environment variable matching the uppercase key name before falling back to the file. For example, if you set export GITHUB_TOKEN=ghp_xxx, calls to Config().get("GITHUB_TOKEN") will return that value without reading the disk, ideal for CI/CD pipelines and containerized deployments.
How does Agent Reach prevent other users on the system from reading my cookies?
The implementation uses explicit Unix permission bits. The make_private_dir function creates the ~/.agent-reach directory with 0o700 (rwx------), and the _save method in Config applies stat.S_IRUSR | stat.S_IWUSR (0o600) to the temporary file before atomically replacing the live config file. This blocks group and other read access regardless of the system umask.
What happens if I need to revoke or delete a credential?
You can call Config().delete("KEY_NAME") programmatically, or use the CLI equivalent (e.g., agent_reach config delete --key KEY_NAME). This method removes the key from the internal dictionary and immediately rewrites the YAML file using the atomic _save procedure, ensuring the revoked credential leaves no trace in the storage file.
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 →