# Secure Storage of Credentials in Agent-Reach: Protecting Cookies and Tokens in `~/.agent-reach/config.yaml`

> Learn how Agent-Reach securely stores credentials like cookies and tokens in config.yaml using 0o600 permissions, secret masking, and environment variable fallbacks for robust protection.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: best-practices
- Published: 2026-06-27

---

**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`](https://github.com/Panniantong/Agent-Reach/blob/main/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`](https://github.com/Panniantong/Agent-Reach/blob/main/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:

```python
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 `…`.

```python
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.

```python
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`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) automates the extraction of authentication cookies from Chrome and other browsers, then persists them securely through the `Config` class.

```python
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.

```python
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 `Config` class creates `~/.agent-reach/config.yaml` with strict `0o600` permissions using `os.open()` with `stat.S_IRUSR | stat.S_IWUSR` in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_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()` in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) extracts cookies and stores them via `Config.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`](https://github.com/Panniantong/Agent-Reach/blob/main/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`](https://github.com/Panniantong/Agent-Reach/blob/main/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`](https://github.com/Panniantong/Agent-Reach/blob/main/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.