docs: Add comprehensive Hostkeeper design document

- Architecture overview: Monolithic CLI with embedded TUI
- Component details: Command, TUI, Core Engine, Storage layers
- Data flow and workflows for all major operations
- Security architecture for Phase 1 (MVP) and Phase 2
- Error handling strategy and recovery procedures
- Cross-platform support strategy
- Implementation phases and success criteria

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
swanadiva
2026-06-22 14:58:20 +07:00
commit ddd3c666c3
+816
View File
@@ -0,0 +1,816 @@
# Hostkeeper: SSH/SFTP Management Tool - Design Document
**Date:** 2024-06-22
**Status:** Design Approved
**Version:** 1.0-MVP
---
## Executive Summary
Hostkeeper is a cross-platform SSH/SFTP management tool written in Go, inspired by Termius but implemented as a CLI tool with progressive TUI enhancement. The goal is to provide secure SSH credential management with cross-device sync capabilities through export/import functionality.
### Key Design Decisions
- **Architecture:** Monolithic CLI with embedded TUI (Progressive enhancement approach)
- **Interface:** Hybrid - CLI commands + TUI for management tasks
- **Storage:** JSON/YAML files (Phase 1), encrypted storage (Phase 2)
- **Platform:** Cross-platform (Linux, macOS, Windows, Termux/Android)
- **Sync:** Manual export/import (Phase 1), cloud sync (future)
---
## Project Requirements
### Must-Have Features (MVP)
1. **SSH Connection Management**
- Username/password authentication
- SSH key authentication
- Host organization and search
- Connection testing
2. **SFTP File Transfer**
- Native SFTP client (Phase 1)
- Custom TUI dual-pane browser (Phase 2)
3. **Credential Management**
- Secure local storage
- Host metadata (tags, descriptions)
- Quick access patterns
4. **SSH Key Management**
- Generate SSH keys
- Import existing keys
- Export keys for distribution
- Key-Host association
5. **Connection Snippets**
- Save common commands
- Variable substitution
- Per-host snippets
6. **Export/Import Functionality**
- Cross-device credential transfer
- Backup and restore
- Merge capabilities
7. **Cross-Platform Support**
- Single binary distribution
- Termux compatibility
- Platform-specific optimizations
8. **Security**
- File permission management
- Secure credential storage
- Memory protection for sensitive data
---
## Architecture Overview
### High-Level Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ HOSTKEEPER CLI │
│ (Single Binary) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
┌───────▼──────────┐ ┌──────▼──────┐ ┌─────────▼────────┐
│ Command Layer │ │ TUI Layer │ │ Core Engine │
│ │ │ │ │ │
│ • connect │ │ • Host List │ │ • SSH Client │
│ • list │ │ • SFTP UI │ │ • SFTP Client │
│ • sftp │ │ • Key Mgmt │ │ • Key Manager │
│ • export │ │ • Snippets │ │ • Encryption │
│ • import │ │ • Settings │ │ • Config I/O │
│ • add │ │ │ │ │
└─────────────────┘ └─────────────┘ └──────────────────┘
│ │ │
└─────────────────────┼─────────────────────┘
┌─────────▼─────────┐
│ Storage Layer │
│ │
│ • hosts.json │
│ • keys.json │
│ • snippets.json │
│ • config.yaml │
└──────────────────┘
```
### Key Design Principles
1. **Single Source of Truth** - All data stored in JSON/YAML files
2. **Command-First** - TUI is wrapper for core commands
3. **Layered Architecture** - UI → Business Logic → Storage
4. **Cross-Platform** - Pure Go, no OS-specific dependencies
5. **Encrypt-Ready** - Structure prepared for encryption upgrade
---
## Component Details
### 1. Command Layer (CLI Interface)
**Framework:** Cobra (standard Go CLI framework)
**Major Commands:**
```bash
hostkeeper connect <host> # SSH connection
hostkeeper list # List all hosts
hostkeeper sftp <host> # SFTP browser
hostkeeper add # Add new host
hostkeeper edit <host> # Edit host config
hostkeeper delete <host> # Delete host
hostkeeper export <file> # Export credentials
hostkeeper import <file> # Import credentials
hostkeeper key generate # Generate SSH key
hostkeeper key import <file> # Import existing key
hostkeeper snippet add <name> # Add command snippet
hostkeeper completion # Shell completion setup
```
**Error Handling:**
- Invalid command → Show help message
- Missing arguments → Prompt interactive input
- Connection errors → User-friendly error messages with hints
---
### 2. TUI Layer (Interactive Interface)
**Framework:** Bubble Tea (recommended for modern, maintainable TUI)
**Main Screens:**
- **Host List:** Grid/List view with status indicators
- **Connection Manager:** Active connections, quick actions
- **SFTP Browser:** Dual-pane file browser (Phase 2)
- **Key Manager:** SSH keys list, import/export, generate
- **Snippet Manager:** Command snippets with variables
- **Settings:** Config management, preferences
**TUI Features:**
- Event-driven architecture
- Responsive layout
- Keyboard navigation
- Mouse support (optional)
- Quick actions (`/` search, `n` new, `Ctrl+S` SFTP, etc.)
---
### 3. Core Engine (Business Logic)
#### SSH Client Module
```go
type SSHClient struct {
Hostname string
Port int
AuthMethod AuthMethod // password, key, or both
ClientConfig *ssh.ClientConfig
}
func (c *SSHClient) Connect() (*ssh.Client, error)
func (c *SSHClient) Execute(cmd string) (string, error)
func (c *SSHClient) Close() error
```
#### SFTP Client Module
```go
type SFTPClient struct {
SSHClient *SSHClient
Client *sftp.Client
}
func (s *SFTPClient) Connect() error
func (s *SFTPClient) Upload(local, remote string) error
func (s *SFTPClient) Download(remote, local string) error
func (s *SFTPClient) List(path string) ([]os.FileInfo, error)
```
#### Key Management Module
```go
type KeyManager struct {
StoragePath string
}
func (k *KeyManager) GenerateKey(name string) (*KeyPair, error)
func (k *KeyManager) ImportKey(name, keyPath string) error
func (k *KeyManager) ExportKey(name, destPath string) error
func (k *KeyManager) ListKeys() ([]KeyInfo, error)
```
---
### 4. Storage Layer (Data Persistence)
#### File Structure
```
~/.hostkeeper/
├── config.yaml # App configuration
├── hosts.json # Saved hosts/connections
├── keys.json # SSH keys store
├── snippets.json # Command snippets
└── exported/ # Exported configurations
└── hostkeeper-backup-2024-06-22.json
```
#### Data Structures
**hosts.json:**
```json
{
"hosts": [
{
"id": "server1",
"name": "Production Server",
"hostname": "192.168.1.100",
"port": 22,
"username": "admin",
"auth": {
"type": "key",
"key_id": "default_key",
"password": null
},
"tags": ["production", "linux"],
"created_at": "2024-06-22T10:00:00Z"
}
]
}
```
**keys.json:**
```json
{
"keys": [
{
"id": "default_key",
"name": "Default Key",
"private_key": "-----BEGIN RSA PRIVATE KEY-----...",
"public_key": "ssh-rsa AAAA...",
"comment": "Generated by hostkeeper",
"created_at": "2024-06-22T10:00:00Z"
}
]
}
```
**config.yaml:**
```yaml
version: "1.0"
default_port: 22
connection_timeout: 30
sftp_timeout: 60
log_level: info
storage:
encrypt: false
compression: false
terminal:
color_scheme: default
font_size: medium
```
---
## Key User Workflows
### Workflow 1: Quick SSH Connection (Command-based)
```bash
$ hostkeeper connect production
```
**Flow:**
1. CLI parses command → validates host exists
2. Core Engine loads host config from `hosts.json`
3. Establishes SSH connection with native terminal
4. User gets native terminal experience
5. On exit: connection cleanup, return to CLI
**Error Handling:**
- Host not found → Show available hosts
- Connection failed → User-friendly error with troubleshooting tips
- Auth failed → Prompt for password/key selection
---
### Workflow 2: Add New Host (Interactive)
```bash
$ hostkeeper add
```
**Interactive Prompts:**
```
Hostname: staging-server
IP Address: 192.168.1.50
Port: [22]
Username: admin
Auth Method: [1] Password [2] SSH Key → 2
Tags: staging, linux, development
```
**Flow:**
1. Collect host information interactively
2. Validate for duplicates
3. Generate UUID for host
4. Append to `hosts.json`
5. Offer connection test
---
### Workflow 3: SFTP File Transfer
#### Phase 1 (MVP) - Native SFTP
```bash
$ hostkeeper sftp production
sftp> put /local/file.txt /remote/path/
sftp> get /remote/file.zip /local/backup/
sftp> ls -la /var/www/
```
#### Phase 2 - Custom TUI Browser
```
┌────────────────────┬────────────────────┐
│ Local Files │ Remote Files │
│ │ │
│ 📁 Documents/ │ 📁 /var/www/ │
│ 📄 file.txt │ 📄 index.html │
│ 📄 backup.zip │ 📄 config.php │
│ │ │
│ [Upload] [Refresh] │ [Download] [Delete]│
└────────────────────┴────────────────────┘
```
---
### Workflow 4: Export/Import Credentials
```bash
$ hostkeeper export backup-2024-06.json
$ hostkeeper import backup-2024-06.json
```
**Export Flow:**
1. Read all JSON files
2. Combine into single structure
3. Phase 1: Plain JSON export
4. Phase 2: AES-256 encryption with password
5. Write export file with summary
**Export Structure:**
```json
{
"version": "1.0",
"exported_at": "2024-06-22T16:00:00Z",
"data": {
"hosts": [...],
"keys": [...],
"snippets": [...],
"config": {...}
}
}
```
**Import Flow:**
1. Validate import file format
2. Phase 2: Decrypt with password
3. Merge options: replace/merge/skip
4. Update local JSON files
5. Show import summary
---
## Security Architecture
### Phase 1 Security (MVP)
**File Security:**
- File permissions: 0600 (owner read/write only)
- Environment variable protection
- No password/key logging in errors
- Sensitive data filtering from logs
- Plain text storage (Phase 2 encryption)
**Security Measures:**
```go
// Proper file permissions
func SaveConfig(data []byte, path string) error {
err := os.WriteFile(path, data, 0600)
if err != nil {
return err
}
// Validate permissions
info, _ := os.Stat(path)
if info.Mode().Perm() != 0600 {
os.Chmod(path, 0600)
}
return nil
}
```
---
### Phase 2 Security (Enhanced)
**Encryption Layer:**
```go
type EncryptionManager struct {
MasterPassword []byte
Salt []byte
}
func (e *EncryptionManager) EncryptData(data []byte) ([]byte, error) {
// PBKDF2 key derivation
key := pbkdf2.Key(e.MasterPassword, e.Salt, 100000, 32, sha256.New)
// AES-256-GCM encryption
block, err := aes.NewCipher(key)
gcm, err := cipher.NewGCM(block)
// Encrypt with random nonce
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce)
ciphertext := gcm.Seal(nonce, nonce, data, nil)
return ciphertext, nil
}
```
**Encrypted Storage Format:**
```json
{
"version": "2.0",
"encryption": "AES-256-GCM",
"iterations": 100000,
"salt": "base64_encoded_salt",
"data": "encrypted_base64_data"
}
```
---
### Security Best Practices
**Memory Security:**
```go
// Clear sensitive data from memory
func ClearSensitiveData(data []byte) {
for i := range data {
data[i] = 0
}
}
defer ClearSensitiveData(password)
```
**Logging Security:**
```go
// Filter sensitive information
func sanitizeSensitiveData(input string) string {
sensitivePatterns := []string{
`password["']?\s*[:=]\s*["']?[^\s"']+`,
`private_key["']?\s*[:=]\s*["']?.+?["']?`,
}
for _, pattern := range sensitivePatterns {
re := regexp.MustCompile(pattern)
input = re.ReplaceAllString(input, "[REDACTED]")
}
return input
}
```
---
## Error Handling Strategy
### Connection Error Handling
```go
type ConnectionError struct {
Type string // "auth", "network", "timeout", "config"
Message string
Details string
Hints []string
}
func HandleSSHError(err error) *ConnectionError {
switch {
case strings.Contains(err.Error(), "connection refused"):
return &ConnectionError{
Type: "network",
Message: "Cannot connect to server",
Details: err.Error(),
Hints: []string{"Check if server is running", "Verify firewall rules"},
}
case strings.Contains(err.Error(), "authentication failed"):
return &ConnectionError{
Type: "auth",
Message: "Authentication failed",
Details: err.Error(),
Hints: []string{"Verify username/password", "Check SSH key permissions"},
}
// ... additional cases
}
}
```
**Error Display Format:**
```
❌ Connection Error: Authentication failed
Details: ssh: handshake failed: ssh: unable to authenticate
Possible solutions:
1. Verify username: admin
2. Check SSH key is loaded: hostkeeper key list
3. Test connection manually: ssh admin@192.168.1.100
Use 'hostkeeper edit production' to update credentials
```
---
### Critical Error Scenarios
**Scenario 1: Corrupted Configuration File**
```
❌ Configuration Error: Invalid hosts.json
Details: hosts.json contains corrupted data at line 23
Recovery options:
1. Restore from backup: ~/.hostkeeper/hosts.json.backup
2. Import from export: hostkeeper import backup.json
3. Reset configuration: hostkeeper reset --force (⚠️ This will delete all data)
Action needed: Configuration is unusable. Please choose recovery option.
```
**Scenario 2: SSH Key Permission Issues**
```
⚠️ Security Warning: Insecure key permissions
File: ~/.ssh/id_rsa has permissions 644
Recommended: 600 (owner read/write only)
Auto-fix command:
$ chmod 600 ~/.ssh/id_rsa
Continue anyway? [y/N]
```
---
## Cross-Platform Strategy
### Platform Support
**Primary Platforms:**
- Linux (x86_64, ARM)
- macOS (x86_64, ARM64)
- Windows (x86_64)
- Termux/Android (ARM)
**Build Strategy:**
- Go cross-compilation for all platforms
- Single binary distribution
- Platform-specific optimizations
**Platform-Specific Handling:**
**Linux/Unix:**
- Standard permission handling
- Native terminal integration
- System configuration paths
**macOS:**
- Keychain integration (optional)
- Proper terminal sizing
- macOS-specific paths
**Windows:**
- Windows Terminal support
- Path handling (backslash vs forward slash)
- Registry integration (optional)
**Termux/Android:**
- File permissions workaround
- Storage location adaptation
- Terminal limitations handling
---
## Technology Stack
### Core Libraries
**SSH/SFTP:**
- `golang.org/x/crypto/ssh` - SSH protocol implementation
- `pkg.sftp.io/ssh` - SFTP client implementation
**CLI Framework:**
- `github.com/spf13/cobra` - Command framework
- `github.com/spf13/viper` - Configuration management
**TUI Framework:**
- `github.com/charmbracelet/bubbletea` - TUI framework
- `github.com/charmbracelet/lipgloss` - Styling
**Encryption:**
- `crypto/aes` - AES encryption (Phase 2)
- `crypto/cipher` - Cipher implementations
- `crypto/pbkdf2` - Key derivation
**Utilities:**
- `encoding/json` - JSON handling
- `gopkg.in/yaml.v3` - YAML support
- `github.com/google/uuid` - UUID generation
---
## Implementation Phases
### Phase 1: MVP Foundation (3-4 weeks)
**Core Functionality:**
- Basic SSH connections (native terminal)
- Host management (add, list, edit, delete)
- SSH key generation and import
- Export/Import (plain JSON)
- Native SFTP client
- Basic TUI for host management
**Deliverables:**
- Working CLI with core commands
- JSON-based storage
- Cross-platform binary builds
- Basic documentation
---
### Phase 2: Enhanced Features (4-6 weeks)
**TUI Enhancement:**
- Rich TUI interface for all operations
- Dual-pane SFTP browser
- Key management UI
- Snippet manager
- Connection snippets execution
**Security Enhancement:**
- AES-256 encryption for storage
- Master password protection
- Secure credential export/import
- Enhanced error messages
**User Experience:**
- Shell completion
- Configuration profiles
- Theme support
- Keyboard shortcuts
---
### Phase 3: Advanced Features (Future)
**Cloud Sync:**
- User account system
- Encrypted cloud storage
- Real-time multi-device sync
- Conflict resolution
**Advanced Terminal:**
- Custom terminal emulator
- Multiple session management
- Tab support
- Advanced text selection
**Integration:**
- Web UI (optional)
- API access
- Plugin system
- Third-party integrations
---
## Development Guidelines
### Code Quality
**Standards:**
- Follow Go best practices and idioms
- Comprehensive error handling
- Logging for debugging
- Code documentation
- Unit tests for critical functions
**Security Considerations:**
- No hardcoded credentials
- Input validation and sanitization
- Secure default configurations
- Regular security audits
---
### Testing Strategy
**Unit Testing:**
- Core engine functions
- SSH connection logic
- Encryption/decryption
- Configuration management
**Integration Testing:**
- End-to-end SSH connections
- SFTP operations
- Export/Import functionality
- Cross-platform compatibility
**Manual Testing:**
- Cross-platform testing (Linux, macOS, Windows, Termux)
- User experience validation
- Performance testing
- Security validation
---
## Success Criteria
### MVP Success Metrics
- ✅ Can establish SSH connections to remote servers
- ✅ Can manage multiple hosts with different auth methods
- ✅ Can perform SFTP operations (Phase 1: native, Phase 2: TUI)
- ✅ Can export/import credentials across devices
- ✅ Works on Linux, macOS, Windows, and Termux
- ✅ Secure credential storage with proper permissions
- ✅ User-friendly error messages and help text
### Phase 2 Success Metrics
- ✅ Rich TUI interface for all operations
- ✅ Encrypted credential storage
- ✅ Dual-pane SFTP browser
- ✅ Shell completion and documentation
- ✅ Enhanced user experience
---
## Risks and Mitigation
### Technical Risks
**Risk:** SSH terminal emulation complexity
**Mitigation:** Progressive approach - native terminal first, custom TUI later
**Risk:** Cross-platform compatibility issues
**Mitigation:** Extensive testing on all platforms, Go's cross-compilation
**Risk:** Performance issues with TUI
**Mitigation:** Framework selection (Bubble Tea), performance testing
### Security Risks
**Risk:** Credential exposure
**Mitigation:** Proper file permissions, memory clearing, secure defaults
**Risk:** Key management complexity
**Mitigation:** Clear user guidance, validation, secure defaults
**Risk:** Encryption implementation bugs
**Mitigation:** Use standard libraries, security audits, testing
---
## Conclusion
Hostkeeper aims to provide a comprehensive SSH/SFTP management solution with cross-platform support and secure credential management. The progressive development approach ensures rapid delivery of core functionality while maintaining a clear path to advanced features.
The hybrid CLI/TUI approach balances power user needs with accessibility, while the phased implementation allows for iterative improvement based on user feedback.
---
**Document Status:** Approved for implementation
**Next Steps:** Implementation planning using writing-plans skill
---
*Sources:*
- [golang.org/x/crypto/ssh](https://pkg.go.dev/golang.org/x/crypto/ssh)
- [Cobra CLI Framework](https://github.com/spf13/cobra)
- [Bubble Tea TUI Framework](https://github.com/charmbracelet/bubbletea)
- [Tamagosh SSH Manager](https://github.com/Candratama/tamagosh)
- [Termius SSH Client](https://termius.com/)