AttackMate Playbook CLI Client
This is a command-line client for interacting with the AttackMate API server for remotely executing playbooks. Client Documentation on github pages.
AttackMate is a framework for automated security testing and attack simulation. For more information about the AttackMate framework, please visit the AttackMate repository and the AttackMate api server repository. Both can be installed with an ansible role: AttackMate ansible role
Client Installation
Clone the repository:
git clone https://github.com/ait-testbed/attackmate-client
cd attackmate-client
With uv (recommended):
uv sync --dev
Alternatively using pip and virtualenv:
python -m venv venv
source venv/bin/activate
pip install -e .
Use from the Command Line
The main executable command is attackmate-client. All commands require authentication credentials (--username and --password).
Options
| Option | Description |
|---|---|
| --server-url | Base URL of the AttackMate API server (default: https://localhost:8445) |
| --username | API username for authentication. (required) |
| --password | API password for authentication. (required) |
| --cacert | Path to the server's CA certificate file if using self-signed SSL. |
| --debug | Enable server debug logging for the playbook instance. |
Example: Execute a Playbook
This command reads the YAML content from a local file and sends the full content directly to the AttackMate server's /playbooks/execute/yaml endpoint for execution.
uv run attackmate-client </path/to/local_playbook.yaml> --server-url <server-url> --username <user> --password <pass> --cacert </path/to/cert>
Example with real values:
uv run attackmate-client playbooks/example.yaml \
--server-url https://attackmate.example.com:8445 \
--username admin \
--password mypassword \
--cacert certs/server-ca.crt \
--debug
Use in Scripts
The core functionality of the client is exposed through the RemoteAttackMateClient class, allowing you to integrate remote playbook execution into other Python scripts or automation workflows.
API Reference
RemoteAttackMateClient is the main client class for interacting with the AttackMate API.
Constructor:
RemoteAttackMateClient(
server_url: str,
username: str,
password: SecretStr,
cacert: Optional[str] = None,
timeout: Optional[float] = 60.0
)
Parameters:
server_url(str): Base URL of the AttackMate server (e.g., "https://attackmate.example.com:8445")username(str): Username for authenticationpassword(SecretStr): Password for authenticationcacert(Optional[str]): Path to CA certificate file for SSL verificationtimeout(Optional[float]): Request timeout in seconds (default: 60.0)
METHODS:
execute_remote_playbook_yaml(playbook_yaml_content: str, debug: bool = False)
Executes a playbook by sending its YAML content to the remote server.
Parameters:
playbook_yaml_content(str): The complete YAML content of the playbookdebug(bool): Enable debug logging on the server (default: False)
Returns:
Dict[str, Any]on success containing:success(bool): Whether execution succeededmessage(str): Status messagefinal_state(dict): Final state including variablesinstance_id(str): remote attackmate instance idattackmate_log(str): attackmate log of remote instanceoutput_log(str): output log of remote instancejson_log(str): Json log of remote instance
Noneon failure
Code Example 1: Basic Playbook Execution
content of playbook.yml:
commands:
- type: shell
cmd: whoami
from attackmate_client import RemoteAttackMateClient
from pydantic import SecretStr
import yaml
# Initialize the client
client = RemoteAttackMateClient(
server_url="https://attackmate.example.com:8445",
username="admin",
password=SecretStr("mypassword"),
cacert="/path/to/ca-cert.pem"
)
# Read playbook from file
with open("my_playbook.yaml", "r") as f:
playbook_content = f.read()
# Execute the playbook
result = client.execute_remote_playbook_yaml(
playbook_yaml_content=playbook_content,
debug=True
)
# Check results
if result and result.get("success"):
print("Playbook executed successfully!")
print(f"Success: {result.get('success', 'N/A')}")
print(f"Message: {result.get('message', 'No message.')}")
print(f" Attackmate Log:\n{result.get('attackmate_log', 'No log available.')}")
print(f"Output Log:\n{result.get('output_log', 'No output log available.')}")
print(f"Json Log:\n{result.get('json_log', 'No json log available.')}")
final_state = result.get('final_state')
if final_state and final_state.get('variables'):
print('Final Variable Store State:')
print(yaml.safe_dump(final_state['variables'], indent=2, default_flow_style=False))
else:
print("Playbook execution failed!")
expected output:
Playbook executed successfully!
Success: True
Message: Playbook execution finished.
Attackmate Log:
2026-03-06 11:43:10 INFO - Delay before commands: 0 seconds
2026-03-06 11:43:10 DEBUG - Template-Command: 'whoami'
2026-03-06 11:43:10 INFO - Executing Shell-Command: 'whoami'
2026-03-06 11:43:10 DEBUG - Running non interactive command
2026-03-06 11:43:10 DEBUG - Closing popen process
2026-03-06 11:43:10 DEBUG - loop_if does not match
2026-03-06 11:43:10 DEBUG - loop_if_not does not match
2026-03-06 11:43:10 WARNING - Cleaning up session stores
2026-03-06 11:43:10 WARNING - Cleaning up session stores
Output Log:
2026-03-06 11:43:10 INFO - Command: whoami
ubuntu
Json Log:
{"start-datetime": "2026-03-06T11:43:10.835655", "type": "shell", "cmd": "whoami", "parameters": {"only_if": null, "error_if": null, "error_if_not": null, "loop_if": null, "loop_if_not": null, "loop_count": "3", "exit_on_error": true, "save": null, "background": false, "kill_on_exit": true, "metadata": null, "interactive": false, "creates_session": null, "session": null, "command_timeout": "10", "read": true, "command_shell": "/bin/sh", "bin": false}}
Final Variable Store State:
RESULT_RETURNCODE: '0'
RESULT_STDOUT: 'ubuntu'
execute_remote_command(command_pydantic_model, debug: bool = False)
Executes a single AttackMate command on the remote serve
Parameters:
command_pydantic_model: A Pydantic model instance (e.g.,ShellCommand) or aRemoteCommandrepresenting the command. Must include atypefield matching a valid remotely executable AttackMate command type.debug(bool): Enable debug logging on the server (default:False)
Returns:
Dict[str, Any]on success containing:success(bool): Whether execution succeededresult(dict): Containsstdout,returncode, and optionallyerror_message
Noneon failure
The dependency problem: command_pydantic_model expects a RemotelyExecutableCommand instance — a Pydantic model from the attackmate package. However, since attackmate is not a dependency of this client, you have two options:
Option A — Pass a RemoteCommand from the attackmate client package (recommended for standalone use)
The client accepts a RemoteCommand, use this approach when you do not have attackmate installed:
from attackmate_client import RemoteAttackMateClient, RemoteCommand
client = RemoteAttackMateClient(...)
command = RemoteCommand(type="shell", cmd="id")
result = client.execute_remote_command(command, debug=True)
Option B — Pass a Attackmate Command Pydantic model (for use within the AttackMate framework)
If you are writing scripts that already have attackmate installed (e.g., plugins or internal tooling), you can import and instantiate the model directly:
from attackmate_client import RemoteAttackMateClient
from attackmate.schemas.shell import ShellCommand
client = RemoteAttackMateClient(...)
command = ShellCommand(type="shell", cmd="whoami")
result = client.execute_remote_command(command, debug=False)
Code Example 2: Basic Remote Command Execution
from pydantic import SecretStr
from attackmate_client import RemoteAttackMateClient, RemoteCommand
client = RemoteAttackMateClient(
server_url="https://attackmate.example.com:8445",
username="admin",
password=SecretStr("mypassword"),
cacert="/path/to/ca-cert.pem"
)
# Pass command as RemoteCommand
command = RemoteCommand(type="shell", cmd="id")
result = client.execute_remote_command(command, debug=True)
if result:
cmd_result = result.get("result", {})
if cmd_result.get("success"):
print("Command succeeded!")
print(f"Output:\n{cmd_result.get('stdout', '')}")
print(f"Return code: {cmd_result.get('returncode')}")
else:
print(f"Command failed: {cmd_result.get('error_message', 'Unknown error')}")
else:
print("No response received from server.")
Expected output:
Command succeeded!
Output:
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
Return code: 0
Session Management
The client handles authentication tokens automatically:
- Tokens are cached per server URL in memory
- Automatic login when credentials are provided
- Token renewal is handled transparently
- Sessions are maintained across multiple API calls within the same process
Documentation
Full documentation for the AttackMate framework and API server is available at:
Attackmate
- GitHub Pages: https://ait-testbed.github.io/attackmate
- Main Repository: https://github.com/ait-testbed/attackmate
Attackmate Api Server
- Main Repository: https://github.com/ait-testbed/attackmate-api-server
License
This project is licensed under EUPL-1.2
Release files for attackmate-client 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| attackmate_client-0.1.2.tar.gz | 16.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| attackmate_client-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.8 kB
Release files / attackmate_client-0.1.2.tar.gz
| Download URL | attackmate_client-0.1.2.tar.gz |
|---|---|
| Size | 16.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a259d64f9041e89e6734ea65ac0a1b4568b256dfc08e95fa70adbb83211644f3
|
|
BLAKE2b-256 checksum How to use checksums |
fd266a97b8ab9ef7ee32ed5e93255b8dbc3887de2e9f675c331ae5d554ee5dc7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 21, 2026.
Transparency logRelease files / attackmate_client-0.1.2-py3-none-any.whl
| Download URL | attackmate_client-0.1.2-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6606d45b0510aeaa8058733b6f84ef19bd8d9346f63be498b12754fe033b834c
|
|
BLAKE2b-256 checksum How to use checksums |
c089c9ae9e9c7484011d94491c7fad6d92637a35ffa381aa7ac35e2ba60a1e14
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 21, 2026.
Transparency log