# Security Practices for Storing Cookies and Tokens in Agent‑Reach

> Learn secure cookie and token storage in Agent-Reach. Discover practices like owner-only file permissions and atomic creation for system security.

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

---

**Agent‑Reach enforces strict owner-only file permissions (mode `0o600`), protected directories (mode `0o700`), and atomic file creation to ensure authentication cookies and tokens remain inaccessible to other users on the system.**

Agent‑Reach is an open‑source tool that extracts and manages authentication data from web browsers, requiring robust safeguards for sensitive credentials on disk. The codebase treats cookies and tokens as high‑value assets, implementing POSIX permission controls and atomic filesystem operations to eliminate exposure windows. These security practices for storing cookies and tokens are enforced across the cookie extraction logic, configuration management, and legacy compatibility layers.

## Restrict File Access with Owner‑Only Permissions (0o600)

The foundation of Agent‑Reach’s security model is the **owner‑only file permission** mode `0o600` (read/write for the file owner only). All credential files, including browser‑extracted cookies and API tokens, are created using the `_open_owner_only()` helper function in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py).

This function opens files with the flags `O_WRONLY | O_CREAT | O_TRUNC` and passes the explicit mode `stat.S_IRUSR | stat.S_IWUSR` (0o600) to `os.open()`. By setting the permission atomically at creation time, the system guarantees the file never exists with default world‑readable permissions.

The configuration persistence layer in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) reuses this primitive. When `Config.save()` writes the user’s settings—including stored authentication tokens—it invokes `_open_owner_only()`, ensuring the JSON or YAML configuration file inherits the same restrictive permissions.

## Harden Directory Permissions (0o700)

Securing individual files is insufficient if surrounding directories allow traversal or listing by other users. Agent‑Reach addresses this by creating parent directories with mode `0o700` (rwx for owner only) using the `make_private_dir()` utility.

The standard storage location `~/.agent-reach` and the legacy fallback `~/.config/xfetch` both receive this treatment. This prevents unauthorized users from discovering credential filenames through directory listings or accessing files via path traversal on systems where the parent permissions might otherwise permit it.

## Eliminate Race Conditions with Atomic Creation

A critical vulnerability in credential storage is the **time‑of‑check to time‑of‑use race condition**, where a file is created with default permissions and only later restricted via `chmod()`. Agent‑Reach eliminates this window by specifying permissions during the initial `open()` system call.

The `_open_owner_only()` implementation attempts to use `os.open()` with mode `0o600` directly. On platforms where these flags are unsupported (such as Windows), the code falls back to a standard `open()` followed immediately by `os.chmod(path, 0o600)`, minimizing the exposure interval.

## Runtime Permission Verification

Agent‑Reach defends against misconfigured environments by verifying and tightening permissions on existing files. When loading cookie files like [`xhs-cookies.json`](https://github.com/Panniantong/Agent-Reach/blob/main/xhs-cookies.json), the CLI checks current permissions using `_owner_only()` and `_owner_only_dir()` helpers. If a user manually created a file with lax permissions, the tool automatically corrects them to `0o600` before processing the credentials.

This self‑healing behavior is validated by unit tests in [`tests/test_cookie_extract_perms.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cookie_extract_perms.py) and [`tests/test_config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_config.py), which assert that files and directories maintain expected permissions after creation and after programmatic tightening.

## Implementation Examples

The following patterns demonstrate how to implement these security practices when storing sensitive data:

### Creating a Private Cookie File

```python
from pathlib import Path
import json

def _open_owner_only(path: str):
    """
    Open *path* for writing, atomically creating it with mode 0o600.
    """
    import os, stat
    try:
        fd = os.open(
            path,
            os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
            stat.S_IRUSR | stat.S_IWUSR,   # 0o600

        )
        if os.name != "nt":
            os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
        return os.fdopen(fd, "w", encoding="utf-8")
    except OSError:
        handle = open(path, "w", encoding="utf-8")
        if os.name != "nt":
            os.chmod(path, 0o600)
        return handle

# Usage: Writing XiaoHongShu cookies

cookie_path = Path.home() / ".agent-reach" / "xhs-cookies.json"
with _open_owner_only(str(cookie_path)) as f:
    json.dump({"cookie_string": cookie_str}, f, indent=2)

```

### Creating a Protected Directory

```python
from agent_reach.utils.paths import make_private_dir
from pathlib import Path

# Creates ~/.agent-reach with mode 0o700 if it does not exist

make_private_dir(Path.home() / ".agent-reach")

```

### Saving Configuration Tokens Securely

```python

# In agent_reach/config.py → Config.save()

with _open_owner_only(self.config_path) as f:
    json.dump(self._data, f, indent=2)

```

### Legacy Session Synchronization

The `_sync_xfetch_session()` function in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) demonstrates backward‑compatible secure storage by writing the legacy `xfetch` session file using the same `_open_owner_only()` primitive:

```python
def _sync_xfetch_session(auth_token: str, ct0: str) -> None:
    from agent_reach.utils.paths import make_private_dir
    import os, json
    
    xfetch_dir = os.path.join(os.path.expanduser("~"), ".config", "xfetch")
    make_private_dir(xfetch_dir)
    session_path = os.path.join(xfetch_dir, "session.json")
    
    # ... load existing JSON if present ...

    session_data = {"auth_token": auth_token, "ct0": ct0}
    
    with _open_owner_only(session_path) as sf:
        json.dump(session_data, sf, indent=2)

```

## Summary

Agent‑Reach implements comprehensive security practices for storing cookies and tokens through the following measures:

- **Atomic file creation** with mode `0o600` via `_open_owner_only()` ensures credentials are never written with world‑readable permissions.
- **Directory isolation** using mode `0o700` via `make_private_dir()` prevents unauthorized discovery and traversal of credential storage paths.
- **Runtime hardening** automatically tightens permissions on existing files that may have been created with insecure defaults.
- **Cross‑platform fallbacks** maintain security posture on Windows and other platforms where POSIX flags may be unavailable.
- **Test enforcement** via [`test_cookie_extract_perms.py`](https://github.com/Panniantong/Agent-Reach/blob/main/test_cookie_extract_perms.py) and [`test_config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/test_config.py) guarantees these protections persist across code changes.

## Frequently Asked Questions

### What file permissions does Agent‑Reach use for cookie storage?

Agent‑Reach creates all credential files with **mode 0o600** (owner read/write only). This is enforced atomically at file creation time through the `_open_owner_only()` helper in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py), which passes `stat.S_IRUSR | stat.S_IWUSR` to `os.open()`.

### How does Agent‑Reach prevent race conditions when creating credential files?

The codebase eliminates race conditions by specifying the restrictive mode `0o600` during the initial `open()` system call rather than creating the file and subsequently calling `chmod()`. On platforms where atomic creation with permissions is unsupported, it immediately follows the `open()` with `chmod(path, 0o600)` to minimize the exposure window.

### Does Agent‑Reach protect legacy configuration directories?

Yes. The function `_sync_xfetch_session()` in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) creates the legacy `~/.config/xfetch` directory using `make_private_dir()`, which applies mode `0o700`. This ensures backward compatibility with older `xfetch` configurations while maintaining the same security posture as the modern `~/.agent-reach` path.

### How does the CLI handle existing files with insecure permissions?

When loading existing cookie files (such as [`xhs-cookies.json`](https://github.com/Panniantong/Agent-Reach/blob/main/xhs-cookies.json)), the CLI verifies permissions using `_owner_only()` and `_owner_only_dir()`. If a file is detected with permissions more permissive than `0o600`, the tool automatically tightens them before reading the credentials, protecting against manual misconfiguration or restored backups with incorrect modes.