842 lines
23 KiB
Markdown
842 lines
23 KiB
Markdown
# 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:** TUI-first with tab-based session management (embedded terminal replacement)
|
|
- **Interface:** TUI for full experience (multiple SSH sessions, host management, SFTP); CLI for quick tasks and automation
|
|
- **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 files
|
|
2. **TUI-First** - TUI is the primary interface; CLI commands serve quick tasks and scripting
|
|
3. **Layered Architecture** - UI → Business Logic → Storage
|
|
4. **Cross-Platform** - Pure Go, no OS-specific dependencies
|
|
5. **Encrypt-Ready** - Structure prepared for encryption upgrade
|
|
6. **Orange Theme** - Distinct orange color palette to visually separate Hostkeeper from the native terminal, signaling the user is inside the application environment
|
|
|
|
---
|
|
|
|
## 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 (event-driven TUI) + Lipgloss (styling)
|
|
|
|
**Theme:** Orange/light color palette (`#FF6B00`, `#FF9F43`, `#FFB800`) — visually distinct from native terminal to signal the user is inside Hostkeeper
|
|
|
|
#### Tab System Architecture
|
|
|
|
```
|
|
┌─ Hosts ──── Server Nico ── SFTP ── Keys ── Settings ────────┐
|
|
│ │
|
|
│ [content of active tab] │
|
|
│ │
|
|
├───────────────────────────────────────────────────────────────┤
|
|
│ Ctrl+Q:close Ctrl+Tab:next Shift+Tab:prev ↑↓:nav /:search│
|
|
└───────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Tab Types:**
|
|
- **HostsTab** — Host list with search, filter, sort, keyboard navigation
|
|
- **SessionTab** — Live interactive SSH session (input/output piped via Go SSH client)
|
|
- **SFTPTab** — Remote file browser with upload/download operations
|
|
- **KeysTab** — SSH key management (list, generate, import)
|
|
- **SnippetsTab** — Command snippets with variable substitution
|
|
- **SettingsTab** — Application configuration
|
|
|
|
**SessionTab Internals:**
|
|
- Connect via Go SSH client with stored credentials (password auto-injected)
|
|
- 2 goroutines per session: stdin → SSH channel, SSH stdout → TUI render
|
|
- Terminal resize event → `WindowChange` via SSH channel
|
|
- `Ctrl+Q` disconnects session and closes tab
|
|
- Multiple session tabs can be open simultaneously (e.g. connect to 3 servers at once)
|
|
|
|
**Keyboard Navigation:**
|
|
| Key | Action |
|
|
|-----|--------|
|
|
| `Ctrl+Tab` / `Shift+Tab` | Cycle tabs forward/backward |
|
|
| `Ctrl+N` | New tab (add host / new connection) |
|
|
| `Ctrl+Q` | Close current tab / disconnect session |
|
|
| `↑` / `↓` | Navigate lists (hosts, keys, files) |
|
|
| `Enter` | Select host / open directory / confirm |
|
|
| `/` | Search/filter within active tab |
|
|
| `q` | Quit Hostkeeper (confirmation dialog) |
|
|
|
|
---
|
|
|
|
### 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/) |