3 Shell Execution
Gitea Actions edited this page 2026-06-11 01:37:17 +00:00

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

# 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

# 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:

# 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 TRCAA_ENCRYPTION_KEY (or legacy TRCAA_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:

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:

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:

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:

{
  "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.

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.

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.

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.

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)

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)

Version History

  • v1.1.0 (2026-06-06): Production-ready with three-tier safety classification, kubectl bundling, and multi-cluster support
  • v1.0.0 (2026-06-02): Initial release with three-tier safety classification, kubectl bundling, and multi-cluster support