06 Configuration - samerfarida/mcp-ssh-orchestrator GitHub Wiki

6. Configuration

Purpose: Overview of the configuration system and how the three main configuration files work together to define hosts, credentials, and security policies.

Configuration Overview

mcp-ssh-orchestrator uses a three-file configuration system that separates concerns and enables secure, flexible deployment:

Configuration Architecture

graph TB
    subgraph "Configuration Files"
        SERVERS[servers.yml<br/>Host Inventory]
        CREDS[credentials.yml<br/>SSH Authentication]
        POLICY[policy.yml<br/>Security Policies]
    end
    
    subgraph "Configuration Loader"
        CONFIG_LOADER[config.py]
    end
    
    subgraph "Policy Engine"
        POLICY_ENGINE[policy.py]
    end
    
    subgraph "SSH Client"
        SSH_CLIENT[ssh_client.py]
    end
    
    SERVERS --> CONFIG_LOADER
    CREDS --> CONFIG_LOADER
    POLICY --> CONFIG_LOADER
    
    CONFIG_LOADER --> POLICY_ENGINE
    CONFIG_LOADER --> SSH_CLIENT
    
    POLICY_ENGINE --> POLICY
Loading

Directory Structure

mcp-ssh-orchestrator/
├── config/
│   ├── servers.yml       # Host inventory
│   ├── credentials.yml   # SSH credentials
│   └── policy.yml        # Security policies
├── keys/                 # SSH private keys (chmod 0400)
└── secrets/              # Docker secrets (passwords, passphrases)

Configuration Loading Process

1. File Discovery

The configuration loader searches for files in this order:

  1. Command-line arguments (if specified)
  2. Environment variables (MCP_SSH_CONFIG_DIR)
  3. Default paths (/app/config/ in container, ./config/ locally)

2. File Validation

Each configuration file is validated for:

  • YAML syntax correctness
  • Required fields presence
  • Data type validation
  • Cross-file references validity

3. Configuration Merging

The system merges configurations with this precedence:

  1. servers.yml - Host definitions and network settings
  2. credentials.yml - Authentication methods and secrets
  3. policy.yml - Security policies and access controls

Configuration Relationships

servers.yml ↔ credentials.yml

Relationship: Hosts reference credential entries by name.

# servers.yml
hosts:
  - alias: "web1"
    host: "10.0.0.11"
    credentials: "prod_admin"  # References credentials.yml

# credentials.yml  
entries:
  - name: "prod_admin"        # Referenced by servers.yml
    username: "ubuntu"
    key_path: "id_ed25519"

servers.yml ↔ policy.yml

Relationship: Policy rules can target hosts by alias or tags.

# servers.yml
hosts:
  - alias: "prod-web-1"
    tags: ["production", "web"]  # Used by policy rules

# policy.yml
rules:
  - action: "allow"
    aliases: ["prod-*"]        # Matches prod-web-1
    tags: ["production"]       # Matches production tag
    commands: ["uptime*"]

credentials.yml ↔ policy.yml

Relationship: Policy can enforce credential requirements.

# credentials.yml
entries:
  - name: "prod_admin"
    username: "ubuntu"
    key_path: "id_ed25519"

# policy.yml
limits:
  require_known_host: true     # Enforces host key verification

Configuration Validation

Syntax Validation

# Validate YAML syntax
python -c "import yaml; yaml.safe_load(open('config/servers.yml'))"

Cross-Reference Validation

# Check credential references
python -c "
from mcp_ssh.config import Config
config = Config('config/')
print('Valid configuration:', config.validate())
"

Policy Validation

# Test policy rules
python -c "
from mcp_ssh.policy import Policy
policy = Policy('config/policy.yml')
print('Policy valid:', policy.validate())
"

Configuration Security

Path Traversal Protection

Security Enhancement: mcp-ssh-orchestrator includes built-in path traversal protection for all file path resolution.

Secret Path Security

  • Secret names are validated to contain only safe characters (alphanumeric, dash, underscore)
  • Absolute paths are rejected for secrets (relative paths only)
  • All paths are normalized and validated to stay within /app/secrets
  • Path traversal attempts (e.g., ../, ..\\) are blocked and logged

SSH Key Path Security

  • Key paths can be relative or absolute
  • Absolute paths must be within the configured keys_dir
  • Traversal patterns (.., ..\\) are detected and rejected
  • Paths are normalized and validated before access
  • Only regular files are accepted (directories and symlinks are rejected)

File Type Validation

All resolved file paths are validated to ensure security:

  • Directories: Rejected (paths must point to files, not directories)
  • Symbolic Links: Rejected (symlinks can be security risks)
  • Regular Files: Accepted (must exist for secrets, optional for keys)
  • Non-existent files: Allowed for keys (validated when actually used)

Security Events: All path traversal attempts and file validation failures are logged as security events for monitoring and incident response.

YAML File Size Limits

All YAML configuration files are protected against resource exhaustion attacks:

  • Maximum File Size: 10MB per YAML file (applies to servers.yml, credentials.yml, policy.yml)
  • Size Validation: File size is checked before parsing to prevent loading oversized files
  • Security Impact: Prevents resource exhaustion attacks via maliciously large configuration files
  • Logging: Size limit violations are logged as security events

Effect: Protects against memory exhaustion and processing time attacks while allowing legitimate large configurations.

File Permissions

# Secure configuration files
chmod 0600 config/servers.yml
chmod 0600 config/credentials.yml  
chmod 0600 config/policy.yml
chmod 0400 keys/*.pem
chmod 0400 keys/id_ed25519

Secrets Management

# credentials.yml - Use secrets, not plaintext
entries:
  - name: "prod_admin"
    username: "ubuntu"
    key_path: "id_ed25519"
    key_passphrase_secret: "prod_key_passphrase"  # Docker secret
    password_secret: ""                            # Empty = no password

Environment Variables

# Override configuration via environment
export MCP_SSH_CONFIG_DIR="/custom/config"
export MCP_SSH_SECRET_PROD_PASSWORD="secret-password"

Configuration Examples

Development Environment

# servers.yml - Development hosts
hosts:
  - alias: "dev-web-1"
    host: "192.168.1.10"
    port: 22
    credentials: "dev_admin"
    tags: ["development", "web"]

# credentials.yml - Development credentials
entries:
  - name: "dev_admin"
    username: "developer"
    key_path: "dev_key"
    key_passphrase_secret: "dev_passphrase"

# policy.yml - Permissive development policy
limits:
  max_seconds: 120
  require_known_host: true  # Always enforced for security (CWE-295)

rules:
  - action: "allow"
    aliases: ["dev-*"]
    commands: ["*"]  # Allow all commands in dev

Production Environment

# servers.yml - Production hosts
hosts:
  - alias: "prod-web-1"
    host: "10.0.0.11"
    port: 22
    credentials: "prod_admin"
    tags: ["production", "web"]

# credentials.yml - Production credentials
entries:
  - name: "prod_admin"
    username: "ubuntu"
    key_path: "prod_key"
    key_passphrase_secret: "prod_passphrase"

# policy.yml - Strict production policy
limits:
  max_seconds: 30
  require_known_host: true
  deny_substrings:
    - "rm -rf /"
    - "shutdown*"
    - "reboot*"

rules:
  - action: "allow"
    aliases: ["prod-*"]
    commands: ["uptime*", "df -h*", "systemctl status *"]

Configuration Management

Hot Reloading

# Reload configuration without restart
ssh_reload_config

Configuration Backup

# Backup configuration
tar -czf config-backup-$(date +%Y%m%d).tar.gz config/ keys/

Configuration Versioning

# Track configuration changes
git add config/
git commit -m "Update production policy for new hosts"

Troubleshooting Configuration

Common Issues

  1. YAML Syntax Errors

    # Check YAML syntax
    python -c "import yaml; yaml.safe_load(open('config/servers.yml'))"
  2. Missing Credential References

    # Validate credential references
    python -c "
    from mcp_ssh.config import Config
    config = Config('config/')
    for host in config.list_hosts():
        print(f'{host}: {config.get_host(host).credentials}')
    "
  3. Policy Rule Conflicts

    # Test policy rules
    ssh_plan --alias "web1" --command "uptime"

Configuration Validation Tools

# Validate all configuration files
python -m mcp_ssh.config validate config/

# Test policy rules
python -m mcp_ssh.policy test config/policy.yml

# Check credential references
python -m mcp_ssh.config check-refs config/

Next Steps

⚠️ **GitHub.com Fallback** ⚠️