RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /How-to
  5. /How to Implement Secure File Operations for Agents
HOW-TO · RAG

How to Implement Secure File Operations for Agents

advanced·25 min·By Eruo Fredoline
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

File system tools working, security review needed, Python 3.10+

What this does

Secure file operations prevent path traversal, unauthorized access, command injection, and data leaks when agents interact with the file system. Security must be enforced at the tool level, not by convention.

Steps

  • Enforce an allowlist of permitted directories. Never rely on relative path safety alone.
import os

ALLOWED_DIRS = [
    os.path.abspath(os.path.expanduser("~/agent_workspace")),
    os.path.abspath("/tmp/agent_data"),
]

def validate_path(requested_path: str) -> str:
    abs_path = os.path.abspath(os.path.normpath(requested_path))
    for allowed in ALLOWED_DIRS:
        if abs_path.startswith(allowed):
            return abs_path
    raise PermissionError(f"Path {requested_path} is not in allowed directories")
  • Restrict file extensions. Only allow safe file types.
ALLOWED_EXTENSIONS = {".txt", ".md", ".json", ".csv", ".py", ".yaml", ".yml", ".log"}

def validate_extension(path: str):
    ext = os.path.splitext(path)[1].lower()
    if ext not in ALLOWED_EXTENSIONS:
        raise PermissionError(f"File extension {ext} is not allowed")
  • Set file size limits. Prevent agent from reading or writing huge files.
MAX_READ_SIZE = 10 * 1024 * 1024  # 10 MB
MAX_WRITE_SIZE = 5 * 1024 * 1024   # 5 MB

def validate_read_size(path: str):
    size = os.path.getsize(path)
    if size > MAX_READ_SIZE:
        raise ValueError(f"File too large: {size} bytes (max {MAX_READ_SIZE})")

def validate_write_size(content: str):
    if len(content.encode()) > MAX_WRITE_SIZE:
        raise ValueError(f"Content too large: {len(content)} bytes (max {MAX_WRITE_SIZE})")
  • Implement an audit log for all file operations.
import logging
import json

file_audit_logger = logging.getLogger("file_audit")

def audit_file_operation(agent_id: str, operation: str, path: str, status: str, details: str = ""):
    file_audit_logger.info(json.dumps({
        "agent": agent_id,
        "operation": operation,
        "path": path,
        "status": status,
        "details": details
    }))
  • Add the security wrapper to every file tool.
@tool
def secure_read_file(path: str, agent_id: str = "unknown") -> str:
    """Read a file with security validation."""
    try:
        safe = validate_path(path)
        validate_extension(safe)
        validate_read_size(safe)
        with open(safe, "r") as f:
            content = f.read()
        audit_file_operation(agent_id, "read", path, "success")
        return content
    except (PermissionError, ValueError) as e:
        audit_file_operation(agent_id, "read", path, "denied", str(e))
        return f"Access denied: {e}"
  • Prevent command injection in shell-based tools. Never pass user input directly to a shell.
import subprocess

@tool
def grep_file(pattern: str, path: str) -> str:
    """Search a file using grep (safe version)."""
    safe = validate_path(path)
    validate_extension(safe)
    # Use list form of subprocess, never shell=True with string interpolation
    result = subprocess.run(
        ["grep", "--", pattern, safe],
        capture_output=True, text=True, timeout=10
    )
    return result.stdout or "No matches"

Verification

python -c "
import os
allowed = [os.path.abspath('/tmp')]
path = os.path.abspath('/tmp/../etc/passwd')
print(any(path.startswith(a) for a in allowed))
# Expected: False (path traversal detected)
"

Common failures

  • Symlink attacks. A file within an allowed directory could be a symlink to a forbidden file. Resolve symlinks with os.path.realpath().
  • Race conditions (TOCTOU). A file passes validation but is replaced before being read. Open and validate using the file descriptor, not the path.
  • Logging sensitive content. Audit logs may contain file contents with PII. Log only metadata (path, size, timestamp), not content.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Add File System Operations as Agent Tools
  • How to Build Custom Tools for Agents
← All how-to guidesCourses →