docs: sync from docs/wiki/ at commit 74f56b6a
parent
05b4c5504b
commit
ca09347f58
@ -90,16 +90,49 @@ Uses OpenAI-compatible request/response format.
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| `config.name` | `"ollama"` |
|
||||
| Default URL | `http://localhost:11434/api/chat` |
|
||||
| Default URL | `http://localhost:11434` |
|
||||
| Auth | None |
|
||||
| Max tokens | No limit enforced |
|
||||
| **Tool Calling** | ✅ **Fully Supported** (v1.0.7+) |
|
||||
| Timeout | 180s (tool calling), 60s (regular chat) |
|
||||
| Retry Logic | 3 attempts with 2s delay |
|
||||
|
||||
**Models:** Any model pulled locally — `llama3.1`, `llama3`, `mistral`, `codellama`, `phi3`, etc.
|
||||
**Recommended Models (≥3B parameters):**
|
||||
|
||||
Fully offline. Responses include `eval_count` / `prompt_eval_count` token stats.
|
||||
| Model | Size | Min RAM | Notes |
|
||||
|-------|------|---------|-------|
|
||||
| `llama3.2:3b` | 2.0 GB | 6 GB | Balanced performance |
|
||||
| `phi3.5:3.8b` | 2.2 GB | 6 GB | Excellent reasoning |
|
||||
| `llama3.1:8b` | 4.7 GB | 10 GB | **RECOMMENDED** - Strong IT analysis |
|
||||
| `qwen2.5:14b` | 9.0 GB | 16 GB | Best for complex log analysis |
|
||||
| `gemma2:9b` | 5.5 GB | 12 GB | Google's efficient model |
|
||||
|
||||
**⚠️ Important:** Models with <3B parameters (e.g., `llama3.2:1b`) cannot reliably follow tool calling instructions. They will describe tools instead of invoking them.
|
||||
|
||||
**Features:**
|
||||
- ✅ **Function Calling Support** (v1.0.7): Executes shell commands, kubectl operations
|
||||
- ✅ **Multi-turn Tool Conversations**: Preserves `tool_call_id` for correlation
|
||||
- ✅ **Resilient Parsing**: Skips malformed tool calls with warnings
|
||||
- ✅ **Connection Reliability** (v1.0.8): Health checks, retry logic, extended timeouts
|
||||
- ✅ **Auto-Start**: Automatically starts Ollama service if not running
|
||||
- ✅ **Fully Offline**: No internet required, complete privacy
|
||||
|
||||
**Custom URL:** Change the Ollama URL in Settings → AI Providers → Ollama (stored in `settingsStore.ollama_url`).
|
||||
|
||||
**Troubleshooting:**
|
||||
|
||||
| Error | Cause | Solution |
|
||||
|-------|-------|----------|
|
||||
| "Cannot connect to Ollama" | Service not running | Run `ollama serve` or check auto-start |
|
||||
| Timeout after 60s (chat) / 180s (tool calling) | Model too slow / tool calling needs more time | Use a smaller model, reduce tool usage, or wait for the higher tool-calling timeout to elapse |
|
||||
| Tool calls described but not executed | Model too small (<3B) | Use `llama3.2:3b` or larger |
|
||||
| Model not loaded | First request loads model | Wait 5-10s for model to load into VRAM |
|
||||
|
||||
**Performance Tips:**
|
||||
- Use quantized models (Q4_K_M or Q4_0) for faster responses
|
||||
- Keep model loaded with `ollama run <model>` in background
|
||||
- Monitor VRAM usage - models stay loaded for 5 minutes by default
|
||||
|
||||
---
|
||||
|
||||
## Domain System Prompts
|
||||
|
||||
@ -5,10 +5,11 @@
|
||||
| Component | URL | Notes |
|
||||
|-----------|-----|-------|
|
||||
| Gitea | `https://gogs.tftsr.com` / `http://172.0.0.29:3000` | Git server (migrated from Gogs 0.14) |
|
||||
| Woodpecker CI (direct) | `http://172.0.0.29:8084` | v2.x |
|
||||
| Woodpecker CI (proxy) | `http://172.0.0.29:8085` | nginx reverse proxy |
|
||||
| Gitea Actions | Built into Gitea | Native GitHub Actions-compatible CI/CD |
|
||||
| PostgreSQL (Gitea DB) | Container: `gogs_postgres_db` | DB: `gogsdb`, User: `gogs` |
|
||||
|
||||
**CI/CD System:** Gitea Actions (v1.22+) with native GitHub Actions API compatibility. Uses `.gitea/workflows/*.yml` for workflow definitions.
|
||||
|
||||
### CI Agents
|
||||
|
||||
| Agent | Platform | Host | Purpose |
|
||||
@ -35,9 +36,9 @@ Rust toolchain, cross-compilers) so that CI jobs skip package installation entir
|
||||
|
||||
| Image | Used by jobs | Contents |
|
||||
|-------|-------------|----------|
|
||||
| `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22` | `rust-fmt-check`, `rust-clippy`, `rust-tests`, `build-linux-amd64` | Rust 1.88 + rustfmt + clippy + Tauri amd64 libs + Node.js 22 |
|
||||
| `172.0.0.29:3000/sarman/trcaa-windows-cross:rust1.88-node22` | `build-windows-amd64` | Rust 1.88 + mingw-w64 + NSIS + Node.js 22 |
|
||||
| `172.0.0.29:3000/sarman/trcaa-linux-arm64:rust1.88-node22` | `build-linux-arm64` | Rust 1.88 + aarch64 cross-toolchain + arm64 multiarch libs + Node.js 22 |
|
||||
| `172.0.0.29:3000/sarman/tftsr-linux-amd64:rust1.88-node22` | `rust-fmt-check`, `rust-clippy`, `rust-tests`, `build-linux-amd64` | Rust 1.88 + rustfmt + clippy + Tauri amd64 libs + Node.js 22 |
|
||||
| `172.0.0.29:3000/sarman/tftsr-windows-cross:rust1.88-node22` | `build-windows-amd64` | Rust 1.88 + mingw-w64 + NSIS + Node.js 22 |
|
||||
| `172.0.0.29:3000/sarman/tftsr-linux-arm64:rust1.88-node22` | `build-linux-arm64` | Rust 1.88 + aarch64 cross-toolchain + arm64 multiarch libs + Node.js 22 |
|
||||
|
||||
**Rebuild triggers:** Rust toolchain version bump, webkit2gtk/gtk major version change, Node.js major version change.
|
||||
|
||||
@ -106,7 +107,7 @@ Pipeline jobs (run in parallel):
|
||||
```
|
||||
|
||||
**Docker images used:**
|
||||
- `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22` — Rust steps (replaces `rust:1.88-slim`)
|
||||
- `172.0.0.29:3000/sarman/tftsr-linux-amd64:rust1.88-node22` — Rust steps (replaces `rust:1.88-slim`)
|
||||
- `node:22-alpine` — Frontend steps
|
||||
|
||||
---
|
||||
@ -120,15 +121,15 @@ Release jobs are executed in the same workflow and depend on `autotag` completio
|
||||
|
||||
```
|
||||
Jobs (run in parallel after autotag):
|
||||
build-linux-amd64 → image: trcaa-linux-amd64:rust1.88-node22
|
||||
build-linux-amd64 → image: tftsr-linux-amd64:rust1.88-node22
|
||||
→ cargo tauri build (x86_64-unknown-linux-gnu)
|
||||
→ {.deb, .rpm, .AppImage} uploaded to Gitea release
|
||||
→ fails fast if no Linux artifacts are produced
|
||||
build-windows-amd64 → image: trcaa-windows-cross:rust1.88-node22
|
||||
build-windows-amd64 → image: tftsr-windows-cross:rust1.88-node22
|
||||
→ cargo tauri build (x86_64-pc-windows-gnu) via mingw-w64
|
||||
→ {.exe, .msi} uploaded to Gitea release
|
||||
→ fails fast if no Windows artifacts are produced
|
||||
build-linux-arm64 → image: trcaa-linux-arm64:rust1.88-node22 (ubuntu:22.04-based)
|
||||
build-linux-arm64 → image: tftsr-linux-arm64:rust1.88-node22 (ubuntu:22.04-based)
|
||||
→ cargo tauri build (aarch64-unknown-linux-gnu)
|
||||
→ {.deb, .rpm, .AppImage} uploaded to Gitea release
|
||||
→ fails fast if no Linux artifacts are produced
|
||||
|
||||
90
Database.md
90
Database.md
@ -389,6 +389,96 @@ CREATE VIEW IF NOT EXISTS v_image_attachments_with_issue AS
|
||||
|
||||
Used by `list_all_log_files` and `list_all_image_attachments` to power the cross-incident Attachments tab in the History page. Explicitly selects named columns (not `SELECT *`) to avoid including the BLOB data in list queries.
|
||||
|
||||
### 023 — MCP Resources table (MCP Integration v0.3.0+)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS mcp_resources (
|
||||
id TEXT PRIMARY KEY,
|
||||
server_id TEXT NOT NULL,
|
||||
uri TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
mime_type TEXT,
|
||||
discovered_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY(server_id) REFERENCES mcp_servers(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX idx_mcp_resources_server ON mcp_resources(server_id);
|
||||
```
|
||||
|
||||
Stores resources (files, data sources) exposed by MCP servers for AI agent access.
|
||||
|
||||
### 024 — shell_commands table (Shell Execution v1.0.0+)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS shell_commands (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_template TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL CHECK(tier IN (1, 2, 3)),
|
||||
description TEXT,
|
||||
category TEXT NOT NULL, -- 'kubectl', 'proxmox', 'general'
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
```
|
||||
|
||||
Pre-defined command templates with tier classification for the three-tier safety system. See [[Shell-Execution]] for details.
|
||||
|
||||
### 025 — kubeconfig_files table (Shell Execution v1.0.0+)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS kubeconfig_files (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
encrypted_content TEXT NOT NULL,
|
||||
context TEXT NOT NULL,
|
||||
cluster_url TEXT,
|
||||
is_active INTEGER NOT NULL DEFAULT 0,
|
||||
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE INDEX idx_kubeconfig_active ON kubeconfig_files(is_active);
|
||||
```
|
||||
|
||||
Encrypted storage for kubectl configuration files. Content encrypted with AES-256-GCM. Only one config can be active at a time.
|
||||
|
||||
### 026 — command_executions table (Shell Execution v1.0.0+)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS command_executions (
|
||||
id TEXT PRIMARY KEY,
|
||||
issue_id TEXT,
|
||||
command TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL,
|
||||
approval_status TEXT NOT NULL, -- 'auto', 'approved', 'denied'
|
||||
kubeconfig_id TEXT,
|
||||
exit_code INTEGER,
|
||||
stdout TEXT,
|
||||
stderr TEXT,
|
||||
execution_time_ms INTEGER,
|
||||
executed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (kubeconfig_id) REFERENCES kubeconfig_files(id) ON DELETE SET NULL
|
||||
);
|
||||
CREATE INDEX idx_command_executions_issue ON command_executions(issue_id);
|
||||
CREATE INDEX idx_command_executions_executed ON command_executions(executed_at);
|
||||
```
|
||||
|
||||
Complete audit trail of all shell command executions with exit codes, stdout/stderr capture, and execution timing.
|
||||
|
||||
### 027 — approval_decisions table (Shell Execution v1.0.0+)
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS approval_decisions (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_pattern TEXT NOT NULL,
|
||||
decision TEXT NOT NULL CHECK(decision IN ('allow_once', 'allow_session', 'deny')),
|
||||
session_id TEXT,
|
||||
decided_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
expires_at TEXT
|
||||
);
|
||||
CREATE INDEX idx_approval_decisions_session ON approval_decisions(session_id);
|
||||
```
|
||||
|
||||
Session-based approval preferences for Tier 2 commands. Allows users to approve similar commands for the duration of a session.
|
||||
|
||||
---
|
||||
|
||||
## Key Design Notes
|
||||
|
||||
@ -28,6 +28,20 @@ Node **v22** required. Install via nvm or system package manager.
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
|
||||
### kubectl Binary (for Shell Execution)
|
||||
|
||||
kubectl v1.30.0 is bundled with the application. To download binaries for development:
|
||||
|
||||
```bash
|
||||
./scripts/download-kubectl.sh linux amd64
|
||||
./scripts/download-kubectl.sh linux arm64
|
||||
./scripts/download-kubectl.sh darwin arm64
|
||||
./scripts/download-kubectl.sh darwin amd64
|
||||
./scripts/download-kubectl.sh windows amd64
|
||||
```
|
||||
|
||||
Binaries are placed in `binaries/kubectl-{os}-{arch}` and bundled via `tauri.conf.json` resources. See [[Shell-Execution]] for runtime usage details.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@ -603,6 +603,86 @@ interface TicketResult {
|
||||
|
||||
---
|
||||
|
||||
## Shell Execution Commands
|
||||
|
||||
> **Status:** Fully Implemented (v1.0.0+)
|
||||
>
|
||||
> See [[Shell-Execution]] for complete documentation of the three-tier safety system.
|
||||
|
||||
### `upload_kubeconfig`
|
||||
```typescript
|
||||
uploadKubeconfigCmd(name: string, content: string) → string
|
||||
```
|
||||
Upload and encrypt a kubeconfig file. Returns the kubeconfig ID.
|
||||
|
||||
### `list_kubeconfigs`
|
||||
```typescript
|
||||
listKubeconfigsCmd() → KubeconfigInfo[]
|
||||
```
|
||||
List all uploaded kubeconfig files with metadata.
|
||||
```typescript
|
||||
interface KubeconfigInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
context: string;
|
||||
cluster_url?: string;
|
||||
is_active: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### `activate_kubeconfig`
|
||||
```typescript
|
||||
activateKubeconfigCmd(id: string) → void
|
||||
```
|
||||
Set a kubeconfig as active for kubectl commands.
|
||||
|
||||
### `delete_kubeconfig`
|
||||
```typescript
|
||||
deleteKubeconfigCmd(id: string) → void
|
||||
```
|
||||
Delete a kubeconfig file permanently.
|
||||
|
||||
### `respond_to_shell_approval`
|
||||
```typescript
|
||||
respondToShellApprovalCmd(approvalId: string, decision: string) → void
|
||||
```
|
||||
Respond to a Tier 2 command approval request.
|
||||
- `decision`: `"deny"`, `"allow_once"`, or `"allow_session"`
|
||||
|
||||
### `list_command_executions`
|
||||
```typescript
|
||||
listCommandExecutionsCmd(issueId?: string) → CommandExecution[]
|
||||
```
|
||||
List recent command executions, optionally filtered by issue ID.
|
||||
```typescript
|
||||
interface CommandExecution {
|
||||
id: string;
|
||||
command: string;
|
||||
tier: number; // 1, 2, or 3
|
||||
approval_status: string; // 'auto', 'approved', 'denied'
|
||||
exit_code?: number;
|
||||
stdout?: string;
|
||||
stderr?: string;
|
||||
execution_time_ms?: number;
|
||||
executed_at: string;
|
||||
}
|
||||
```
|
||||
|
||||
### `check_kubectl_installed`
|
||||
```typescript
|
||||
checkKubectlInstalledCmd() → KubectlStatus
|
||||
```
|
||||
Check if kubectl is installed and return version info.
|
||||
```typescript
|
||||
interface KubectlStatus {
|
||||
installed: boolean;
|
||||
path?: string;
|
||||
version?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Storage
|
||||
|
||||
All integration credentials are stored in the `credentials` table:
|
||||
|
||||
665
Shell-Execution.md
Normal file
665
Shell-Execution.md
Normal file
@ -0,0 +1,665 @@
|
||||
# Shell Execution
|
||||
|
||||
**Status**: ✅ Production-ready agentic shell execution with three-tier safety classification (v1.0.0)
|
||||
|
||||
## Overview
|
||||
|
||||
The Shell Execution feature enables AI-powered autonomous execution of diagnostic commands with intelligent safety controls. The AI can directly execute kubectl, Proxmox tools, and general shell commands to gather troubleshooting data without manual intervention.
|
||||
|
||||
**Key Features**:
|
||||
- Three-tier command safety classification (auto/approve/deny)
|
||||
- Real-time approval modal for mutating operations
|
||||
- kubectl integration with bundled binary (v1.30.0)
|
||||
- Multi-cluster support via multiple kubeconfig files
|
||||
- AES-256-GCM encrypted kubeconfig storage
|
||||
- Complete audit trail for all executions
|
||||
- Pipe/chain command analysis with tier escalation
|
||||
- Command timeout protection (30s)
|
||||
- Approval timeout protection (60s)
|
||||
|
||||
## Three-Tier Safety Architecture
|
||||
|
||||
Commands are automatically classified into three safety tiers based on their potential impact:
|
||||
|
||||
### Tier 1: Auto-Execute (Read-Only)
|
||||
**Behavior**: Execute immediately without user approval
|
||||
|
||||
**kubectl commands**:
|
||||
- `kubectl get [resource]` - List resources
|
||||
- `kubectl describe [resource]` - Show detailed resource information
|
||||
- `kubectl logs [pod]` - View pod logs
|
||||
|
||||
**General commands**:
|
||||
- `cat [file]` - Display file contents
|
||||
- `grep [pattern]` - Search text patterns
|
||||
- `ls` - List directory contents
|
||||
- `pwd` - Print working directory
|
||||
- `whoami` - Display current user
|
||||
- `date` - Show system date/time
|
||||
- `uptime` - Show system uptime
|
||||
- `df -h` - Show disk usage
|
||||
- `free -m` - Show memory usage
|
||||
- `ps aux` - List processes
|
||||
|
||||
**Proxmox commands**:
|
||||
- `pvecm status` - Show cluster status
|
||||
- `pvesh get /cluster/status` - Get cluster status via API
|
||||
|
||||
### Tier 2: Require Approval (Mutating)
|
||||
**Behavior**: Pause execution and display approval modal to user
|
||||
|
||||
**kubectl commands**:
|
||||
- `kubectl apply -f [file]` - Apply configuration
|
||||
- `kubectl delete [resource]` - Delete resources
|
||||
- `kubectl scale [deployment]` - Scale deployments
|
||||
- `kubectl exec -it [pod]` - Execute command in container
|
||||
- `kubectl port-forward` - Forward ports
|
||||
- `kubectl patch` - Update resource fields
|
||||
- `kubectl create` - Create resources
|
||||
- `kubectl edit` - Edit resources
|
||||
|
||||
**System commands**:
|
||||
- `ssh` - Remote shell access
|
||||
- `scp` - Secure copy
|
||||
- `chmod` - Change file permissions
|
||||
- `chown` - Change file ownership
|
||||
- `systemctl restart [service]` - Restart services
|
||||
- `systemctl stop [service]` - Stop services
|
||||
- `systemctl start [service]` - Start services
|
||||
- `docker restart [container]` - Restart Docker containers
|
||||
- `docker stop [container]` - Stop Docker containers
|
||||
- `reboot` (with confirmation) - System reboot
|
||||
|
||||
**Proxmox commands**:
|
||||
- `qm start [vmid]` - Start virtual machine
|
||||
- `qm stop [vmid]` - Stop virtual machine
|
||||
- `qm restart [vmid]` - Restart virtual machine
|
||||
|
||||
### Tier 3: Always Deny (Destructive)
|
||||
**Behavior**: Immediate denial with clear reasoning
|
||||
|
||||
**Destructive operations**:
|
||||
- `rm -rf` - Recursive force delete
|
||||
- `mkfs` - Format filesystem
|
||||
- `dd` - Low-level disk operations
|
||||
- `fdisk` - Partition manipulation
|
||||
- `parted` - Partition editing
|
||||
- `shutdown` - System shutdown
|
||||
- `init 0` - System halt
|
||||
- `halt` - System halt
|
||||
- `poweroff` - System power off
|
||||
- `wipefs` - Wipe filesystem signatures
|
||||
|
||||
**Why Tier 3 is Denied**:
|
||||
These commands can cause irreversible data loss, system downtime, or infrastructure damage. They should only be executed manually by authorized personnel with explicit intent.
|
||||
|
||||
## Pipe and Chain Analysis
|
||||
|
||||
The classifier analyzes complex command structures and escalates to the highest tier found:
|
||||
|
||||
### Piped Commands
|
||||
```bash
|
||||
# Tier 1: Both commands are read-only
|
||||
kubectl get pods | grep nginx
|
||||
|
||||
# Tier 2: Second command is mutating (escalates entire chain)
|
||||
kubectl get pods | kubectl delete -f -
|
||||
|
||||
# Tier 3: Contains destructive operation (entire chain denied)
|
||||
cat /tmp/list.txt | xargs rm -rf
|
||||
```
|
||||
|
||||
### Logical Operators
|
||||
```bash
|
||||
# Tier 2: Uses && to chain mutating operations
|
||||
kubectl apply -f deployment.yaml && kubectl rollout status deployment/nginx
|
||||
|
||||
# Tier 2: Uses || for fallback (escalates to highest tier)
|
||||
ssh server1 || ssh server2
|
||||
|
||||
# Tier 3: Contains destructive command (entire chain denied)
|
||||
cd /tmp && rm -rf *
|
||||
```
|
||||
|
||||
### Command Substitution
|
||||
Commands using `$()` or backticks are flagged with a risk factor and analyzed recursively:
|
||||
|
||||
```bash
|
||||
# Tier 2: Inner command is read-only, but ssh requires approval
|
||||
ssh server "$(cat /tmp/script.sh)"
|
||||
|
||||
# Tier 3: Inner command is destructive (entire operation denied)
|
||||
rm -rf $(find / -name "*.tmp")
|
||||
```
|
||||
|
||||
## Approval Workflow
|
||||
|
||||
When a Tier 2 command is detected:
|
||||
|
||||
1. **Execution Paused**: Command execution stops before running
|
||||
2. **Modal Displayed**: Real-time modal appears in the UI showing:
|
||||
- Full command text
|
||||
- Safety tier badge
|
||||
- Classification reasoning
|
||||
- Risk factors (if any)
|
||||
- Safety controls in place
|
||||
3. **User Decision**: Three options available:
|
||||
- **Deny**: Reject the command permanently
|
||||
- **Allow Once**: Execute this specific command only
|
||||
- **Allow for Session**: Execute this and future similar commands in the current session
|
||||
4. **Timeout**: If no response within 60 seconds, automatically deny
|
||||
|
||||
### Approval Modal Screenshot
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 🛡️ Command Approval Required │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ This command requires your approval before execution │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ $ kubectl delete pod nginx-5d5f4c7d9-abcde │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Safety Tier: [Tier 2] │
|
||||
│ │
|
||||
│ ⚠️ Why approval is needed: │
|
||||
│ Mutating operation: kubectl delete │
|
||||
│ │
|
||||
│ Safety Controls: │
|
||||
│ • Command execution is logged and auditable │
|
||||
│ • 30-second timeout protection │
|
||||
│ • PII detection before execution │
|
||||
│ • Output is captured for review │
|
||||
│ │
|
||||
│ [Deny] [Allow Once] [Allow for Session] │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## kubectl Integration
|
||||
|
||||
### Bundled Binary
|
||||
kubectl v1.30.0 is bundled with the application for all platforms:
|
||||
- **Linux**: amd64, arm64
|
||||
- **macOS**: Intel (x86_64), Apple Silicon (aarch64)
|
||||
- **Windows**: amd64
|
||||
|
||||
The binary is automatically selected based on the runtime platform.
|
||||
|
||||
### Kubeconfig Management
|
||||
|
||||
**Upload Process**:
|
||||
1. Navigate to **Settings → Kubeconfig**
|
||||
2. Click **Upload Kubeconfig**
|
||||
3. Select your kubeconfig file (.yaml or .yml)
|
||||
4. Provide a friendly name (e.g., "production-cluster")
|
||||
5. File is parsed and validated
|
||||
6. Content is encrypted using AES-256-GCM
|
||||
7. Stored in `kubeconfig_files` table
|
||||
|
||||
**Multiple Clusters**:
|
||||
- Upload multiple kubeconfig files for different clusters
|
||||
- Only one can be **active** at a time
|
||||
- Activate a config by clicking **Activate** button
|
||||
- Active config is used for all kubectl commands
|
||||
- Cluster URL and context displayed for each config
|
||||
|
||||
**Auto-Detection**:
|
||||
Kubeconfig auto-detection from `~/.kube/config` is implemented but not enabled at startup due to AppHandle state access limitations. Users must manually upload kubeconfig files via the UI.
|
||||
|
||||
### Environment Isolation
|
||||
When kubectl commands execute:
|
||||
- `KUBECONFIG` environment variable set to active config path
|
||||
- Sensitive environment variables cleared (AWS credentials, etc.)
|
||||
- Working directory isolated if specified
|
||||
- 30-second timeout per command
|
||||
|
||||
## Command Execution Flow
|
||||
|
||||
### Full Execution Pipeline
|
||||
|
||||
1. **AI Tool Call**: AI invokes `execute_shell_command` tool with command text
|
||||
2. **PII Detection**: Command text scanned for sensitive data (passwords, tokens, API keys)
|
||||
3. **Audit Log (Pre-Execution)**: Command logged with hash chain before execution
|
||||
4. **Classification**: CommandClassifier analyzes command structure and assigns tier
|
||||
5. **Tier Decision**:
|
||||
- **Tier 1**: Proceed directly to execution
|
||||
- **Tier 2**: Emit `shell:approval-needed` event, wait for user response
|
||||
- **Tier 3**: Return error immediately with reasoning
|
||||
6. **Execution** (if approved):
|
||||
- For kubectl: Use `execute_kubectl()` with active kubeconfig
|
||||
- For general: Use `tokio::process::Command` with 30s timeout
|
||||
7. **Result Capture**: Capture exit code, stdout, stderr, execution time
|
||||
8. **Database Record**: Store execution in `command_executions` table
|
||||
9. **Audit Log (Post-Execution)**: Log result with exit code
|
||||
10. **Return to AI**: Format output as text for AI analysis
|
||||
|
||||
### Error Handling
|
||||
- **Timeout**: 30s command timeout, returns timeout error
|
||||
- **Approval Timeout**: 60s approval timeout, command denied
|
||||
- **Execution Failure**: Exit code != 0, stderr captured and returned
|
||||
- **Classification Error**: Unparseable command, denied with reasoning
|
||||
- **PII Detected**: Warning logged but execution continues (non-blocking)
|
||||
|
||||
## Audit Trail
|
||||
|
||||
All command executions are recorded in the `command_executions` table:
|
||||
|
||||
**Fields**:
|
||||
- `id`: Unique UUID
|
||||
- `command`: Full command text
|
||||
- `tier`: Safety tier (1, 2, or 3)
|
||||
- `approval_status`: "auto", "approved", or "denied"
|
||||
- `kubeconfig_id`: Reference to active kubeconfig (if kubectl)
|
||||
- `exit_code`: Command exit code
|
||||
- `stdout`: Command output
|
||||
- `stderr`: Error output
|
||||
- `execution_time_ms`: Execution duration
|
||||
- `executed_at`: Timestamp
|
||||
|
||||
**Audit Logging**:
|
||||
All executions are also written to the audit log (`audit_events` table) with:
|
||||
- Event type: `shell_command_execution`
|
||||
- Entity type: `shell_command`
|
||||
- Entity ID: Command text
|
||||
- Details JSON: `{"command": "...", "exit_code": 0}`
|
||||
- Hash chain linkage for tamper detection
|
||||
|
||||
**Viewing History**:
|
||||
Navigate to **Settings → Shell Execution** to view recent command executions:
|
||||
- Last 10 commands displayed
|
||||
- Tier badge and approval status
|
||||
- Exit code (green for 0, red for non-zero)
|
||||
- Execution time
|
||||
- Timestamp
|
||||
- Collapsible stdout output
|
||||
|
||||
## Security Controls
|
||||
|
||||
### Encryption
|
||||
- **Kubeconfig Files**: AES-256-GCM encryption at rest
|
||||
- **Encryption Key**: Derived from `TFTSR_ENCRYPTION_KEY` environment variable
|
||||
- **Nonce**: Random 12-byte nonce per encryption operation
|
||||
- **Authentication Tag**: 16-byte tag for integrity verification
|
||||
|
||||
### PII Detection
|
||||
Before execution, commands are scanned for:
|
||||
- Passwords (e.g., `--password=secret`)
|
||||
- API keys (patterns like `AKIAIOSFODNN7EXAMPLE`)
|
||||
- Tokens (e.g., `token=abc123`)
|
||||
- SSH keys (private key patterns)
|
||||
|
||||
If PII is detected:
|
||||
- Warning logged with span count
|
||||
- Execution continues (non-blocking)
|
||||
- Consider sanitizing command history in future enhancement
|
||||
|
||||
### Command Injection Prevention
|
||||
- No shell interpretation of user-provided arguments
|
||||
- Arguments passed directly to `tokio::process::Command`
|
||||
- kubectl arguments parsed from command string, not shell-interpreted
|
||||
|
||||
### Timeout Protection
|
||||
- **Command Timeout**: 30 seconds per command
|
||||
- **Approval Timeout**: 60 seconds for user response
|
||||
- Prevents indefinite hangs or runaway processes
|
||||
|
||||
### Hash-Chained Audit Log
|
||||
All executions recorded in audit log with:
|
||||
- Previous event hash
|
||||
- Current event data hash
|
||||
- Timestamp
|
||||
- Tamper detection via hash verification
|
||||
|
||||
## Settings
|
||||
|
||||
### Shell Execution Settings
|
||||
**Location**: Settings → Shell Execution
|
||||
|
||||
**Features**:
|
||||
- kubectl installation status and version display
|
||||
- Link to Kubeconfig Manager
|
||||
- Three-tier safety architecture visualization
|
||||
- Recent command execution history (last 10)
|
||||
|
||||
### Kubeconfig Manager
|
||||
**Location**: Settings → Kubeconfig
|
||||
|
||||
**Features**:
|
||||
- Upload kubeconfig files (.yaml, .yml)
|
||||
- List all uploaded configs with context and cluster URL
|
||||
- Activate/deactivate configs
|
||||
- Delete configs with confirmation
|
||||
- Preview uploaded file content (first 500 chars)
|
||||
|
||||
## API Reference
|
||||
|
||||
### Backend Commands
|
||||
|
||||
#### `upload_kubeconfig`
|
||||
Upload and encrypt a kubeconfig file.
|
||||
|
||||
**Parameters**:
|
||||
- `name: String` - Friendly name for the config
|
||||
- `content: String` - Full kubeconfig YAML content
|
||||
|
||||
**Returns**: `Result<String, String>` - Config ID on success
|
||||
|
||||
#### `list_kubeconfigs`
|
||||
List all uploaded kubeconfig files.
|
||||
|
||||
**Returns**: `Result<Vec<KubeconfigInfo>, String>`
|
||||
|
||||
**KubeconfigInfo**:
|
||||
```rust
|
||||
pub struct KubeconfigInfo {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub context: String,
|
||||
pub cluster_url: Option<String>,
|
||||
pub is_active: bool,
|
||||
}
|
||||
```
|
||||
|
||||
#### `activate_kubeconfig`
|
||||
Set a kubeconfig as active.
|
||||
|
||||
**Parameters**:
|
||||
- `id: String` - Config ID to activate
|
||||
|
||||
**Returns**: `Result<(), String>`
|
||||
|
||||
#### `delete_kubeconfig`
|
||||
Delete a kubeconfig file.
|
||||
|
||||
**Parameters**:
|
||||
- `id: String` - Config ID to delete
|
||||
|
||||
**Returns**: `Result<(), String>`
|
||||
|
||||
#### `respond_to_shell_approval`
|
||||
Respond to a shell command approval request.
|
||||
|
||||
**Parameters**:
|
||||
- `approval_id: String` - Unique approval request ID
|
||||
- `decision: String` - "deny", "allow_once", or "allow_session"
|
||||
|
||||
**Returns**: `Result<(), String>`
|
||||
|
||||
#### `list_command_executions`
|
||||
List recent command executions.
|
||||
|
||||
**Parameters**:
|
||||
- `issue_id: Option<String>` - Filter by issue ID (optional)
|
||||
|
||||
**Returns**: `Result<Vec<CommandExecution>, String>`
|
||||
|
||||
**CommandExecution**:
|
||||
```rust
|
||||
pub struct CommandExecution {
|
||||
pub id: String,
|
||||
pub command: String,
|
||||
pub tier: i32,
|
||||
pub approval_status: String,
|
||||
pub exit_code: Option<i32>,
|
||||
pub stdout: Option<String>,
|
||||
pub stderr: Option<String>,
|
||||
pub execution_time_ms: Option<i64>,
|
||||
pub executed_at: String,
|
||||
}
|
||||
```
|
||||
|
||||
#### `check_kubectl_installed`
|
||||
Check if kubectl is installed and get version info.
|
||||
|
||||
**Returns**: `Result<KubectlStatus, String>`
|
||||
|
||||
**KubectlStatus**:
|
||||
```rust
|
||||
pub struct KubectlStatus {
|
||||
pub installed: bool,
|
||||
pub path: Option<String>,
|
||||
pub version: Option<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### AI Tool: `execute_shell_command`
|
||||
|
||||
**Description**: Execute shell commands with automatic safety classification.
|
||||
|
||||
**Parameters**:
|
||||
- `command: String` (required) - Shell command to execute
|
||||
- `working_directory: String` (optional) - Working directory for execution
|
||||
- `kubeconfig_id: String` (optional) - Kubeconfig file ID for kubectl commands
|
||||
|
||||
**Returns**: String with formatted output:
|
||||
```
|
||||
Exit Code: 0
|
||||
|
||||
Stdout:
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-5d5f4c7d9-abcde 1/1 Running 0 5m
|
||||
|
||||
Stderr:
|
||||
```
|
||||
|
||||
**Usage in AI Context**:
|
||||
```typescript
|
||||
{
|
||||
"name": "execute_shell_command",
|
||||
"arguments": {
|
||||
"command": "kubectl get pods -n production",
|
||||
"kubeconfig_id": "uuid-of-active-config"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
### `shell_commands` (Migration 024)
|
||||
Pre-defined command templates with tier classification.
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS shell_commands (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_template TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL CHECK(tier IN (1, 2, 3)),
|
||||
description TEXT,
|
||||
category TEXT NOT NULL, -- 'kubectl', 'proxmox', 'general'
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
```
|
||||
|
||||
### `kubeconfig_files` (Migration 025)
|
||||
Encrypted kubeconfig storage.
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS kubeconfig_files (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
encrypted_content TEXT NOT NULL,
|
||||
context TEXT NOT NULL,
|
||||
cluster_url TEXT,
|
||||
is_active INTEGER NOT NULL DEFAULT 0,
|
||||
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_kubeconfig_active ON kubeconfig_files(is_active);
|
||||
```
|
||||
|
||||
### `command_executions` (Migration 026)
|
||||
Full audit trail of all command executions.
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS command_executions (
|
||||
id TEXT PRIMARY KEY,
|
||||
issue_id TEXT,
|
||||
command TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL,
|
||||
approval_status TEXT NOT NULL, -- 'auto', 'approved', 'denied'
|
||||
kubeconfig_id TEXT,
|
||||
exit_code INTEGER,
|
||||
stdout TEXT,
|
||||
stderr TEXT,
|
||||
execution_time_ms INTEGER,
|
||||
executed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (kubeconfig_id) REFERENCES kubeconfig_files(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_command_executions_issue ON command_executions(issue_id);
|
||||
CREATE INDEX idx_command_executions_executed ON command_executions(executed_at);
|
||||
```
|
||||
|
||||
### `approval_decisions` (Migration 027)
|
||||
Session-based approval preferences.
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS approval_decisions (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_pattern TEXT NOT NULL,
|
||||
decision TEXT NOT NULL CHECK(decision IN ('allow_once', 'allow_session', 'deny')),
|
||||
session_id TEXT,
|
||||
decided_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
expires_at TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_approval_decisions_session ON approval_decisions(session_id);
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Backend Tests
|
||||
**Location**: `src-tauri/src/shell/`
|
||||
|
||||
**Classifier Tests** (`classifier.rs`):
|
||||
- `test_tier1_kubectl_get` - Auto-execute kubectl get
|
||||
- `test_tier2_kubectl_delete` - Require approval for kubectl delete
|
||||
- `test_tier3_rm_rf` - Deny rm -rf
|
||||
- `test_pipe_tier_escalation` - Piped command tier analysis
|
||||
- 19 total tests covering all tier classifications
|
||||
|
||||
**kubectl Tests** (`kubectl.rs`):
|
||||
- `test_locate_kubectl_finds_binary` - Binary location logic
|
||||
- `test_kubectl_version_check` - Verify binary works
|
||||
- `test_execute_kubectl_with_timeout` - Timeout implementation
|
||||
- 3 total tests
|
||||
|
||||
**Executor Tests** (`executor.rs`):
|
||||
- Currently ignored (require full app setup)
|
||||
- Placeholder tests for approval flow
|
||||
|
||||
**Coverage**:
|
||||
- Classifier: 100% (critical safety component)
|
||||
- kubectl: 90%
|
||||
- Executor: Needs integration test environment
|
||||
|
||||
### Frontend Tests
|
||||
**Location**: `src/components/__tests__/`, `src/pages/__tests__/`
|
||||
|
||||
**Component Tests**:
|
||||
- ShellApprovalModal: Event listener, modal rendering, button actions
|
||||
- All existing tests passing (103 total)
|
||||
|
||||
### Integration Testing
|
||||
|
||||
**Manual Test Cases**:
|
||||
|
||||
1. **Tier 1 Auto-Execution**
|
||||
- AI request: "Show me all pods in the default namespace"
|
||||
- Expected: Command executes immediately without modal
|
||||
- Verify: `command_executions` has `approval_status='auto'`
|
||||
|
||||
2. **Tier 2 Approval Flow**
|
||||
- AI request: "Scale the nginx deployment to 5 replicas"
|
||||
- Expected: Approval modal appears
|
||||
- Test: Deny → execution blocked
|
||||
- Test: Allow Once → execution proceeds
|
||||
- Test: Allow for Session → execution proceeds
|
||||
|
||||
3. **Tier 3 Denial**
|
||||
- AI request: "Delete all files in /tmp"
|
||||
- Expected: No modal, immediate error with reasoning
|
||||
- Verify: Command not executed
|
||||
|
||||
4. **Piped Command Analysis**
|
||||
- Command: `kubectl get pods | grep nginx` → Tier 1 (auto-execute)
|
||||
- Command: `kubectl get pods | kubectl delete -f -` → Tier 2 (approval)
|
||||
- Command: `cat /tmp/list.txt | xargs rm -rf` → Tier 3 (deny)
|
||||
|
||||
5. **Timeout Protection**
|
||||
- Command: `sleep 60` → Times out after 30s
|
||||
- Approval: Wait 61s → Approval times out, command denied
|
||||
|
||||
6. **Audit Trail**
|
||||
- Query: `SELECT * FROM command_executions ORDER BY executed_at DESC`
|
||||
- Verify: All commands logged with correct tier, status, exit code
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### kubectl not found
|
||||
**Problem**: "kubectl is not installed" message in Shell Execution settings
|
||||
|
||||
**Solutions**:
|
||||
1. Check if kubectl is bundled: Binary should be at `Resources/kubectl` (macOS) or similar platform path
|
||||
2. Verify PATH: Ensure system PATH includes kubectl location
|
||||
3. Reinstall: Download latest application bundle with kubectl included
|
||||
|
||||
### Kubeconfig upload fails
|
||||
**Problem**: "Failed to parse kubeconfig" error
|
||||
|
||||
**Solutions**:
|
||||
1. Validate YAML: Ensure kubeconfig is valid YAML format
|
||||
2. Check contexts: Kubeconfig must have at least one context defined
|
||||
3. Cluster URL: Ensure cluster URL is accessible
|
||||
4. File format: Only .yaml or .yml files accepted
|
||||
|
||||
### Commands not executing
|
||||
**Problem**: Commands hang or don't execute
|
||||
|
||||
**Solutions**:
|
||||
1. Check timeout: Commands timeout after 30 seconds
|
||||
2. Approval timeout: User must respond within 60 seconds for Tier 2
|
||||
3. Active kubeconfig: Ensure a kubeconfig is activated for kubectl commands
|
||||
4. Review logs: Check audit log for denial reason
|
||||
|
||||
### Approval modal not appearing
|
||||
**Problem**: Tier 2 command doesn't show approval modal
|
||||
|
||||
**Solutions**:
|
||||
1. Check browser: Ensure JavaScript is enabled
|
||||
2. Event listener: Modal listens for `shell:approval-needed` event
|
||||
3. Tauri events: Verify Tauri event system is working
|
||||
4. Console errors: Check browser console for errors
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
**Planned Features**:
|
||||
- Session-based approval preferences (approve all kubectl get for 1 hour)
|
||||
- Command templating (save frequently used commands)
|
||||
- Execution rollback (undo kubectl apply operations)
|
||||
- Tier overrides (admin can override tier classification)
|
||||
- Command history search and filtering
|
||||
- Export execution history as CSV/JSON
|
||||
- Integration with issue timeline (show commands executed during incident)
|
||||
- Proxmox advanced commands (cluster management, backups)
|
||||
- Multi-kubeconfig context switching within single file
|
||||
- Auto-detection of ~/.kube/config on startup (pending AppHandle fix)
|
||||
|
||||
**Stretch Goals**:
|
||||
- Parallel command execution (run multiple commands concurrently)
|
||||
- Command scheduling (execute command at specific time)
|
||||
- Command chaining with dependencies (run X, then Y if X succeeds)
|
||||
- Command output parsing (extract structured data from stdout)
|
||||
- Integration with monitoring systems (auto-execute commands on alerts)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [[Architecture]] - Overall application architecture
|
||||
- [[Security-Model]] - Security architecture and threat model
|
||||
- [[Database]] - Database schema and migrations
|
||||
- [[IPC-Commands]] - Frontend-backend communication
|
||||
- [[AI-Providers]] - AI integration and tool use
|
||||
|
||||
## Version History
|
||||
|
||||
- **v1.0.0** (2026-06-02): Initial release with three-tier safety classification, kubectl bundling, and multi-cluster support
|
||||
Loading…
Reference in New Issue
Block a user