f1ab5d90dc
CI / unit_tests (push) Waiting to run
CI / benchmark-publish (push) Waiting to run
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
CI / helm (push) Waiting to run
CI / status-check (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / security (push) Waiting to run
CI / quality (push) Waiting to run
CI / integration_tests (push) Waiting to run
CI / e2e_tests (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / benchmark-regression (push) Blocked by required conditions
- Promote [Unreleased] CHANGELOG entries to [3.8.0] (2026-04-05) - Add Shell Danger Detection section to docs/api/tui.md covering ShellDangerLevel, DangerousPattern, ShellSafetyService, and SafetyCheckResult with full API reference and usage examples - Add InvariantService section to docs/api/core.md documenting the new DI-registered singleton, its methods, and emitted events - Update docs/architecture.md Plan Lifecycle section to document invariant reconciliation as a phase transition gate - Update README.md Highlights with shell danger detection, inline permission questions, invariant reconciliation, UKO provenance tracking, and JSON-RPC 2.0 A2A wire format - Create docs/modules/shell-safety.md with full module guide covering purpose, key classes, built-in patterns, custom pattern registration, TUI integration, and testing guidance ISSUES CLOSED: #1003 #997 #1391 #1004 #891 #1501 #1577 #1941 #2334
155 lines
4.4 KiB
Markdown
155 lines
4.4 KiB
Markdown
# Shell Safety Module
|
|
|
|
**Package:** `cleveragents.tui.shell_safety`
|
|
|
|
The shell safety module protects users from accidentally executing dangerous
|
|
commands in the TUI shell mode (`!` prefix). It provides a configurable
|
|
pattern registry, a danger-level classification system, and an application
|
|
service that integrates with the TUI warning overlay.
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
When a user types `!<command>` in the TUI, the `ShellSafetyService` checks
|
|
the command against a registry of known-dangerous patterns before the
|
|
subprocess is spawned. Commands that match a pattern at or above the
|
|
configured `block_level` are blocked; commands below that level surface a
|
|
warning overlay that the user must acknowledge before proceeding.
|
|
|
|
---
|
|
|
|
## Key Classes
|
|
|
|
### `ShellDangerLevel`
|
|
|
|
Four-level `IntEnum` severity scale:
|
|
|
|
```
|
|
LOW (1) < MEDIUM (2) < HIGH (3) < CRITICAL (4)
|
|
```
|
|
|
|
Numeric comparisons work naturally: `level >= ShellDangerLevel.HIGH`.
|
|
|
|
### `DangerousPattern`
|
|
|
|
Immutable frozen dataclass describing a single dangerous pattern:
|
|
|
|
```python
|
|
DangerousPattern(
|
|
name="fork_bomb",
|
|
pattern=r":\(\)\s*\{",
|
|
level=ShellDangerLevel.CRITICAL,
|
|
description="Fork bomb — exhausts process table and crashes the system.",
|
|
)
|
|
```
|
|
|
|
### `DangerousPatternDetector`
|
|
|
|
Maintains the registry of `DangerousPattern` objects and provides
|
|
`check_first(command) → DangerousCommandWarning | None` to return the
|
|
highest-severity matching pattern.
|
|
|
|
### `ShellSafetyService`
|
|
|
|
High-level application service used by the TUI:
|
|
|
|
```python
|
|
from cleveragents.tui.shell_safety import ShellSafetyService, ShellDangerLevel
|
|
|
|
# Default: block MEDIUM and above automatically
|
|
service = ShellSafetyService()
|
|
|
|
# Custom: only block CRITICAL; show overlay for HIGH and below
|
|
service = ShellSafetyService(block_level=ShellDangerLevel.CRITICAL)
|
|
|
|
# Custom: delegate all decisions to a callback
|
|
def my_callback(warning):
|
|
# Return True to allow, False to block
|
|
return warning.danger_level < ShellDangerLevel.HIGH
|
|
|
|
service = ShellSafetyService(warn_callback=my_callback)
|
|
|
|
result = service.check_command("rm -rf /")
|
|
if not result.allowed:
|
|
print(f"Blocked: {result.warning.description}")
|
|
```
|
|
|
|
### `DangerousCommandWarning`
|
|
|
|
Value object returned when a dangerous pattern is matched:
|
|
|
|
| Attribute | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `command` | `str` | The original command text |
|
|
| `pattern` | `DangerousPattern` | The matched pattern |
|
|
| `danger_level` | `ShellDangerLevel` | Convenience alias for `pattern.level` |
|
|
| `message` | `str` | Human-readable warning message |
|
|
|
|
---
|
|
|
|
## Built-in Pattern Categories
|
|
|
|
| Category | Example patterns | Default level |
|
|
|----------|-----------------|---------------|
|
|
| Recursive deletion | `rm -rf /`, `rm -rf ~` | CRITICAL |
|
|
| Disk-level writes | `dd if=`, `mkfs`, `shred` | CRITICAL |
|
|
| Fork bombs | `:(){ :|:& };:` | CRITICAL |
|
|
| Privilege escalation | `sudo su`, `chmod 777 /` | HIGH |
|
|
| Network exfiltration | `curl \| sh`, `wget \| bash` | HIGH |
|
|
| Reverse shells | `nc -e /bin/sh`, `bash -i >& /dev/tcp` | HIGH |
|
|
| Dangerous redirects | `> /dev/sda`, `> /etc/passwd` | HIGH |
|
|
| Credential exposure | `env \| curl`, `cat ~/.ssh/id_rsa \| nc` | MEDIUM |
|
|
|
|
---
|
|
|
|
## Adding Custom Patterns
|
|
|
|
```python
|
|
from cleveragents.tui.shell_safety import (
|
|
DangerousPattern,
|
|
ShellDangerLevel,
|
|
ShellSafetyService,
|
|
)
|
|
|
|
custom = DangerousPattern(
|
|
name="drop_database",
|
|
pattern=r"DROP\s+DATABASE",
|
|
level=ShellDangerLevel.HIGH,
|
|
description="Drops an entire database — irreversible.",
|
|
case_sensitive=False,
|
|
)
|
|
|
|
service = ShellSafetyService(extra_patterns=[custom])
|
|
```
|
|
|
|
---
|
|
|
|
## Integration with the TUI
|
|
|
|
The TUI wires `ShellSafetyService` into the shell input handler. When
|
|
`check_command()` returns `allowed=False`, the TUI displays a
|
|
`DangerousCommandWarningOverlay` widget with the warning message and danger
|
|
level. The user must explicitly confirm before the command is executed.
|
|
|
|
For commands that are blocked outright (above `block_level` with no
|
|
callback), the overlay displays a non-dismissable error and the command is
|
|
never executed.
|
|
|
|
---
|
|
|
|
## Testing
|
|
|
|
The shell safety module is fully covered by BDD scenarios in
|
|
`features/shell_safety.feature`. All pattern matching is deterministic and
|
|
does not require a running TUI, making it straightforward to test in
|
|
isolation:
|
|
|
|
```python
|
|
from cleveragents.tui.shell_safety import ShellSafetyService
|
|
|
|
service = ShellSafetyService()
|
|
assert not service.is_safe("rm -rf /")
|
|
assert service.is_safe("ls -la")
|
|
```
|