Security Model
Design Philosophy
Section titled “Design Philosophy”Provara’s security policy follows a simple principle: deny by default, allow by category.
Command → DENY check (first) → ALLOW check → CWD check → Execute ↓ match = blocked ↓ no match = blockedEvery command must:
- Not match any deny pattern
- Match at least one allow pattern
- Execute from an approved working directory
Deny Patterns
Section titled “Deny Patterns”Deny patterns are checked first. If any pattern matches (via re.search()), the command is immediately blocked — regardless of allow patterns.
There are 26 deny rules organized into 7 categories:
System Modification (NEVER allow)
Section titled “System Modification (NEVER allow)”r"(?i)\b(schtasks|bcdedit|diskpart|cipher|takeown|icacls)\b"r"(?i)\b(net\s+user|net\s+localgroup|sc\.exe|wmic)\b"r"(?i)\breg\s+(add|delete|import|export|save|restore)\b"Blocks: Task scheduling, boot configuration, disk management, file encryption, ownership changes, ACL modification, user management, service control, WMI, and registry modification.
Security Bypass (NEVER allow)
Section titled “Security Bypass (NEVER allow)”r"(?i)\b(Add-MpPreference|Set-MpPreference|Remove-MpPreference)\b"r"(?i)\b(Disable-WindowsOptionalFeature|Enable-WindowsOptionalFeature)\b"r"(?i)(powershell|pwsh)(\.exe)?\s+.*-[eE]nc"r"(?i)\b(frombase64string|iex|Invoke-Expression)\b"r"(?i)\bStart-Process\b"Blocks: Defender manipulation, Windows feature toggling, encoded commands, base64 execution, Invoke-Expression, and Start-Process.
Remote Operations (NEVER allow)
Section titled “Remote Operations (NEVER allow)”r"(?i)\b(Invoke-WebRequest|curl\s|wget\s|bitsadmin|Start-BitsTransfer)\b"r"(?i)\bInvoke-RestMethod\s+https?://(?!127\.0\.0\.1|localhost)"r"(?i)\bInvoke-Command\s+-Computer"r"(?i)\bEnter-PSSession\b"Blocks: Web downloads, remote API calls (except localhost), remote command execution, and remote PowerShell sessions.
Credential Access (NEVER allow)
Section titled “Credential Access (NEVER allow)”r"(?i)\b(Get-Credential|ConvertTo-SecureString|ConvertFrom-SecureString)\b"r"(?i)\b(Get-ItemProperty|Set-ItemProperty)\s+(HKLM:|HKCU:|Registry::)"Blocks: Credential prompts, secure string operations, and registry access via *-ItemProperty.
Destructive Operations (outside workspace)
Section titled “Destructive Operations (outside workspace)”r"(?i)\b(Remove-Item|del\s|erase\s|rmdir)\b(?!.*[/\\]workspace[/\\])"r"(?i)\bClear-Content\b(?!.*[/\\]workspace[/\\])"Blocks: File/directory deletion and content clearing outside the workspace/ directory. Deletions within workspace are permitted.
Output Redirection (outside project)
Section titled “Output Redirection (outside project)”r"(?i)\bOut-File\b(?!.*[/\\]agent-hub[/\\])"r"(?i)\bExport-\w+\b(?!.*[/\\]agent-hub[/\\])"Blocks: Writing files and exporting data outside the project directory.
Environment Modification
Section titled “Environment Modification”r"(?i)\$env:\w+\s*="r"(?i)\bSet-Variable\s+-Name\s+env:"Blocks: All environment variable modifications.
Allow Patterns
Section titled “Allow Patterns”After passing deny checks, a command must match at least one allow pattern (via re.fullmatch() with IGNORECASE).
Allow patterns are organized into 9 categories:
Category 1: Simple Info Commands
Section titled “Category 1: Simple Info Commands”r"^(whoami|hostname|pwd|systeminfo)$"r"^(Get-Date|\$PSVersionTable|\[Environment\]::OSVersion)$"r"^git\s+--version$"Category 2: Echo/Output
Section titled “Category 2: Echo/Output”r"^echo\s+.+$"r"^Write-Output\s+.+$"Category 3: Read-Only File/Directory
Section titled “Category 3: Read-Only File/Directory”r"^(dir|ls|Get-ChildItem)(\s+.*)?$"r"^(type|cat|Get-Content)\s+.+$"r"^(Test-Path|Resolve-Path|Get-Item)\s+.+$"Category 4: System Inspection
Section titled “Category 4: System Inspection”r"^Get-Process(\s+.*)?$"r"^tasklist(\s+.*)?$"r"^Get-Service(\s+.*)?$"Category 5: Network Diagnostics (localhost only)
Section titled “Category 5: Network Diagnostics (localhost only)”r"^Test-NetConnection\s+(127\.0\.0\.1|localhost)\s+-Port\s+\d+$"r"^ping\s+(127\.0\.0\.1|localhost)(\s+.+)?$"Category 6: Workspace Scripts
Section titled “Category 6: Workspace Scripts”r"^.*python(\.exe)?\s+.*[/\\]workspace[/\\](inbox|outbox)[/\\].+\.py(\s+.*)?$"r"^powershell(\.exe)?\s+.*-File\s+.*[/\\]workspace[/\\](inbox|outbox)[/\\].+\.ps1(\s+.*)?$"Only scripts in workspace/inbox/ or workspace/outbox/ can be executed.
Category 7: Workspace File Operations
Section titled “Category 7: Workspace File Operations”r"^New-Item\s+.*[/\\]workspace[/\\].+$"r"^(Set-Content|Add-Content)\s+.*[/\\]workspace[/\\].+$"r"^Remove-Item\s+.*[/\\]workspace[/\\].+$"File creation, modification, and deletion — but only within workspace/.
Category 8: Git (read-only)
Section titled “Category 8: Git (read-only)”r"^git\s+(status|log|diff|branch|remote|show|rev-parse|config\s+--get)(\s+.*)?$"Only read-only git operations. No push, commit, checkout, or reset.
Category 9: Localhost API Calls
Section titled “Category 9: Localhost API Calls”r"^Invoke-RestMethod\s+https?://(127\.0\.0\.1|localhost)(:\d+)?/\w+.*$"Allows REST calls to local services only.
Working Directory Jail
Section titled “Working Directory Jail”Even after passing deny and allow checks, the command’s working directory must be under the project root:
def is_path_under_project(path: str) -> bool: resolved = Path(path).resolve() project = _PROJECT_ROOT.resolve() return str(resolved).lower().startswith(str(project).lower())This prevents path traversal attacks where a command might operate on system directories.
Runtime Pattern Extension
Section titled “Runtime Pattern Extension”For testing and debugging, patterns can be added at runtime:
from src.server.exec.policy import add_allow_pattern, add_deny_pattern
# Add a temporary allow patternadd_allow_pattern(r"^my-custom-command\s+.+$")
# Add a temporary deny pattern (inserted at position 0)add_deny_pattern(r"(?i)\bmy-dangerous-cmd\b")Pattern Validation
Section titled “Pattern Validation”All patterns are validated at import time:
def _validate_patterns(): for name, patterns in [("ALLOW", ALLOW), ("DENY", DENY)]: for p in patterns: try: re.compile(p) except re.error as e: raise ValueError(f"Invalid {name} pattern: {p} - {e}")If any pattern has invalid regex syntax, the server will fail to start with a clear error message.
Next Steps
Section titled “Next Steps”- API Reference — Complete endpoint documentation
- Troubleshooting — Common policy issues