# How Agent Reach Handles Credential Security and File Permissions

> Secure your credentials with Agent Reach. Learn how it uses 0o700/0o600 permissions and atomic operations to protect files and mask secrets.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-07-05

---

**Agent Reach secures credentials by creating directories with 0o700 permissions, writing files with 0o600 using atomic open operations, and masking secrets in logs and diagnostic output.**

The Panniantong/Agent-Reach library implements defense-in-depth for credential security, combining restrictive POSIX file permissions with runtime masking to prevent accidental secret exposure. This article examines the specific mechanisms—including `make_private_dir()`, `Config.save()`, and `_open_owner_only()`—that ensure API keys and tokens remain accessible only to the file owner.

## Restrictive File System Permissions

### Private Directory Creation with make_private_dir()

In [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/paths.py), the `make_private_dir()` function establishes the foundation for secure credential storage by creating directories with mode `0o700` (owner read/write/execute only). After creation, the function explicitly calls `chmod 700` on POSIX systems to ensure the permission mask is applied regardless of umask settings.

### Atomic Configuration File Writes in Config.save()

When persisting secrets to disk, the `Config.save()` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) eliminates race conditions by opening files with restricted permissions atomically. The implementation uses `os.open(..., stat.S_IRUSR | stat.S_IWUSR)`, which creates the file with mode `0o600` before any data is written. For platforms where low-level flags are unavailable, the code falls back to a standard `open()` followed by an explicit `chmod 600` call.

### Secure Sync File Operations via _open_owner_only()

Credential synchronization for XFetch sessions and Bird CLI environments uses the `_open_owner_only()` helper defined in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) (lines 49-73). This utility opens target files with mode `0o600` atomically, preventing a temporary window where the file might be world-readable during creation.

## Runtime Secret Protection

Beyond storage permissions, Agent Reach ensures secrets never appear in logs or stack traces. The `Config.to_dict()` method in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (lines 108-127) automatically masks any key containing identifiers like `key`, `token`, `cookie`, or `auth`, displaying only the first eight characters followed by an ellipsis. The codebase contains no print statements or logging calls that output raw credential values.

## Environment Variable Integration

The `Config.get()` method implements a secure fallback chain: it first checks the YAML configuration file, then searches for an uppercase environment variable of the same name. This allows users to store sensitive values entirely in memory via environment variables, keeping credentials off the disk entirely when preferred. This logic resides in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) at lines 75-84.

## Practical Implementation Example

The following example demonstrates the automatic creation of private directories, atomic file writes with restricted permissions, and runtime masking:

```python
from agent_reach.config import Config

# Initialize config; creates ~/.agent-reach with 0700 permissions

cfg = Config()

# Store secret; file is created atomically with 0600 permissions

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

# Retrieval checks file first, then environment variables

api_key = cfg.get("openai_api_key")

# Output is automatically masked in diagnostic views

print(cfg.to_dict())  # Shows 'sk-xxxx…' instead of full key

```

## Summary

- **Directory permissions**: `make_private_dir()` enforces `0o700` (owner-only access) in [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/paths.py)
- **File permissions**: `Config.save()` and `_open_owner_only()` use atomic `0o600` creation to prevent race conditions
- **Memory safety**: Secrets are masked in `to_dict()` and never logged in plaintext
- **Flexible storage**: `Config.get()` supports environment variables as a disk-free alternative

## Frequently Asked Questions

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

Agent Reach creates directories with `0o700` (read/write/execute for owner only) and files with `0o600` (read/write for owner only). These permissions are enforced atomically using `os.open()` with `stat.S_IRUSR | stat.S_IWUSR` flags before any data is written, as implemented in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) and [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py).

### How does Agent Reach prevent secrets from appearing in logs?

The `Config.to_dict()` method automatically detects keys containing secret identifiers (such as `key`, `token`, `cookie`, or `auth`) and masks their values to the first eight characters followed by an ellipsis. The codebase contains no logging statements that output raw credential values.

### Can I store credentials outside the filesystem with Agent Reach?

Yes. The `Config.get()` method checks for environment variables as a fallback after checking the YAML file. Setting an uppercase environment variable allows you to keep secrets entirely in memory without writing them to disk.

### Where are the permission enforcement functions located?

Directory creation logic resides in [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/paths.py) (`make_private_dir()`), configuration file handling is in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) (`Config.save()`), and atomic file operations for sync files are implemented in [`agent_reach/cookie_extract.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cookie_extract.py) (`_open_owner_only()`).