Skip to main content

Elastic Defend Operations - Response Actions CLI for Elastic Endpoint Security XDR

Project description

edops logo

edops

PyPI version Python 3.10+ Elastic 8.x Elastic 9.x License: MIT

Elastic Defend Operations - command-line interface for Elastic Endpoint Security / Elastic Defend response actions. Isolate hosts, kill processes, retrieve files, execute commands, run osquery queries, investigate alerts, inspect session views, and run a semi-interactive shell — all from the terminal, directly against the Kibana response actions API.

Built and tested on Elastic Stack 9.3.3, but most of it should work on 8.19.+ also.


Demo

edops demo

Generate your own: install VHS, set EDOPS_KIBANA_URL and EDOPS_KIBANA_API_KEY, then run vhs docs/tapes/demo-main.tape. See docs/tapes/ for tapes covering individual features.


Features

  • Response actions — isolate, unisolate, kill/suspend processes, get files, execute commands, upload files, scan, memory dump
  • osquery — run live queries, fetch results, list saved queries
  • Session View — render the process tree and terminal I/O captured by Elastic for any detection alert
  • Fleet agents — list enrolled agents, filter by hostname prefix, IP, or MAC address
  • Interactive console — endpoint-scoped console with tab-completion for all commands
  • Semi-interactive shell — execute actions wrapped as a remote shell session (stdout/stderr rendered locally)
  • Alerts — query Elastic Security detection alerts, globally or per endpoint
  • JSON output on every command for scripting and piping
  • Comment/ticket traceability — stamp every API call with a ticket reference
  • Flexible auth — API key or username/password; config file, .env, environment variables, or global CLI flags per invocation

Target Audience

SOC analysts, blue teams, and incident responders.
Applicability beyond that is neither the goal nor the focus.

This CLI is built to interact with Elastic Kibana, Fleet, Elastic Agent and Elastic Endpoint Security (XDR) for endpoint visibility and response actions.


Requirements

  • Python 3.10+
  • Elastic Stack 9.x (Enterprise license required)
  • Elastic Agent enrolled via Fleet with Endpoint Security enabled on target endpoints
  • Kibana user with the correct role for response actions

Installation

From PyPI

pip install edops

pipx is recommended for CLI tools — it installs in an isolated environment and puts edops on your PATH:

pipx install edops

From source

git clone https://github.com/renini/edops.git
cd edops
pip install -e .
# or
pipx install -e .

Quick Start

# 1. Point at your Kibana instance
edops config set --url https://kibana.lab.internal:5601
edops config set --api-key    # prompts with hidden input — nothing in shell history

# 2. Find your endpoint
edops agents workstation-01

# 3. Act on it (agent ID from step 2)
edops execute <agent-id> --command "whoami" --comment "INC-1337"

Configuration

Settings are stored in ~/.config/edops/config.json (mode 0600).

edops config set --url https://kibana.lab.internal:5601
edops config set --api-key          # prompts with hidden input — nothing stored in shell history
edops config show

| Option | Default | Description | |---|---|---| | --url | — | Kibana URL | | --api-key | — | API key (base64 id:key); omit value to be prompted | | --username / --password | — | Basic auth alternative to API key; --password omit value to be prompted | | --space-id | default | Kibana space | | --ca-cert | — | Path to CA bundle for self-signed certs | | --no-verify-ssl | — | Disable TLS verification (never use against production) | | --require-comment / --no-require-comment | on | Require a ticket reference on every action | | --persist-history / --no-persist-history | off | Save console/shell command history to ~/.config/edops/ across sessions |

Credential priority (highest to lowest)

  1. Global CLI flags (--url, --api-key, --username, --password) — per-invocation override
  2. Shell environment variables (EDOPS_KIBANA_*)
  3. .env file in the current working directory
  4. config.json
  5. Auto-prompt — if nothing provides a URL or credentials, edops asks interactively

Environment variables

| Variable | Description | |---|---| | EDOPS_KIBANA_URL | Kibana base URL (e.g. https://kibana.lab.internal:5601) | | EDOPS_KIBANA_API_KEY | API key (base64 id:key) | | EDOPS_KIBANA_USERNAME | Username for basic auth | | EDOPS_KIBANA_PASSWORD | Password for basic auth | | EDOPS_KIBANA_VERIFY_SSL | Set to false to skip TLS verification | | EDOPS_KIBANA_CA_CERT | Path to a custom CA certificate bundle | | EDOPS_KIBANA_SPACE_ID | Kibana space ID (default: default) |

.env file

Place a .env in your working directory to set credentials without exporting shell variables — useful when working against multiple stacks from different project directories:

# .env  (add to .gitignore — never commit this file)
EDOPS_KIBANA_URL=https://kibana.lab.internal:5601
EDOPS_KIBANA_API_KEY=<base64-id:key>

Authentication

API key (recommended) — generate in Kibana → Stack Management → API keys:

edops config set --api-key              # hidden prompt, nothing in shell history
edops config set --api-key <base64>     # pass directly

Username / password:

edops config set --username elastic
edops config set --password             # hidden prompt

Per-invocation override — useful on shared machines or when switching stacks:

edops --url https://kibana.lab.internal:5601 --api-key <base64> processes <agent-id>
edops --api-key processes <agent-id>    # prompts for key, uses URL from config
edops --url https://staging:5601 agents workstation-01

TLS

edops config set --ca-cert /path/to/ca.crt     # custom CA for self-signed certs
edops config set --no-verify-ssl               # disable verification (not for production)

Commands

Endpoint discovery

| Command | Description | |---|---| | edops agents [query] | List enrolled Fleet agents, filter by hostname prefix, IP, or MAC — omit to list all | | edops agents --online | Only show agents currently online | | edops metadata <agent-id> | Show OS, agent version, policy, capabilities, isolation state |

edops agents                          # all enrolled agents
edops agents WIN-VM-01               # hostname prefix match
edops agents 10.10.10.               # all agents on 10.10.10.x
edops agents de:ad:be                 # MAC address prefix
edops agents --online                 # all agents currently online
edops agents WIN-VM-01 --online      # hostname prefix, online only

Isolation

| Command | Description | |---|---| | edops isolate <agent-id> | Isolate a host from the network | | edops unisolate <agent-id> | Release network isolation |

Both accept --wait to poll until the action completes, --comment for traceability, and --json for raw output.

edops isolate <agent-id> --comment "INC-1337 ransomware containment" --wait
edops unisolate <agent-id> --comment "INC-1337 containment lifted" --wait

Process management

| Command | Description | |---|---| | edops processes <agent-id> | List running processes | | edops kill-process <agent-id> --pid <pid> | Terminate a process by PID | | edops kill-process <agent-id> --entity-id <id> | Terminate by process entity ID | | edops suspend-process <agent-id> --pid <pid> | Suspend a process by PID | | edops suspend-process <agent-id> --entity-id <id> | Suspend by process entity ID |

File operations

| Command | Description | |---|---| | edops execute <agent-id> --command <cmd> | Execute a shell command and return stdout/stderr | | edops get-file <agent-id> --path <path> | Retrieve a file from the endpoint | | edops upload <agent-id> --file <local-path> | Upload a local file to the endpoint | | edops scan <agent-id> --path <path> | Scan a file or directory with Elastic Defend | | edops memory-dump <agent-id> | Full kernel memory dump (Windows only) | | edops memory-dump <agent-id> --pid <pid> | Process memory dump |

edops execute <agent-id> --command "whoami && hostname" --comment INC-1337
edops execute <agent-id> --command "heavyscript.ps1" --timeout 300 --comment INC-1337
edops get-file <agent-id> --path "C:\Users\analyst\Desktop\suspicious.exe" \
               --output-dir ./evidence --comment INC-1337
edops scan <agent-id> --path "/tmp/dropped_file" --comment INC-1337

Security alerts

edops alerts                                    # all alerts from the last 24 hours
edops alerts <agent-id>                         # alerts for a specific endpoint
edops alerts <agent-id> --status open           # filter by status: open, acknowledged, closed
edops alerts <agent-id> --since 7d              # time window: 30m, 6h, 7d, etc.
edops alerts --json | jq '.hits.total.value'    # total alert count across all endpoints

Session View

Render the process tree and captured terminal I/O for any detection alert — equivalent to Kibana's Session View, but in the terminal:

edops session-view <alert-id>

The <alert-id> is the document _id from the alert, visible via edops alerts --json:

# Get alert IDs for a specific endpoint
edops alerts <agent-id> --json | jq -r '.hits.hits[]._id'

# Inspect the full attack chain for an alert
edops session-view 55485a1b9d9a0348d3f0328cf6565665b2e8d280a2692e40b8c35ba586750be6
Session View  55485a1b9d9a0…  2026-05-03 14:10:46
Rule: Malware Prevention Alert

Process Tree
root  sshd-session  (11793)
└── analyst  -bash  (11820)  [I/O]
    └── root  sudo -s  (11822)
        └── root  su  (11830)  [I/O]
            ├── root  ps fax  (11831)
            ├── root  wget https://secure.eicar.org/eicar.com  (12085)
            ├── root  vim malware  (12100)  [I/O]  ◄ alerted
            └── root  wget https://nothing.malicious.example.org  (12099)

Session Export

Export the terminal I/O for an alert's session to an asciicast file for archiving, sharing, or converting to GIF/MP4:

edops session-export <alert-id>                          # save to tty_<alert-id[:16]>.cast
edops session-export <alert-id> --output session.cast   # custom filename
edops session-export <alert-id> --comment INC-1337      # filename becomes tty_INC-1337-id.cast
edops session-export <alert-id> --force                 # overwrite existing file
edops session-export <alert-id> --gif                   # also produce a GIF via agg
edops session-export <alert-id> --mp4                   # also produce an MP4 via agg + ffmpeg
edops session-export <alert-id> --no-intro              # skip the 2-second animated intro

Session Play

Replay a session as live terminal output — accepts an alert ID or a .cast file:

edops session-play <alert-id>                   # replay the alerted process's I/O
edops session-play <alert-id> --all             # include I/O from all session processes
edops session-play session.cast                 # replay a previously exported .cast file
edops session-play <alert-id> --yes             # skip the safety prompt

osquery

# Run a live query and wait for results
edops osquery run <agent-id> --query "SELECT name, pid, path FROM processes LIMIT 10"

# Use a saved query or a pack
edops osquery run <agent-id> --saved-query-id my-query
edops osquery run <agent-id> --pack-id my-pack

# Fire and forget — fetch results later
edops osquery run <agent-id> --query "SELECT * FROM users" --no-wait
edops osquery results <action-id> <query-action-id>

# List all saved queries
edops osquery saved-queries

Action management

edops status <action-id>                         # status and per-agent output of a response action
edops actions                                    # list recent response actions
edops actions <endpoint-id>                      # filter by endpoint
edops actions --command execute                  # filter by command type (isolate, execute, etc.)
edops actions --page 2 --page-size 50           # pagination

Interactive Modes

Console

A full response console scoped to a single endpoint. All commands run against the same agent — no need to repeat the agent ID. Tab-completion is available for commands and their flags.

edops console <agent-id> --comment INC-1337
Elastic Defend >_ Respond console  endpoint=<agent-id>  host=WIN-VM-01  os=Windows 10 Pro  ip=10.10.10.11

[WIN-VM-01]> processes
[WIN-VM-01]> execute --command "net localgroup administrators"
[WIN-VM-01]> alerts --status open
[WIN-VM-01]> osquery --query "SELECT name, path FROM processes WHERE on_disk = 0"
[WIN-VM-01]> isolate --wait
[WIN-VM-01]> comment INC-5678        # change the active ticket reference mid-session
[WIN-VM-01]> exit

Available console commands: isolate, unisolate, processes, kill-process, suspend-process, get-file, execute, upload, scan, memory-dump, status, actions, alerts, osquery, osquery-results, osquery-saved, metadata, shell, comment, help, exit

Shell

Semi-interactive shell that wraps execute response actions. Each command you type is dispatched as an Elastic response action; stdout/stderr are extracted from the returned zip and printed locally.

edops shell <agent-id> --comment INC-1337
Edops Shell  <agent-id>
Ctrl+D or 'exit' to quit  ·  commands routed via Kibana execute action

[65d97abd]> whoami
nt authority\system

[65d97abd]> net localgroup administrators
Alias name     administrators
...

[65d97abd]> exit

Note: Each command is a separate API round-trip (submit → poll → download). Expect 3–10 seconds per command depending on network and endpoint load.


File Retrieval

Files returned by get-file, execute (when output is large), and memory-dump are saved as password-protected zip archives. The password is always elastic.

edops get-file <agent-id> --path "C:\Users\analyst\Desktop\suspicious.exe" \
               --output-dir ./evidence --comment INC-1337

unzip -P elastic ./evidence/INC-1337_suspicious.exe.zip

The filename is prefixed with the --comment value when provided (e.g. INC-1337_suspicious.exe.zip), making it easy to organise evidence by case.


Comment and Ticket Traceability

Every response action accepts --comment to attach a ticket or case reference. This is recorded in the Kibana action log and is visible in the Security app.

edops isolate <agent-id> --comment "INC-1337 - ransomware containment"

Enforce comments across all actions:

edops config set --require-comment

With this set, any action without --comment will be rejected before hitting the API.

In edops console, change the active comment mid-session without leaving:

[WIN-VM-01]> comment INC-5678

Global Options

These flags are accepted before any subcommand:

edops --version                                    # show version and exit
edops --verbose <command>                          # print each HTTP request and response
edops --url <url> <command>                        # override Kibana URL for this invocation
edops --api-key <key> <command>                    # override API key for this invocation
edops --api-key <command>                          # prompt for API key with hidden input
edops --username <u> --password <p> <command>      # basic auth override
edops --password <command>                         # prompts for password with hidden input
edops --help                                       # show top-level help
edops <command> --help                             # show help for a specific command

Security Notes

Elastic Endpoint Security (XDR) operates with high privileges across endpoints. This tool interfaces directly with its control plane.

  • Treat access as extremely sensitive
  • Audit and monitor usage — every action is stamped in the Kibana action log
  • Compromised XDR access == GAME OVER

Credential storage

Credentials are stored in ~/.config/edops/config.json (mode 0600). Prefer environment variables or per-invocation flags on shared systems. Never commit credentials to version control.

API key vs. username/password

API keys (Kibana → Stack Management → API keys) are preferred over username/password:

  • Scoped to specific privileges
  • Revocable without changing the account password
  • Auditable individually in the Kibana audit log

TLS

Never use --no-verify-ssl against a production stack. If your Kibana uses a self-signed or internal CA, use --ca-cert instead:

edops config set --ca-cert /path/to/internal-ca.crt

Shell and console history

Command history in edops shell and edops console is not persisted by default. Enable it only if you understand the tradeoff:

edops config set --persist-history   # saves to ~/.config/edops/{shell,console}_history

Credits and Acknowledgements

  • Endgame (now part of Elastic) — for the high-end endpoint security solution, which offers great resistance against cyber threat actors.
  • Elastic — for the powerful stack and getting the wider community involved in cybersecurity defense, by being transparent on detection methods and tooling (i.e. YARA rules and other detection rules).
  • Anthropic — for their assisted AI coding software; this project was created from idea to code with their top-tier models, credits $$ and Claude Code.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edops-0.1.2.tar.gz (252.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

edops-0.1.2-py3-none-any.whl (44.0 kB view details)

Uploaded Python 3

File details

Details for the file edops-0.1.2.tar.gz.

File metadata

  • Download URL: edops-0.1.2.tar.gz
  • Upload date:
  • Size: 252.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for edops-0.1.2.tar.gz
Algorithm Hash digest
SHA256 4dd4a371b105f242fb5d180e904c1fbe52e66adf5ff6168a9cf403149cf650b8
MD5 d68da8ba1a1b01afd1b066f808c536da
BLAKE2b-256 bc827f86b60ad88b4c1f65418fa1c17962b5ae54c0d3e42e862806fb910d2eeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for edops-0.1.2.tar.gz:

Publisher: release.yml on renini/edops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edops-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: edops-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 44.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for edops-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f31435b6629c05fff670cc9d43096f84e329f7724e935e677fb1c67cb5df3d7e
MD5 ba29e220c0b86b61ed0029452c284654
BLAKE2b-256 d9ab86b319b774a37c46f973350d6de6d81cb8ee6c7a88c7bb6a66f1f4865fbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for edops-0.1.2-py3-none-any.whl:

Publisher: release.yml on renini/edops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page