# How Agent-Reach Stores and Protects Credentials: Security Model Explained

> Discover Agent-Reach's robust security model for storing credentials. Learn how API keys and secrets are protected with strict permissions and automatic masking to prevent exposure.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-07-11

---

**Agent-Reach stores API keys and secrets in `~/.agent-reach/config.yaml` with strict Unix permissions (`0o600` for files and `0o700` for directories), supports environment variable overrides, and automatically masks sensitive values in CLI output to prevent accidental exposure.**

Agent-Reach, an open-source automation framework maintained at `Panniantong/Agent-Reach`, implements a defense-in-depth security model for credential storage that prioritizes file system isolation and user-controlled access. Rather than relying on external secret managers, the codebase enforces strict permission controls, optional transient injection via environment variables, and automatic masking of sensitive data. This article examines the specific implementation details found in the configuration handling and utility modules.

## Private Directory and File Permissions

The foundation of Agent-Reach’s security model relies on Unix file permissions to ensure only the owner can access stored credentials.

### Secure Directory Creation

When initializing the configuration store, Agent-Reach creates the storage directory using `make_private_dir` in [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/paths.py) (lines 10-16). This helper function explicitly sets the directory mode to `0o700`, granting the owner exclusive read, write, and execute permissions while denying all access to group and other users.

### Restricted File Access

The `Config.save` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 52-73) enforces the same owner-only restriction for the configuration file itself. The implementation uses `os.open` with flags that atomically create the file with mode `0o600` (owner read/write only). On platforms where these specific flags are unavailable, the code falls back to creating the file normally and immediately applying `chmod 0o600` to ensure the permissions are set regardless of umask settings.

## Environment Variable Fallback

Agent-Reach provides a transient injection mechanism that bypasses disk storage entirely. The `Config.get` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 75-84) implements a two-tier lookup strategy:

1.  First, it checks the YAML configuration file for the requested key.
2.  If not found, it searches for an environment variable matching the uppercase version of the key name.

This allows operators to export `OPENAI_API_KEY` or `EXA_API_KEY` in their shell session without ever persisting the value to [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml), reducing the attack surface for systems that manage secrets through environment-specific injection rather than files.

## Secret Masking in Output

To prevent credential leakage in logs and console output, the `Config.to_dict` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 108-130) automatically masks sensitive values. When the configuration is displayed—whether via the CLI or programmatic inspection—any key containing substrings like `key`, `token`, `password`, `secret`, or `cookie` is truncated to show only the first eight characters followed by an ellipsis (`...`). This ensures that even if a user accidentally shares their configuration output, the full secrets remain protected.

## Browser Cookie Handling

Browser cookies extracted for automated sessions receive the same protection as manually entered API keys. The `cookie_extract.configure_from_browser` function in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) (lines 267-292) extracts session cookies from the browser, converts them into a header string, and stores them via `Config.set`. Consequently, these cookies inherit the `0o600` file permissions, directory isolation, and masking behavior applied to all other credentials.

## Practical Usage Examples

The following examples demonstrate the security model in practice, including permission verification and environment variable overrides.

Initialize the configuration manager and store a secret with automatic permission enforcement:

```python
from agent_reach.config import Config

# Creates ~/.agent-reach with 0o700 and config.yaml with 0o600

cfg = Config()

# Writes to config.yaml with owner-only permissions

cfg.set("openai_api_key", "sk-XXXXXXXXXXXXXXXXXXXXXXXX")

```

Retrieve credentials using the fallback chain (file first, then environment):

```python

# Checks config.yaml, then checks OPENAI_API_KEY env var

api_key = cfg.get("openai_api_key")

# Verify configuration completeness without exposing secrets

if cfg.is_configured("exa_search"):
    print("Exa Search credentials present")

```

Use environment variables to avoid disk persistence entirely:

```bash

# Set secret in environment (not written to disk)

export OPENAI_API_KEY="sk-YYYYYYYYYYYYYYYYYYYYYYYY"

# Agent-Reach reads this value without touching config.yaml

python -c "from agent_reach.config import Config; print(Config().get('openai_api_key'))"

```

View the configuration with automatic masking applied:

```bash

# Secret values are truncated to prevent exposure

$ agent-reach config view
{
  "openai_api_key": "sk-XXXXXX...",
  "exa_api_key": "XXXXXX..."
}

```

Remove sensitive data when no longer needed:

```python

# Deletes the key from config.yaml entirely

cfg.delete("openai_api_key")

```

## Summary

- **Private storage location**: The `~/.agent-reach` directory is created with `0o700` permissions, ensuring only the owner can access the path.
- **Strict file permissions**: Configuration files are written with `0o600` permissions via `os.open` in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py), preventing group or world access.
- **Environment override**: The `Config.get` method checks environment variables after the file, allowing secrets to be injected without disk persistence.
- **Automatic masking**: The `Config.to_dict` method masks keys containing `key`, `token`, `password`, or `cookie` to prevent leakage in logs and CLI output.
- **Unified cookie protection**: Browser cookies extracted via `cookie_extract.configure_from_browser` are stored with the same permission and masking rules as API keys.

## Frequently Asked Questions

### Where does Agent-Reach store API keys?

Agent-Reach stores all credentials in `~/.agent-reach/config.yaml` within the user’s home directory. This location is defined in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 20-22) and is created with owner-only permissions (`0o700` for the directory, `0o600` for the file).

### What file permissions does Agent-Reach use for credential storage?

The configuration directory uses mode `0o700` (owner read/write/execute only), and the YAML file uses mode `0o600` (owner read/write only). These permissions are enforced by `make_private_dir` in [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/paths.py) and `Config.save` in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py).

### Can I use environment variables instead of the config file?

Yes. The `Config.get` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 75-84) implements a fallback system: it first checks the YAML file, then searches for an uppercase environment variable with the same name. Setting `export OPENAI_API_KEY="..."` allows the application to run without writing the secret to disk.

### 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) (lines 108-130) automatically masks any configuration key containing sensitive substrings (`key`, `token`, `password`, `cookie`, etc.). When displayed, these values show only the first eight characters followed by an ellipsis, preventing accidental exposure in console output or log files.