Location: ~/.dynamic-mcp/oauth-servers/
Security Measures:
- Tokens stored in user's home directory
- File-based storage with JSON serialization
- No encryption at rest (relies on filesystem permissions)
- Directory created with default umask permissions (typically 0755)
- Token files created with default umask permissions (typically 0644)
- WARNING: No automatic permission hardening - operators must manually set restrictive permissions
Token Security:
- PKCE (Proof Key for Code Exchange) used for authorization
- RFC 6749 compliant refresh token rotation
- Automatic token refresh before expiry (5-minute buffer)
- Tokens include expiry timestamp for validation
Recommendations for Production:
- Ensure home directory has proper permissions (mode 0700)
- Consider using OS keychain integration for token storage:
- macOS: Keychain Access
- Linux: Secret Service API (gnome-keyring, KWallet)
- Windows: Credential Manager
- Implement token encryption at rest if operating in multi-user environments
- Rotate credentials regularly using OAuth refresh flow
- Monitor token storage location for unauthorized access
Syntax: Only ${VAR} syntax supported (not $VAR)
Security Considerations:
- Environment variables exposed to child processes (stdio transport)
- No sanitization of env var values
- Undefined variables preserved as
${VAR}with warning
Recommendations:
- Avoid storing secrets directly in config files
- Use environment variables for sensitive data
- Set restrictive permissions on config files (0600)
- Review environment variables passed to child processes
- Consider using secret management tools (e.g., HashCorp Vault)
HTTP/SSE Transports:
- HTTPS recommended but not enforced (HTTP URLs accepted)
- No certificate pinning (uses system trust store via rustls)
- Custom headers supported (including
Authorization) - No request/response size limits enforced
Recommendations:
- Use HTTPS for all remote MCP servers
- Validate TLS certificates (default behavior)
- Implement rate limiting on upstream servers
- Monitor network traffic for anomalies
Child Process Management (stdio transport):
- Spawns child processes with configured environment variables
- Process groups created for proper cleanup (Unix: setpgid, Windows: CREATE_NEW_PROCESS_GROUP)
- Graceful shutdown with SIGTERM, forced cleanup with SIGKILL on drop
- Stderr redirected to null to prevent noise
- No sandboxing or containerization
- Child processes run with same user privileges
- No resource limits enforced (CPU, memory, file descriptors)
Recommendations:
- Review command and args in configuration before deployment
- Use absolute paths for commands to prevent PATH hijacking
- Consider using containerization for isolation
- Implement resource limits at OS level (ulimit, cgroups)
- Monitor child process behavior
Config File: User-specified path (no default discovery)
- Must be explicitly provided as CLI argument or via
DYNAMIC_MCP_CONFIGenvironment variable - Common names:
config.json,dynamic-mcp.json(by convention, not enforced)
Security Considerations:
- Plain text JSON (no encryption)
- May contain sensitive data (URLs, OAuth client IDs, API tokens)
- Read by multiple modules during startup
- Live reload feature watches config file for changes
- File path validation not enforced (accepts any valid path)
Recommendations:
- Set restrictive permissions:
chmod 600 config.json - Store in secure location (not web-accessible directories)
- Use environment variables for secrets (${VAR} syntax)
- Add config files to
.gitignore - Review changes before config reload (automatic reload triggers on file modification)
- Token Storage: Tokens stored as plain text in filesystem (not encrypted, default umask permissions)
- File Permissions: No automatic permission hardening (operators must manually set 0600/0700)
- No HTTPS Enforcement: HTTP URLs accepted (relies on user to configure HTTPS)
- No Rate Limiting: No built-in rate limiting for tool calls
- No Audit Logging: Security events not logged separately
- No Input Validation: Tool arguments passed through without validation
- Process Privileges: Child processes inherit full privileges
- No Sandboxing: No isolation between upstream MCP servers
-
Least Privilege:
# Run as dedicated user with minimal permissions useradd -r -s /bin/false dynamic-mcp sudo -u dynamic-mcp /usr/local/bin/dmcp config.json -
File Permissions (CRITICAL - not set automatically):
# Config file (use your actual config filename) chmod 600 config.json chown dynamic-mcp:dynamic-mcp config.json # Token storage directory and files chmod 700 ~/.dynamic-mcp chmod 700 ~/.dynamic-mcp/oauth-servers chmod 600 ~/.dynamic-mcp/oauth-servers/*.json # Verify permissions ls -la ~/.dynamic-mcp/oauth-servers/
-
Network Isolation:
# Restrict network access with firewall rules # Allow only necessary outbound connections
-
Monitoring:
# Enable debug logging RUST_LOG=debug dmcp config.json # Monitor for anomalies tail -f /var/log/dmcp.log | grep -E 'ERROR|WARN'
-
Regular Updates:
# Check for updates regularly pip install --upgrade dmcp # or: cargo install dynamic-mcp --force
-
Input Validation:
- Validate all tool arguments before passing to upstream
- Sanitize file paths and command arguments
- Implement schema validation for tool inputs
-
Secret Management:
- Never log tokens or secrets
- Use secure comparison for CSRF tokens
- Implement token rotation policies
-
Error Handling:
- Don't leak sensitive information in error messages
- Log security events separately
- Implement rate limiting for authentication
-
Code Review:
- Security-focused code review for auth changes
- Dependency audit:
cargo audit - Static analysis:
cargo clippy
-
Testing:
- Security test cases in CI/CD
- Fuzzing for input validation
- Regular penetration testing
- OAuth 2.0: RFC 6749
- PKCE: RFC 7636
- Token Refresh: RFC 6749 Section 6
- MCP Specification: Model Context Protocol
****_****_****_****_****
Last Updated: January 10, 2026 Version: 1.3.0