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 mode 0o700 (rwx------)
  • File: ~/.agent-reach/config.yaml written with mode 0o600 (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 via export KEY=value without touching the disk.
  • set(key, value): Persists a key-value pair to config.yaml using 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.

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.

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_TOKEN
  • REDDIT_CLIENT_ID / REDDIT_CLIENT_SECRET
  • GITHUB_TOKEN
  • OPENAI_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

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 0o700 and file 0o600 ensure only the owner can read or write secrets.
  • Access Pattern: The Config class in agent_reach/config.py provides get, set, and delete with environment variable fallback.
  • Cookie Workflow: agent_reach/cookie_extract.py validates browser exports before persisting them via Config.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:

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 →