sensor-tasking
Send tasks (commands) to EDR sensors to gather data or take action. Handles offline agents via reliable-tasking, collects responses via LCQL queries, and creates D&R rules for automated response handling. Use for live response, data collection, forensic acquisition, or fleet-wide operations like "get OS version from all Windows servers" or "isolate all hosts with tag X".
SKILL.md
| Name | sensor-tasking |
| Description | Send tasks (commands) to EDR sensors to gather data or take action. Handles offline agents via reliable-tasking, collects responses via LCQL queries, and creates D&R rules for automated response handling. Use for live response, data collection, forensic acquisition, or fleet-wide operations like "get OS version from all Windows servers" or "isolate all hosts with tag X". |
name: sensor-tasking description: Send tasks (commands) to EDR sensors to gather data or take action. Handles offline agents via reliable-tasking, collects responses via LCQL queries, and creates D&R rules for automated response handling. Use for live response, data collection, forensic acquisition, or fleet-wide operations like "get OS version from all Windows servers" or "isolate all hosts with tag X". allowed-tools:
- Task
- Read
- Bash
- Skill
Sensor Tasking - Query and Command EDR Agents
This skill orchestrates sending tasks (commands) to EDR sensors and handling responses. It solves two key challenges of sensor tasking:
- Offline agents: Sensors may be offline when you want to task them
- Response collection: Some tasks generate data that needs to be collected
LimaCharlie Integration
Prerequisites: Run
/init-lcto initialize LimaCharlie context.
LimaCharlie CLI Access
All LimaCharlie operations use the limacharlie CLI directly:
limacharlie <noun> <verb> --oid <oid> --output yaml [flags]
For command help and discovery: limacharlie <command> --ai-help
Critical Rules
| Rule | Wrong | Right |
|---|---|---|
| CLI Access | Call MCP tools or spawn api-executor | Use Bash("limacharlie ...") directly |
| Output Format | --output json | --output yaml (more token-efficient) |
| Filter Output | Pipe to jq/yq | Use --filter JMESPATH to select fields |
| LCQL Queries | Write query syntax manually | Use limacharlie ai generate-query first |
| Timestamps | Calculate epoch values | Use date +%s or date -d '7 days ago' +%s |
| OID | Use org name | Use UUID (call limacharlie org list if needed) |
When to Use
Use this skill when the user wants to:
- Live Response: Query running processes, network connections, registry keys, services
- Forensic Collection: Collect memory maps, file listings, autoruns, packages
- Fleet Operations: Execute commands across many sensors (by tag, platform, etc.)
- Incident Response: Isolate hosts, kill processes, gather evidence
- Data Collection at Scale: Get OS versions, installed software, users across fleet
Example requests:
- "Get running processes from sensor X"
- "List all files in C:\Windows\Temp on compromised hosts"
- "Get OS version from all Windows servers when they come online"
- "Run a memory collection on all hosts tagged 'incident-response'"
- "Execute netstat on all online Linux servers"
Core Concepts
Challenge 1: Offline Agents
Direct tasking (get_processes, dir_list, etc.) only works for online sensors. If a sensor is offline, the task fails immediately.
Reliable tasking queues tasks for delivery when sensors come online. Tasks persist for a configurable TTL (default: 1 week).
| Approach | Use When | Pros | Cons |
|---|---|---|---|
| Direct Task | ≤5 online sensors, need immediate response | Fast, response inline | Fails if offline |
| Reliable Task | >5 sensors, offline sensors, or can wait | Guaranteed delivery | Response via telemetry |
Challenge 2: Receiving Responses
| Method | Use When | How It Works |
|---|---|---|
| Inline Response | Direct tasking small numbers | Response returned directly from API |
| LCQL Query | Need to collect reliable task responses | Query for routing/investigation_id containing your context |
| D&R Rule | Need automated action on responses | Create rule matching investigation_id, with response actions |
Decision Tree
START: User wants to task sensors
|
v
Are all targets online AND ≤5 sensors?
|
|--YES--> Use Direct Tasking (inline response, parallel execution)
|
|--NO--> Use Reliable Tasking (>5 sensors OR any offline)
|
v
Do you need the response data?
|
|--NO (action-only like isolate)--> Create Reliable Task, done
|
|--YES--> Do you need automated handling?
|
|--NO--> Create Reliable Task, wait 2+ min, then LCQL query
|
|--YES--> 1. Create D&R rule with TTL FIRST
2. THEN create Reliable Task
(rule must exist before task to avoid missing responses)
How to Use
Step 1: Understand the Request
Parse the user's request to determine:
- Target scope: Single sensor, selector, all sensors?
- Task type: Data collection (needs response) or action (unidirectional)?
- Urgency: Need immediate response or can wait?
- Response handling: Inline, LCQL collection, or automated D&R?
Step 2: Get Organization and Sensors
If you don't have the OID, get it first:
limacharlie org list --output yaml
Check sensor status if targeting specific sensors:
limacharlie sensor get --sid <sid> --oid <oid> --output yaml
CRITICAL: Filter to Taskable EDR Sensors
Before spawning executor agents or tasking sensors, you MUST verify sensors are EDR agents (not adapters or cloud sensors). Non-EDR sensors will fail with
UNSUPPORTED_FOR_PLATFORM.Taskable sensors require BOTH:
- Platform:
windows,linux,macos, orchrome- Architecture: NOT
usp_adapter(code 9)A sensor running on Linux platform but with
arch=usp_adapteris an adapter (USP), not an EDR agent. These adapters forward logs but cannot execute commands.Use combined selector when listing sensors:
limacharlie sensor list --selector "(plat==windows or plat==linux or plat==macos) and arch!=usp_adapter" --online --oid <oid> --output yamlOr check sensor info before tasking - verify both
platformis in["windows", "linux", "macos", "chrome"]ANDarchis not9/usp_adapter.
Step 3A: Direct Tasking (≤5 Online Sensors)
For immediate data collection from a small number of online sensors (up to 5), use direct tasking functions with parallel execution.
Available Direct Task Commands (return response inline via limacharlie task send --sid <sid> --task <command>):
| Task Command | Description | Common Use |
|---|---|---|
os_processes | Running processes | Process investigation |
os_kill_process | Kill a process | Incident response |
os_modules --pid [pid] | Loaded modules | Malware analysis |
netstat | Active connections | C2 hunting |
os_version | OS details | Asset inventory |
os_users | System users | Account enumeration |
os_services | Windows services | Persistence check |
os_drivers | Loaded drivers | Rootkit detection |
os_autoruns | Persistence mechanisms | Malware persistence |
os_packages | Installed packages | Software inventory |
reg_list [path] | Registry values | Config/persistence |
dir_list [path] | Directory listing | File investigation |
find_strings | String search | Memory forensics |
yara_scan --pid [pid] | YARA scan process | Malware detection |
yara_scan --filePath [path] | YARA scan file | File analysis |
yara_scan --dirPath [path] | YARA scan directory | Bulk scanning |
Example - Get processes from a sensor:
limacharlie task send --sid <sid> --task os_processes --oid <oid> --output yaml
Step 3B: Reliable Tasking (>5 Sensors or Offline)
For more than 5 sensors, offline sensors, or fleet-wide operations, use reliable tasking.
IMPORTANT: Order of Operations
If you need automated response handling via D&R rules, you MUST create the D&R rule FIRST, before creating the reliable task. This ensures no responses are missed between task creation and rule deployment.
Order: D&R Rule → Reliable Task (not the other way around)
Create a reliable task:
# reliable-send is per-sensor; first list matching sensors, then loop
limacharlie sensor list --selector 'plat==windows' --oid <oid> --filter '[].sid' --output yaml
for sid in <sid-list>; do
limacharlie task reliable-send --sid $sid --command 'os_version' --investigation-id 'fleet-inventory-2024-01' --ttl 86400 --oid <oid> --output yaml
done
Key Parameters:
--sid: Target sensor ID (reliable-send operates per-sensor)--command: The command to execute (e.g.,os_version,mem_map --pid 4,run --shell-command whoami)--investigation-id: Identifier that appears inrouting/investigation_idof responses (for collection)--ttl: Time-to-live in seconds (default: 604800 = 1 week)
Available Task Commands:
Any sensor command can be used as a task. Common ones:
| Task Command | Description |
|---|---|
os_version | Get OS details |
mem_map --pid [pid] | Memory map of process |
mem_strings --pid [pid] | Strings from process memory |
file_get [path] | Get file contents |
dir_list [path] | List directory |
netstat | Network connections |
run --shell-command [cmd] | Execute shell command |
deny_tree -p [process] | Kill process tree |
isolate_network | Network isolation |
rejoin_network | End network isolation |
Step 4: Collecting Responses
Option A: LCQL Query (Manual Collection)
After reliable tasking, wait at least 2 minutes for responses to arrive, then query:
First, generate the LCQL query:
limacharlie ai generate-query --prompt "Find all events in the last 2 hours where investigation_id contains 'fleet-inventory-2024-01'" --oid <oid> --output yaml
Then run the query:
limacharlie search run --query "<generated_query>" --start <ts> --end <ts> --oid <oid> --output yaml
Option B: D&R Rule (Automated Handling)
For automated response handling, create a D&R rule that matches the investigation_id.
CRITICAL: Create the D&R rule BEFORE creating the reliable task. Online sensors may respond within milliseconds - if the rule doesn't exist yet, those responses will be missed.
Step 1: Generate the detection:
limacharlie ai generate-detection --description "Match events where investigation_id contains 'fleet-inventory-2024-01'" --oid <oid> --output yaml
Step 2: Generate the response:
limacharlie ai generate-response --description "Report to output 'siem' and add detection 'FLEET_INVENTORY_RESPONSE'" --oid <oid> --output yaml
Step 3: Write to temp files and validate:
cat > /tmp/detect.yaml << 'EOF'
<detection_yaml>
EOF
cat > /tmp/respond.yaml << 'EOF'
<response_yaml>
EOF
limacharlie dr validate --detect /tmp/detect.yaml --respond /tmp/respond.yaml --oid <oid>
Step 4: Deploy with expiry:
Calculate expiry timestamp (e.g., 7 days from now):
date -d '+7 days' +%s
cat > /tmp/rule.yaml << 'EOF'
detect:
<detection_yaml>
respond:
<response_yaml>
EOF
limacharlie dr set --key temp-fleet-inventory-handler --input-file /tmp/rule.yaml --oid <oid>
Step 5: NOW create the reliable task
Only after the D&R rule is deployed, create the reliable task (see Step 3B above). The rule will catch all responses as sensors execute the task.
Monitoring Reliable Tasks
List pending tasks for a sensor:
limacharlie task reliable-list --sid <sensor-id> --oid <oid> --output yaml
Delete/cancel a task:
limacharlie task reliable-delete --sid <sensor-id> --task-id <task_id> --oid <oid>
Example Workflows
Example 1: Get Processes from Single Sensor
User: "Get running processes from sensor abc-123"
# Check sensor status
limacharlie sensor get --sid abc-123 --oid c7e8f940-... --output yaml
# If online, get processes directly
limacharlie task send --sid abc-123 --task os_processes --oid c7e8f940-... --output yaml
Example 2: Fleet-Wide OS Inventory
User: "Get OS version from all Windows servers when they come online"
# List Windows sensors first
limacharlie sensor list --selector 'plat == windows' --oid c7e8f940-... --filter '[].sid' --output yaml
# Create reliable task per sensor (loop over SIDs)
for sid in <sid-list>; do
limacharlie task reliable-send --sid $sid --command 'os_version' --investigation-id 'os-inventory-20240120' --oid c7e8f940-... --output yaml
done
Response to user: "Created reliable tasks to collect OS version from all Windows sensors.
- Online sensors will execute immediately
- Offline sensors will execute when they reconnect
- Task will remain active for 1 week (default TTL)
- Use investigation ID 'os-inventory-20240120' to query responses via LCQL"
Example 3: Incident Response Collection
User: "Run memory collection on all hosts tagged 'incident-response', I need the data sent to our SIEM"
# Step 1: Create D&R rule FIRST to forward responses to SIEM
# Use AI generation for the detection and response, then deploy:
limacharlie ai generate-detection --description "Match events where investigation_id contains 'ir-memcollect-001'" --oid c7e8f940-... --output yaml
limacharlie ai generate-response --description "Report to output 'siem' and add detection 'IR_MEMCOLLECT_RESPONSE'" --oid c7e8f940-... --output yaml
# Write generated YAML to files, validate, then deploy:
limacharlie dr validate --detect /tmp/detect.yaml --respond /tmp/respond.yaml --oid c7e8f940-... --output yaml
# Combine into single rule file with detect/respond keys, then set:
limacharlie dr set --key temp-ir-memcollect-handler --input-file /tmp/ir-rule.yaml --oid c7e8f940-...
# Step 2: Get sensors tagged 'incident-response'
limacharlie sensor list --tag incident-response --oid c7e8f940-... --filter '[].sid' --output yaml
# Step 3: THEN create reliable task per sensor (rule is now in place to catch responses)
for sid in <sid-list>; do
limacharlie task reliable-send \
--sid $sid \
--command 'mem_map --pid 4' \
--investigation-id 'ir-memcollect-001' \
--ttl 172800 \
--oid c7e8f940-... --output yaml
done
Example 4: Quick Data Collection with Inline Response
User: "What's the OS version on all 5 of our production Linux servers?"
If sensors are online and small in number, parallel direct tasking is faster:
# Run parallel tasks for each sensor
limacharlie task send --sid sid1 --task os_version --oid <oid> --output yaml &
limacharlie task send --sid sid2 --task os_version --oid <oid> --output yaml &
limacharlie task send --sid sid3 --task os_version --oid <oid> --output yaml &
limacharlie task send --sid sid4 --task os_version --oid <oid> --output yaml &
limacharlie task send --sid sid5 --task os_version --oid <oid> --output yaml &
wait
Important Notes
Taskable Sensors (EDR Only)
WARNING: Sensor tasking only works for EDR agents (real endpoint agents). Cloud sensors, adapters, and USP log sources cannot receive tasks.
Taskable sensors require BOTH conditions:
- Platform is Windows, Linux, macOS, or Chrome
- Architecture is NOT
usp_adapter(code 9)
Platforms that support tasking:
| Platform | Platform ID (hex) | Platform ID (decimal) | Selector |
|---|---|---|---|
| Windows | 0x10000000 | 268435456 | plat==windows |
| Linux | 0x20000000 | 536870912 | plat==linux |
| macOS | 0x30000000 | 805306368 | plat==macos |
| Chrome | Architecture 0x00000006 | 6 | arch==chromium |
Non-taskable sensors include:
- Cloud sensors (Office365, Okta, AWS, GCP, Azure, etc.)
- External adapters (
ext-*sensors like ext-zeek, ext-strelka) - USP log sources (Syslog, S3 buckets, webhooks)
- Any sensor with
arch=usp_adapter(architecture code 9) - even if platform is Linux/macOS
These sensors will return UNSUPPORTED_FOR_PLATFORM errors when tasked.
Recommendation: When tasking a fleet, filter by both platform AND architecture:
- Use combined selector:
(plat==windows or plat==linux or plat==macos) and arch!=usp_adapter - Or check sensor info for both
platformandarchfields before direct tasking
Extension Requirement
Reliable tasking requires the ext-reliable-tasking extension to be subscribed in the organization. If you get a 403 error, the extension may not be enabled.
Selector Syntax
Selectors use bexpr syntax:
plat==windows- Windows sensorsplat==linux- Linux sensorsproduction in tags- Sensors with 'production' taghostname matches '^web-'- Hostname starts with 'web-'sid=='abc-123-def-456'- Specific sensor*- All sensors
Context for Response Collection
The context parameter in reliable tasking:
- Appears in
routing/investigation_idof response events - Use unique identifiers (include date/time)
- Can be used in LCQL queries or D&R rules for matching
Timestamps
When setting TTL or expiry:
- Use bash for timestamp calculation:
date -d '+7 days' +%s - TTL is in seconds from now
- D&R rule expiry is absolute Unix timestamp
Related Skills
detection-engineering- For creating D&R rules to handle responsessensor-health- For checking sensor online status across fleetsensor-coverage- For understanding fleet coverage before tasking
Reference
- ext-reliable-tasking documentation
- Use
limacharlie task --ai-helpfor CLI help