-
-
Notifications
You must be signed in to change notification settings - Fork 2
Security Best Practices
Gordon T Watts edited this page Jan 26, 2026
·
2 revisions
Secure development with MAINFRAME for AI agents.
- Security Philosophy
- Core Principles
- Input Validation
- Safe Command Execution
- Path Safety
- Secret Management
- Audit Logging
- Error Handling
- AI Agent Security
- Security Checklist
- Reporting Vulnerabilities
MAINFRAME is built with security as a core principle, not an afterthought. This is essential because:
- AI agents control systems - A compromised agent can cause significant damage
- Bash is powerful - Power requires responsibility
- Mistakes happen - Good defaults prevent accidents
- Defense in depth - Multiple layers of protection
| Principle | Implementation |
|---|---|
| No Eval by Default | Commands executed via array, not string interpolation |
| Validate Before Execute | All inputs validated before use |
| Fail Safely | Operations fail closed, not open |
| Audit Everything | All sensitive operations logged |
| Least Privilege | Minimal permissions required |
| Defense in Depth | Multiple validation layers |
source "$MAINFRAME_ROOT/lib/validation.sh"
# Integer validation
validate_int "$port" 1 65535 || die 1 "Invalid port"
# Float validation
validate_float "$rate" || die 1 "Invalid rate"
# Boolean validation
validate_bool "$enabled" || die 1 "Invalid boolean"# Email
validate_email "$email" || die 1 "Invalid email"
# URL
validate_url "$url" || die 1 "Invalid URL"
# IP address
validate_ipv4 "$ip" || die 1 "Invalid IP"
# Date
validate_date "$date" || die 1 "Invalid date (YYYY-MM-DD)"
# Semantic version
validate_semver "$version" || die 1 "Invalid version"# GOOD: Validate before use
read -p "Enter port: " user_port
validate_int "$user_port" 1 65535 || {
output_error "E_INVALID_INPUT" "Invalid port number"
exit 1
}
start_server "$user_port"
# BAD: Direct use
read -p "Enter port: " user_port
start_server "$user_port" # Could be anythingsource "$MAINFRAME_ROOT/lib/agent_safety.sh"
# GOOD: Safe execution
agent_safe_exec "ls" "-la" "$directory"
# BAD: String interpolation
eval "ls -la $directory" # Injection risk# User provides: "file.txt; rm -rf /"
user_input="file.txt; rm -rf /"
# DANGEROUS
eval "cat $user_input"
# Executes: cat file.txt; rm -rf /
# SAFE
agent_safe_exec "cat" "$user_input"
# Tries to cat literal "file.txt; rm -rf /"
# File not found, no injection# Only allow specific commands
export AGENT_ALLOWED_COMMANDS="ls cat grep git npm"
export AGENT_STRICT_MODE=1
agent_safe_exec "ls" "-la" # OK
agent_safe_exec "rm" "-rf" # BLOCKEDThese patterns are blocked by default:
| Pattern | Risk |
|---|---|
rm -rf / |
System destruction |
dd if= |
Disk overwrite |
mkfs |
Filesystem format |
chmod 777 |
Insecure permissions |
curl | bash |
Remote code execution |
> /dev/sd* |
Disk overwrite |
Prevent directory traversal attacks.
# User tries: "../../../etc/passwd"
user_path="../../../etc/passwd"
# GOOD: Validate first
if validate_path_safe "$user_path" "/allowed/base"; then
cat "$user_path"
else
output_error "E_PATH_TRAVERSAL" "Invalid path"
fi
# Blocks the traversal attempt
# BAD: Direct use
cat "/allowed/base/$user_path"
# Could read /etc/passwd# GOOD: Use path_join with validation
safe_path=$(path_join "/base" "$user_subpath")
validate_path_safe "$safe_path" "/base" && cat "$safe_path"
# BAD: String concatenation
cat "/base/$user_subpath" # Traversal possible# For user-provided filenames
validate_filename "$filename" || {
output_error "E_INVALID_FILENAME" "Invalid filename"
exit 1
}
# Removes path components
sanitize_filename "../../../passwd" # Returns "passwd"# BAD: Hardcoded secret
API_KEY="sk-1234567890"
# GOOD: Environment variable
API_KEY="${API_KEY:?API_KEY not set}"
# GOOD: File with restricted permissions
API_KEY=$(cat /etc/secrets/api_key)# Require secrets at startup
env_require "DATABASE_URL" "Database URL must be set"
env_require "API_KEY" "API key must be set"# BAD: Logs secret
log_info "Connecting with key: $API_KEY"
# GOOD: Mask secret
log_info "Connecting with key: ${API_KEY:0:4}****"# Secrets file should be 600
chmod 600 /etc/secrets/api_key
# Validate permissions
[[ $(stat -c %a /etc/secrets/api_key) == "600" ]] || \
die 1 "Insecure permissions on secrets file"export AGENT_AUDIT_LOG="/var/log/agent_audit.log"- All
agent_safe_execcalls - All
ensure_*operations - All file modifications
- All authentication attempts
[2024-01-15T10:30:00] [worker-1] EXEC ls -la /tmp -> 0
[2024-01-15T10:30:01] [worker-1] ENSURE_FILE /config.json -> updated
[2024-01-15T10:30:02] [worker-1] VALIDATE_PATH /etc/passwd -> BLOCKED
# Rotate at 10MB
agent_audit_rotate 10485760# Append-only log file
chattr +a /var/log/agent_audit.log# BAD: Leaks credentials
output_error "E_AUTH_FAILED" "Failed to connect with password: $DB_PASS"
# GOOD: Generic error
output_error "E_AUTH_FAILED" "Database authentication failed" "Check credentials"# GOOD: Deny by default
if validate_user "$user"; then
grant_access
else
deny_access # Explicit deny
fi
# BAD: Allow by default
if ! validate_user "$user"; then
deny_access
fi
# Implicit allow if validation skipped# Provides context without leaking
output_error "E_PERMISSION" "Access denied" "Check user permissions"
# {"ok":false,"error":{"code":"E_PERMISSION","msg":"Access denied","suggestion":"Check user permissions"}}# Run agent with limited permissions
AGENT_ALLOWED_COMMANDS="ls cat grep"
AGENT_STRICT_MODE=1# Limit operations per minute
export AGENT_RATE_LIMIT=60# Check resources before operations
guard_disk_space "/var" 1024 || die 1 "Insufficient disk space"
guard_memory 512 || die 1 "Insufficient memory"# Validate URLs before fetching
validate_url "$url" || die 1 "Invalid URL"
# Consider allowlisting domainsFor high-security environments:
- Run agents in containers
- Use seccomp/AppArmor profiles
- Limit network access
- Mount filesystems read-only where possible
- All user inputs validated
- Paths validated with
validate_path_safe - Commands use
agent_safe_exec, noteval - Secrets in environment variables, not code
- Secret files have 600 permissions
- Audit logging enabled
- Error messages don't leak sensitive data
- Agent commands whitelisted
- Rate limiting configured
- Resource guards in place
- No
evalusage (or justified exception) - No hardcoded credentials
- All external input sanitized
- Path operations validated
- Error handling doesn't leak info
- Logging doesn't include secrets
Found a security issue?
- DO NOT open a public issue
- Use GitHub Security Advisories
- Or email the repository owner
| Severity | Response | Fix |
|---|---|---|
| Critical | 24 hours | 24-72 hours |
| High | 48 hours | 7 days |
| Medium | 7 days | 14 days |
| Low | 14 days | Next release |
See SECURITY.md for full policy.
MAINFRAME · The AI-Native Bash Runtime
MAINFRAME · The AI-Native Bash Runtime
2,000+ Functions · Zero Dependencies · Safe by Default
GitHub · Discussions · Issues
"Knowing Your Shell is half the battle."