Migration from Docker to Standalone Python Server (#73)
* Migration from docker to standalone server Migration handling Fixed tests Use simpler in-memory storage Support for concurrent logging to disk Simplified direct connections to localhost * Migration from docker / redis to standalone script Updated tests Updated run script Fixed requirements Use dotenv Ask if user would like to install MCP in Claude Desktop once Updated docs * More cleanup and references to docker removed * Cleanup * Comments * Fixed tests * Fix GitHub Actions workflow for standalone Python architecture - Install requirements-dev.txt for pytest and testing dependencies - Remove Docker setup from simulation tests (now standalone) - Simplify linting job to use requirements-dev.txt - Update simulation tests to run directly without Docker Fixes unit test failures in CI due to missing pytest dependency. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove simulation tests from GitHub Actions - Removed simulation-tests job that makes real API calls - Keep only unit tests (mocked, no API costs) and linting - Simulation tests should be run manually with real API keys - Reduces CI costs and complexity GitHub Actions now only runs: - Unit tests (569 tests, all mocked) - Code quality checks (ruff, black) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Fixed tests * Fixed tests --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
9d72545ecd
commit
4151c3c3a5
@@ -2,15 +2,14 @@
|
||||
Security configuration and path validation constants
|
||||
|
||||
This module contains security-related constants and configurations
|
||||
for file access control and workspace management.
|
||||
for file access control.
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Dangerous paths that should never be used as WORKSPACE_ROOT
|
||||
# Dangerous paths that should never be scanned
|
||||
# These would give overly broad access and pose security risks
|
||||
DANGEROUS_WORKSPACE_PATHS = {
|
||||
DANGEROUS_PATHS = {
|
||||
"/",
|
||||
"/etc",
|
||||
"/usr",
|
||||
@@ -18,7 +17,6 @@ DANGEROUS_WORKSPACE_PATHS = {
|
||||
"/var",
|
||||
"/root",
|
||||
"/home",
|
||||
"/workspace", # Container path - WORKSPACE_ROOT should be host path
|
||||
"C:\\",
|
||||
"C:\\Windows",
|
||||
"C:\\Program Files",
|
||||
@@ -88,87 +86,19 @@ EXCLUDED_DIRS = {
|
||||
"vendor",
|
||||
}
|
||||
|
||||
# MCP signature files - presence of these indicates the MCP's own directory
|
||||
# Used to prevent the MCP from scanning its own codebase
|
||||
MCP_SIGNATURE_FILES = {
|
||||
"zen_server.py",
|
||||
"server.py",
|
||||
"tools/precommit.py",
|
||||
"utils/file_utils.py",
|
||||
"prompts/tool_prompts.py",
|
||||
}
|
||||
|
||||
# Workspace configuration
|
||||
WORKSPACE_ROOT = os.environ.get("WORKSPACE_ROOT")
|
||||
CONTAINER_WORKSPACE = Path("/workspace")
|
||||
|
||||
|
||||
def validate_workspace_security(workspace_root: str) -> None:
|
||||
def is_dangerous_path(path: Path) -> bool:
|
||||
"""
|
||||
Validate that WORKSPACE_ROOT is set to a safe directory.
|
||||
Check if a path is in the dangerous paths list.
|
||||
|
||||
Args:
|
||||
workspace_root: The workspace root path to validate
|
||||
|
||||
Raises:
|
||||
RuntimeError: If the workspace root is unsafe
|
||||
"""
|
||||
if not workspace_root:
|
||||
return
|
||||
|
||||
# Resolve to canonical path for comparison
|
||||
resolved_workspace = Path(workspace_root).resolve()
|
||||
|
||||
# Special check for /workspace - common configuration mistake
|
||||
if str(resolved_workspace) == "/workspace":
|
||||
raise RuntimeError(
|
||||
f"Configuration Error: WORKSPACE_ROOT should be set to the HOST path, not the container path. "
|
||||
f"Found: WORKSPACE_ROOT={workspace_root} "
|
||||
f"Expected: WORKSPACE_ROOT should be set to your host directory path (e.g., $HOME) "
|
||||
f"that contains all files Claude might reference. "
|
||||
f"This path gets mounted to /workspace inside the Docker container."
|
||||
)
|
||||
|
||||
# Check against other dangerous paths
|
||||
if str(resolved_workspace) in DANGEROUS_WORKSPACE_PATHS:
|
||||
raise RuntimeError(
|
||||
f"Security Error: WORKSPACE_ROOT '{workspace_root}' is set to a dangerous system directory. "
|
||||
f"This would give access to critical system files. "
|
||||
f"Please set WORKSPACE_ROOT to a specific project directory."
|
||||
)
|
||||
|
||||
# Additional check: prevent filesystem root
|
||||
if resolved_workspace.parent == resolved_workspace:
|
||||
raise RuntimeError(
|
||||
f"Security Error: WORKSPACE_ROOT '{workspace_root}' cannot be the filesystem root. "
|
||||
f"This would give access to the entire filesystem. "
|
||||
f"Please set WORKSPACE_ROOT to a specific project directory."
|
||||
)
|
||||
|
||||
|
||||
def get_security_root() -> Path:
|
||||
"""
|
||||
Determine the security boundary for file access.
|
||||
path: Path to check
|
||||
|
||||
Returns:
|
||||
Path object representing the security root directory
|
||||
True if the path is dangerous and should not be accessed
|
||||
"""
|
||||
# In Docker: use /workspace (container directory)
|
||||
# In tests/direct mode: use WORKSPACE_ROOT (host directory)
|
||||
if CONTAINER_WORKSPACE.exists():
|
||||
# Running in Docker container
|
||||
return CONTAINER_WORKSPACE
|
||||
elif WORKSPACE_ROOT:
|
||||
# Running in tests or direct mode with WORKSPACE_ROOT set
|
||||
return Path(WORKSPACE_ROOT).resolve()
|
||||
else:
|
||||
# Fallback for backward compatibility (should not happen in normal usage)
|
||||
return Path.home()
|
||||
|
||||
|
||||
# Validate security on import if WORKSPACE_ROOT is set
|
||||
if WORKSPACE_ROOT:
|
||||
validate_workspace_security(WORKSPACE_ROOT)
|
||||
|
||||
# Export the computed security root
|
||||
SECURITY_ROOT = get_security_root()
|
||||
try:
|
||||
resolved = path.resolve()
|
||||
return str(resolved) in DANGEROUS_PATHS or resolved.parent == resolved
|
||||
except Exception:
|
||||
return True # If we can't resolve, consider it dangerous
|
||||
|
||||
Reference in New Issue
Block a user