Platform Bridge - Security Documentation¶
Security analysis and best practices fer the platform bridge module.
Security Model¶
The platform bridge follows a delegation security model where authentication and authorization be handled by official CLI tools (gh and az), not by the bridge itself.
Core Principles¶
- No Credential Storage: Bridge never stores or handles credentials
- CLI Authentication: Delegates all authentication to gh/az CLI tools
- Input Validation: All user inputs be validated before subprocess calls
- Safe Subprocess: Parameterized commands prevent shell injection
- Fail Secure: Errors don't leak sensitive information
Authentication Delegation¶
GitHub Authentication¶
The bridge uses gh CLI fer all GitHub operations:
# Bridge NEVER handles GitHub tokens directly
bridge = PlatformBridge() # No tokens or credentials passed
# Authentication handled by gh CLI
issue = bridge.create_issue(title="Test", body="Body")
# Under the hood: gh uses credentials from ~/.config/gh/hosts.yml
User Authentication Flow: 1. User runs: gh auth login 2. GitHub CLI authenticates through OAuth 3. Credentials stored in ~/.config/gh/hosts.yml 4. Bridge calls gh commands which use stored credentials
Benefits: - Bridge code never sees tokens - GitHub handles token refresh - Standard gh security model applies
Azure DevOps Authentication¶
The bridge uses az CLI fer all Azure DevOps operations:
# Bridge NEVER handles Azure DevOps PATs directly
bridge = PlatformBridge() # No tokens or credentials passed
# Authentication handled by az CLI
issue = bridge.create_issue(title="Test", body="Body")
# Under the hood: az uses credentials from ~/.azure/
User Authentication Flow: 1. User runs: az login 2. Azure CLI authenticates through browser 3. Credentials stored in ~/.azure/ 4. Bridge calls az commands which use stored credentials
Benefits: - Bridge code never sees tokens or PATs - Azure handles token refresh - Standard az security model applies
Input Validation¶
All user inputs be validated before bein' passed to subprocess calls.
Title Validation¶
def _validate_title(title: str) -> None:
"""Validate issue/PR title"""
if not title or not title.strip():
raise ValueError("Title cannot be empty")
if len(title) > 256:
raise ValueError("Title too long (max 256 characters)")
# No shell metacharacters in title
dangerous_chars = ['$', '`', '$(', '|', '&', ';']
if any(char in title for char in dangerous_chars):
raise ValueError(f"Title contains invalid characters: {dangerous_chars}")
Branch Name Validation¶
def _validate_branch_name(branch: str) -> None:
"""Validate git branch name"""
if not branch or not branch.strip():
raise ValueError("Branch name cannot be empty")
# Git branch name rules
invalid_patterns = ['..', '~', '^', ':', '\\', '*', '?', '[']
if any(pattern in branch for pattern in invalid_patterns):
raise ValueError(f"Branch name contains invalid patterns")
if branch.startswith('/') or branch.endswith('/'):
raise ValueError("Branch name cannot start or end with /")
Body/Description Validation¶
def _validate_body(body: str) -> None:
"""Validate issue/PR body"""
if not body or not body.strip():
raise ValueError("Body cannot be empty")
# No null bytes (can confuse subprocess)
if '\x00' in body:
raise ValueError("Body contains null bytes")
# Reasonable size limit (prevent DoS)
if len(body) > 65536: # 64KB
raise ValueError("Body too large (max 64KB)")
Safe Subprocess Usage¶
All subprocess calls use parameterized commands to prevent shell injection.
Correct Pattern (Safe)¶
# SAFE - Command and args as list
subprocess.run(
["gh", "issue", "create", "--title", title, "--body", body],
capture_output=True,
text=True,
timeout=30
)
Why this be safe: - Command and arguments passed as list - No shell interpretation - Arguments can't be interpreted as commands - Even if title/body contain ; rm -rf /, they be treated as literal strings
Anti-Pattern (Unsafe)¶
# UNSAFE - Don't do this!
subprocess.run(
f"gh issue create --title '{title}' --body '{body}'",
shell=True, # ❌ Dangerous!
capture_output=True
)
Why this be dangerous: - Shell interprets the entire string - Special characters in title/body can execute commands - Example attack: title = "test'; rm -rf /; echo '"
Timeout Protection¶
All subprocess calls have timeouts to prevent hangs:
Timeout Values: - Standard operations: 30 seconds - CI status checks: 60 seconds (can be slow) - Large file uploads: 120 seconds
Error Handling¶
Errors be handled to prevent information leakage:
Safe Error Messages¶
try:
result = subprocess.run(cmd, ...)
if result.returncode != 0:
# Don't expose full command in error
raise RuntimeError(f"Operation failed: {sanitize_error(result.stderr)}")
except subprocess.TimeoutExpired:
# Don't expose what command timed out
raise RuntimeError("Operation timed out after 30 seconds")
except Exception as e:
# Don't expose internal details
raise RuntimeError(f"Unexpected error: {type(e).__name__}")
Information Leakage Prevention¶
What we DON'T expose: - Full subprocess commands (might contain sensitive args) - File system paths (might reveal directory structure) - Internal stack traces (might reveal implementation details)
What we DO expose: - Operation type (e.g., "create issue failed") - User-actionable guidance (e.g., "run gh auth login") - Error categories (e.g., "authentication required")
Filesystem Security¶
The bridge reads git configuration but never writes to filesystem (except through CLI tools).
Read-Only Operations¶
# Bridge only reads git config
def _get_git_remote(repo_path: Path) -> str:
"""Read git remote URL (read-only)"""
result = subprocess.run(
["git", "remote", "-v"],
cwd=repo_path,
capture_output=True,
text=True
)
return result.stdout
No Filesystem Writes¶
The bridge never writes to: - Git configuration (.git/config) - Credential files (~/.config/gh/, ~/.azure/) - System directories - Temporary files with sensitive data
All writes be handled by official CLI tools which have their own security models.
Threat Model¶
Threats We Mitigate¶
- Shell Injection: Parameterized commands prevent command injection
- Credential Theft: No credentials stored or handled by bridge
- Information Leakage: Error messages don't expose sensitive details
- DoS via Large Inputs: Size limits on all inputs
- Path Traversal: Repository paths validated
Threats Out of Scope¶
These be handled by CLI tools or operating system:
- Network Security: gh/az CLI handle HTTPS connections
- Token Refresh: CLI tools manage token lifecycle
- Multi-Factor Auth: Handled by GitHub/Azure DevOps
- Rate Limiting: CLI tools handle API rate limits
- Audit Logging: Platform services log all operations
Trust Boundaries¶
User Code → PlatformBridge → gh/az CLI → GitHub/Azure DevOps API
↑ ↑ ↑ ↑
| | | |
| | | +-- Trusted (official API)
| | +----------------- Trusted (official CLI)
| +---------------------------------- Trusted (our code)
+----------------------------------------------- Untrusted (user input)
Trust Assumptions: - User input be UNTRUSTED (validate everything) - gh/az CLI tools be TRUSTED (official tools) - Platform APIs be TRUSTED (GitHub/Azure) - Operating system be TRUSTED (subprocess isolation)
Security Best Practices¶
For Users¶
-
Keep CLI Tools Updated:
-
Use Secure Authentication:
-
Review Permissions:
-
Rotate Credentials Regularly:
For Developers¶
-
Never Add Credential Parameters:
-
Always Validate Inputs:
-
Use Parameterized Commands:
-
Set Timeouts:
Security Audit Checklist¶
When reviewin' platform bridge code:
- No credential storage or handling
- All subprocess calls use list (not string with shell=True)
- All user inputs validated before subprocess
- Timeouts set on all subprocess calls
- Error messages don't leak sensitive info
- No filesystem writes except through CLI tools
- Branch names validated against git rules
- Size limits enforced on all inputs
- No null bytes in string inputs
- Exception handling prevents info leakage
Reporting Security Issues¶
If ye discover a security vulnerability in the platform bridge:
- Don't open a public GitHub issue
- Do email security@amplihack.dev with details
- Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if ye have one)
We'll respond within 48 hours and coordinate a fix.
See Also¶
- Platform Bridge Overview - Feature documentation
- API Reference - Complete API
- GitHub CLI Security - gh authentication
- Azure CLI Security - az authentication