# Security-Focused Architecture: CWD-Only Operations
## Overview
This document describes the security-focused architecture that completely removes `repo_path` parameters and environment variables from the Commit Helper MCP. All operations are restricted to the current working directory (CWD) only.
## Motivation
The original design allowed operations on arbitrary filesystem locations through:
1. Explicit `repo_path` parameters in MCP tools
2. `COMMITIZEN_REPO_PATH` environment variable
3. Fallback to current working directory
This flexibility creates potential security risks by allowing services to operate on any folder in the filesystem that the process has access to.
## Security-Focused Design
### Core Principles
1. **No Repository Parameters**: Remove all `repo_path` parameters from tool definitions
2. **No Environment Variables**: Eliminate `COMMITIZEN_REPO_PATH` and similar variables
3. **CWD-Only Operations**: All operations restricted to `os.getcwd()`
4. **Simplified Architecture**: Remove complex path resolution logic
### Architecture Changes
```mermaid
graph TD
A[MCP Tool Called] --> B[Get CWD]
B --> C[Validate CWD]
C --> D{Valid?}
D -->|Yes| E[Execute Operation]
D -->|No| F[Return Error Response]
```
### Simplified Repository Manager
```python
class SecureRepositoryManager:
"""Repository manager that only works with CWD."""
def get_repository_path(self) -> str:
"""Get the current working directory."""
return os.getcwd()
def validate_repository(self) -> Tuple[bool, Optional[str]]:
"""Validate that CWD is a valid repository."""
cwd = os.getcwd()
# Basic validation
if not os.path.exists(cwd):
return False, "Current working directory does not exist"
if not os.path.isdir(cwd):
return False, "Current working directory is not a directory"
if not os.access(cwd, os.R_OK):
return False, "No read access to current working directory"
return True, None
def validate_git_repository(self) -> Tuple[bool, Optional[str]]:
"""Validate that CWD is a git repository."""
is_valid, error = self.validate_repository()
if not is_valid:
return False, error
git_dir = os.path.join(os.getcwd(), ".git")
if not os.path.exists(git_dir):
return False, "Current directory is not a git repository"
return True, None
```
### Tool Definition Updates
```python
# Before: Tool with repo_path parameter
@mcp.tool()
def get_git_status(repo_path: str) -> Dict[str, Any]:
"""Get git status for specified repository."""
service = CommitzenService(repo_path=repo_path)
return service.get_repository_status()
# After: Tool without repo_path parameter
@mcp.tool()
def get_git_status() -> Dict[str, Any]:
"""Get git status for current working directory."""
# Validate CWD
manager = SecureRepositoryManager()
is_valid, error = manager.validate_git_repository()
if not is_valid:
return create_error_response(
RepositoryError(f"Invalid repository: {error}")
)
# Always use CWD
service = CommitzenService(repo_path=os.getcwd())
return service.get_repository_status()
```
### Service Layer Updates
```python
# Before: Service accepts repo_path
class CommitzenService:
def __init__(self, repo_path: str):
self.repo_path = repo_path
self._validate_path()
# After: Service only uses CWD
class CommitzenService:
def __init__(self):
self.repo_path = os.getcwd()
# No path validation needed - always CWD
```
## Benefits
### 1. Enhanced Security
- **No Path Traversal**: Cannot access directories outside CWD
- **No Arbitrary Access**: Services confined to where they're running
- **Reduced Attack Surface**: Eliminates path-based vulnerabilities
### 2. Simplified Codebase
- **No Path Resolution**: Remove complex priority logic
- **No Parameter Validation**: No need to validate path parameters
- **Cleaner Interfaces**: Tool definitions are simpler
### 3. Clearer User Experience
- **No Confusion**: Always operates on current directory
- **Predictable Behavior**: No hidden path resolution
- **Explicit Operations**: Users must `cd` to target directory
### 4. Easier Testing
- **No Path Mocking**: Tests always use CWD
- **Simpler Fixtures**: No need for path parameter variations
- **Focused Tests**: Test business logic, not path handling
## Implementation Impact
### Breaking Changes
1. All tools lose `repo_path` parameter
2. Environment variables no longer work
3. Multi-repository workflows require directory changes
### Migration Path
```python
# Old usage
result = commit_helper.get_git_status(repo_path="/some/path")
# New usage - must change directory first
os.chdir("/some/path")
result = commit_helper.get_git_status()
```
### Error Messages
```python
# Clear, security-focused error messages
{
"success": false,
"error": "Operations are restricted to current working directory",
"details": {
"current_directory": "/current/path",
"is_git_repository": false
},
"suggestions": [
"Change to a git repository directory",
"Run 'git init' to initialize repository in current directory"
]
}
```
## Comparison with Context Provider Design
| Aspect | Context Provider | Security-Focused |
|--------|-----------------|------------------|
| Path Parameters | Optional | Removed |
| Environment Variables | Supported | Removed |
| Path Resolution | Complex priority | None (CWD only) |
| Multi-Repository | Easy switching | Requires `cd` |
| Security | Flexible but risky | Highly restricted |
| Complexity | Moderate | Simple |
## Testing Strategy
### Unit Tests
```python
def test_cwd_only_operation():
"""Test that operations only work on CWD."""
with temporary_directory() as temp_dir:
os.chdir(temp_dir)
# Initialize git
subprocess.run(["git", "init"], check=True)
# Operation should work
result = get_git_status()
assert result["success"] is True
assert result["repository_path"] == temp_dir
```
### Security Tests
```python
def test_cannot_access_other_directories():
"""Test that operations cannot access other directories."""
with temporary_directory() as temp_dir:
other_dir = os.path.join(temp_dir, "other")
os.makedirs(other_dir)
# Even if we try to pass a path, it should be ignored
# (In the new design, there's no parameter to pass)
result = get_git_status()
# Should only operate on CWD
assert result["repository_path"] == os.getcwd()
```
## User Workflows
### Single Repository
```bash
cd /path/to/repo
# All operations now work on this repository
commit_helper generate_commit_message
```
### Multiple Repositories
```bash
# Repository 1
cd /path/to/repo1
commit_helper get_git_status
# Repository 2
cd /path/to/repo2
commit_helper get_git_status
```
### Scripting
```bash
#!/bin/bash
# Script to check multiple repositories
for repo in repo1 repo2 repo3; do
cd "/path/to/$repo"
commit_helper analyze_repository_health
done
```
## Conclusion
The security-focused architecture trades flexibility for security and simplicity. By restricting all operations to the current working directory, we eliminate entire classes of security vulnerabilities while making the codebase simpler and more maintainable.