English | δΈζ
Flashduty Runner is a lightweight, secure agent that runs in your environment to execute commands and access resources on behalf of Flashduty AI SRE platform.
ββββββββββββββββββββ WebSocket (TLS) ββββββββββββββββββββββ
β Flashduty AI β βββββββββββββββββββββββββββΊ β Flashduty Runner β
β SRE Platform β β (Your Server) β
ββββββββββββββββββββ ββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββ
β β’ Execute Commands β
β β’ Read/Write Files β
β β’ MCP Tool Calls β
ββββββββββββββββββββββ
The runner establishes a persistent WebSocket connection to Flashduty cloud, receives task requests, executes them locally, and returns results.
All code is open source - you can audit every line of code to verify exactly what the runner does.
| Layer | Protection |
|---|---|
| Transport | TLS-encrypted WebSocket, API Key authentication |
| Command Execution | Shell parsing to prevent injection attacks (e.g., cmd1; cmd2) |
| Permission Control | Configurable glob-based command whitelist/blacklist |
| File System | Operations sandboxed to workspace root, symlink escape protection |
The runner uses glob pattern matching for command permissions. You have full control over what commands can be executed.
Only allow specific commands explicitly:
permission:
bash:
"*": "deny" # Deny all by default
"kubectl get *": "allow"
"kubectl describe *": "allow"
"kubectl logs *": "allow"
"cat *": "allow"
"ls *": "allow"If the runner is deployed in an isolated environment dedicated to AI operations, you can choose to trust the AI model's judgment:
permission:
bash:
"*": "allow" # Trust AI model
"rm -rf /": "deny" # Block catastrophic commands if desiredThis mode is suitable when:
- The runner runs in an isolated VM/container with limited blast radius
- You trust the AI model's capabilities and want maximum flexibility
- Quick incident response is more important than restrictive permissions
permission:
bash:
"*": "deny"
"cat *": "allow"
"head *": "allow"
"tail *": "allow"
"ls *": "allow"
"grep *": "allow"
"ps *": "allow"
"df *": "allow"
"free *": "allow"# Linux (amd64)
curl -LO https://github.com/flashcatcloud/flashduty-runner/releases/latest/download/flashduty-runner_Linux_x86_64.tar.gz
tar -xzf flashduty-runner_Linux_x86_64.tar.gz
sudo mv flashduty-runner /usr/local/bin/
# Linux (arm64)
curl -LO https://github.com/flashcatcloud/flashduty-runner/releases/latest/download/flashduty-runner_Linux_arm64.tar.gz
tar -xzf flashduty-runner_Linux_arm64.tar.gz
sudo mv flashduty-runner /usr/local/bin/
# macOS (Apple Silicon)
curl -LO https://github.com/flashcatcloud/flashduty-runner/releases/latest/download/flashduty-runner_Darwin_arm64.tar.gz
tar -xzf flashduty-runner_Darwin_arm64.tar.gz
sudo mv flashduty-runner /usr/local/bin/
# macOS (Intel)
curl -LO https://github.com/flashcatcloud/flashduty-runner/releases/latest/download/flashduty-runner_Darwin_x86_64.tar.gz
tar -xzf flashduty-runner_Darwin_x86_64.tar.gz
sudo mv flashduty-runner /usr/local/bin/docker run -d \
--name flashduty-runner \
-e FLASHDUTY_RUNNER_API_KEY=your_api_key \
-e FLASHDUTY_RUNNER_NAME=my-runner \
-v /var/flashduty/workspace:/workspace \
ghcr.io/flashcatcloud/flashduty-runner:latestCreate ~/.flashduty-runner/config.yaml:
# API Key from Flashduty Console (required)
api_key: "fk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Runner display name (optional, defaults to hostname)
name: "prod-k8s-runner"
# Labels for task routing (optional)
labels:
- k8s
- production
# Workspace root directory (optional)
workspace_root: "/var/flashduty/workspace"
# Command permissions (see Security section for options)
permission:
bash:
"*": "deny"
"kubectl get *": "allow"
"kubectl describe *": "allow"
"kubectl logs *": "allow"# Start the runner
flashduty-runner run
# Start with custom config
flashduty-runner run --config /path/to/config.yaml
# Check version
flashduty-runner versionCreate /etc/systemd/system/flashduty-runner.service:
[Unit]
Description=Flashduty Runner
After=network.target
[Service]
Type=simple
User=flashduty
ExecStart=/usr/local/bin/flashduty-runner run
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now flashduty-runner| Field | Required | Default | Description |
|---|---|---|---|
api_key |
Yes | - | Flashduty API Key |
api_url |
No | wss://api.flashcat.cloud/runner/ws |
WebSocket endpoint |
name |
No | hostname | Runner display name |
labels |
No | [] | Labels for task routing |
workspace_root |
No | ~/.flashduty-runner/workspace |
Workspace directory |
permission.bash |
No | deny all | Command permission rules |
log.level |
No | info |
Log level: debug, info, warn, error |
All options can be set via environment variables with FLASHDUTY_RUNNER_ prefix:
FLASHDUTY_RUNNER_API_KEY=fk_xxx
FLASHDUTY_RUNNER_NAME=my-runner
FLASHDUTY_RUNNER_WORKSPACE_ROOT=/workspaceThe runner automatically adds these labels for routing:
os:linux/os:darwin/os:windowsarch:amd64/arch:arm64hostname:<machine-hostname>
| Symptom | Cause | Solution |
|---|---|---|
failed to connect |
Network issue | Check firewall allows outbound port 443 |
authentication failed |
Invalid API Key | Verify API Key in Flashduty console |
| Runner not showing online | Connection dropped | Check logs, verify API Key matches account |
# Test connectivity
curl -v https://api.flashcat.cloud/health
# Check runner logs
journalctl -u flashduty-runner -f| Symptom | Cause | Solution |
|---|---|---|
command denied |
Command not in whitelist | Add pattern to permission.bash |
path escapes workspace |
Path traversal blocked | Use paths within workspace_root |
Permission Pattern Rules:
- Patterns are matched in order, last match wins
*matches any characters- Empty config defaults to deny all
Enable debug logging to see detailed permission decisions:
log:
level: "debug"We welcome contributions! Please see CONTRIBUTING.md.
Apache License 2.0 - see LICENSE.
Made with β€οΈ by Flashcat