v2.0.0 #20
marek-methods
announced in
Announcements
v2.0.0
#20
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
PrimAITE v2.0.0
✨ What's New
Command Line Interface
PrimAITE now comes with a CLI (built with Typer) that serves as the main entry point for those using PrimAITE out of the box.

To run the default PrimAITE Session out of the box, run:
Application Directories
To enable PrimAITE to be used as an installed Python package, and to be used as is out-of-the-box without reliance on the repository, a collection of application directories has been created. These back-end/hidden and user-facing directories are used to store things like application log files, users' config files, users' Jupyter Notebooks, PrimAITE session outputs etc. The user needs to call
primaite setupafter doingpip installto perform the directory setup. The directories are structured as follows:Windows
Linux
MacOS
Support for Ray Rllib
PrimAITE now supports the training of PPO and A2C agents using both Stable Baselines3 and Ray RLlib. The RL framework and agent algorithm to be used for training is determined by the
agent_frameworkandagent_identifierconfigurable items in the training config file. Ifagent_framework=RLLIB, the backend Ray RLlib RL framework can be configured to use either Tensorflow, Tensorflow 2.x, or PyTorch using thedeep_learning_framework.Random red agent
A random red agent has been provided to train the blue agent against. The random red agent will choose a random number of nodes to attack, as well as randomly choosing the actions to perform on the environment.
Repeatability of sessions
A seed can now be provided in the training configuration file. The seed will be used across PrimAITE so that a repeatable run is achievable. The seed needs to be an integer value and by default is set to null.
The ability to set PrimAITE to use deterministic or stochastic evaluation is also added.
Session loading
PrimAITE can now load previously run sessions for SB3 Agents (SB3 agents only, see Known Issues. This can be done via:
CLI
Python
The output for the loaded session will be in the target directory i.e. the PREVIOUS_SESSION_DIRECTORY. While most of the outputs won't be overwritten, the agent zip file will be overwritten.
Agent Session Classes
An
AgentSessionABCclass withSB3AgentandRLlibsubclasses and aHardCodedAgentSessionABCclass with various hard-coded agent subclasses have been created. The Agent Session classes act as a wrapper around various RL and hard-coded agents. They help to standardise how agents are trained in PrimAITE using a common interface. They also provide a suite of standardised session outputs.Standardised Session Output
When a session is run, a session output sub-directory is created in the user's app sessions directory
(
~/primaite/sessions). The sub-directory is formatted as such:~/primaite/sessions/<yyyy-mm-dd>/<yyyy-mm-dd>_<hh-mm-dd>/. This session directory is populated with four types of outputs:Example Session Directory Structure
PrimaiteSession Class
The
PrimaiteSessionclass acts as a single wrapper around the Agent Session classes. It is both an entry point and a broker for the individual Agent Session classes.Action Space
Discrete Action Space
The
NODEandACLaction spaces have been changed from multi-discrete to discrete action spaces.NODEandACLaction spaces are both dictionaries where a single number reflects an entire action an agent can take.The below code block is an example of a dictionary entry for the
NODEaction space:{ 1: [1, 1, 1, 0], }The below code block is an example of a dictionary entry for the
ACLaction space:{ 1: [1, 0, 1, 2, 1, 0, 3], }Combined Action Spaces
A new
ANYaction space option has been introduced. This allows the agent to do bothNODEactions andACLactions in the same episode (e.g., scan a node in Step 1 and create an ACL rule in Step 2).The below code block is an example of a dictionary entry for the
ANYaction space:{ 0: [1, 0, 0, 0], 1: [1, 1, 1, 0], 2: [1, 0, 1, 2, 1, 0, 3] }is_valid_acl_action_extra,is_valid_node_actionandis_valid_acl_actionin theprimaite.agents.utilsmodule help to slim down the dictionary to contain the relevant actions only.For example, a node action to do
PATCHINGon a node's hardware state CANNOT happen so it is not added to the dictionary.transform_action_node_readableandtransform_action_acl_readablein theprimaite.agents.utilsmodule converts the enumerated node action into a more readable form. The readable form is used by functions such asis_valid_node_actionto determine if the action is valid or not.An example using
transform_action_node_readable:ACL Action Space
Previously, the ACL action space was made up of 6 items:
[Decision, Permission, Source, Dest, Protocol, Port].Now the agent can specifically choose where to place the ACL in the
Access Control List:Position-> [0 tolength of ACL List]Observation Space
Configurable observation space
Management of the observation space in
Primaiteenv has been outsourced to a dedicated class,ObservationHandler. This is part of a new submodule,primaite.environment.observation. The observation space is now built from smaller components. The components can take optional user parameters at initialisation. Each component is responsible for querying thePrimaiteenv and formatting information into a numpy array. The handler orchestrates the updating of components' data and combines the data from multiple components to create a composite observation space and observations.The observation space configuration is set in the training config file. The below code block is an example of an observation space configuration:
New observation types
Observations about node hardware and software states can now be formatted as
MultiDiscretegym spaces.The same thing is possible for link traffic amounts.
Changes to the Access Control List
The
acldictionary inAccessControlListis now a list. This accommodates changes made toACLaction space and the positioning ofACLRulesinside the list to signal their level of priority.Blue Agent actions on Nodes
Previously, when a node's
hardware state == HARDWARE_STATE.OFFthere was no validation inactive_node.pyandservice_node.py. This meant the agent could change a Nodes' runningservice_stateorsoftware_stateeven though the Node wasOFF.Logic has now been implemented to check if a node is
OFFbefore executing any actions on the Node by the blue agent such as a change ofservice state,file system stateorsoftware state.Reduced default reward values
Reward values in the default config files have been decreased by a factor of 10000.
Fixing the Functionality of Resetting a Node
A "SHUTTING DOWN" was added to last for a (configurable) given step count and a "BOOTING" operating state was added as well to last for a (configurable) given step count which is applied when either of the blue agent "node off" or "node on" actions are issued respectively. Issuing a reset command is simply the sum of these two instructions (off and on) with the summation of the step counts for each. That way, the blue agent may learn to issue a single instruction (i.e. reset) rather than clunkily issuing a shutdown and then a startup at precisely the right time to make it optimal (which is probably harder than simply issuing a reset).
🐛 Bug Fixes
♻️ Refactoring
Package Structure
The overall PrimAITE repository and package structure have been refactored to enable the build, distribution, and installation of Python wheels without reliance on the repository itself. To make this happen, the following work has been done:
src/directory.PRIMAITEPython package was renamed toprimaiteto adhere to PEP-8 Package & Module Names.src/primaite/VERSIONfile exists to act as a single source of truth for the PrimAITE version.src/directory.src/directory.*/_package_data/directory in their respective sub-package.MANIFEST.infile was added to define which non-python files are to be included in the build (e.g. package data andVERSIONfile).pyproject.tomlfile. See Engineering Notes/pyproject.toml below for more info.Enum classes now in Pascal Case
All Enum classes in
primaite.common.enumshave been re-written in Pascal Case to comply with PEP-8 Class Names.Config keys now in snake case
All config keys have been re-written in snake case. This enables faster instantiation as keys can automatically be passed to a constructor as the YAML keys match the config class keys. The config load functions are backwards compatible with legacy config files (pass
legacy=Trueas an arg).To run a PrimAITE session using legacy files, pass the
--legacy-tcand/or the--legacy-ldcoptions toprimaite session:Config Files Decoupled
The lay down config file needed to be in the same directory as the training config, or the training config needed to hard-code the full path of the lay down config. This coupling was restrictive and cumbersome to manage. Also, there was no benefit in having 1:1 mapping between training and lay down config files. The two configs have been decoupled and can be used interchangeably as they do not depend on one another.
Training config items moved from lay down to training
The lay down config file had:
and
While the training had:
This meant that to configure a training session you had to have values on both the training config and lay down config. These two values from the lay down config have now been moved over to the training config.
In addition, there is a new configuration where you can set different time steps and episode counts depending on whether the session running is a training or an evaluation session. There are two different config values for the number of episodes for training and for evaluation (the same applies to the number of time steps). These can be explicitly specified in the config or a default value will be assigned:
Update to Node attribute Naming
An explicit and consistent naming convention has been enforced on the
Nodeclass and its children,ActiveNode,PassiveNode, andServiceNode. These naming changes have also been carried through to where the Nodes are used inprimaite.environment.primaite_env.Primaite.Constructor params
_id->node_id_name->name_type->node_type_priority->priority_state->hardware_state_ip_address->ip_address_os_state->software_state_file_system_state->file_system_state_config_values->config_valuesInstance variables
Lay Down config file
id->node_idportsList->ports_listserviceList->service_listbaseType->base_typenodeType->node_typehardwareState->hardware_stateipAddress->ip_addresssoftwareState->software_statefileSystemState->file_system_statePrimaite instance variables
_id->node_id_name->name_type->node_type_priority->priority_state->hardware_state_ip_address->ip_address_os_state->software_state_file_system_state->file_system_stateTransactions
Pre-action and post-action observation are no longer reported in the transactions file - Only the pre-action is saved. The CSV header has more human-readable descriptions for columns relating to the observations.
Misc
PrimAITE is now fully type hinted.
Docstring documentation coverage was greatly increased and docstring formatting has been standardised to follow ReST syntax in most submodules.
🚦 Tests
The engineering team have made a great strive towards increasing the test code coverage. This is an ongoing process.
📚 Docs
Currently, while the repository is PrimAITE, we can't host the docs in the repo pages. As a temporary measure, they've been converted to pdf and added here: PrimAITE v2.0.0 Docs.pdf
Documentation has been overhauled with the following changes:
🛠 Engineering Notes
pyproject.toml
Migrated from legacy
setup.pytopyproject.tomlfollowing pypa/pip #8368 Deprecate call to setup.py install when building a wheel failed for source distributions without pyproject.toml.As PrimAITE still has a dependency on openai/gym, we've had to force specific versions of build, setuptools, and wheel when installing PrimAITE from source with the dev extra. A future release will see PrimAITE migrate to farma-foundation/gymnasium as soon as Stable Baselines3 and Ray RLlib are aligned with the version of farma-foundation/gymnasium they're dependant on . Once this has happened, the dependency on specific versions of build, setuptools, and pip will be dropped.
⚡️ Performance Notes
PrimAITE v2.0.0 was benchmarked automatically upon release. Learning rate metrics were captured to be referenced during system-level testing and user acceptance testing (UAT).
The benchmarking process consists of running 10 training sessions using the same training and lay down config files. Each session trains an agent for 500 episodes, with each episode consisting of 256 steps. The mean reward per episode from each session is captured. This is then used to calculate a combined average reward per episode from the 10 individual sessions for smoothing. Finally, a 25-widow rolling average of the combined average reward per session is calculated for further smoothing.
PrimAITE 2.0.0 Learning Benchmark Plot
The full benchmark report is available here: PrimAITE v2.0.0 Learning Benchmark.pdf
RLlibAgentErrorwith the error messageCannot evaluate an RLlib agent that hasn't been through training yet.NotImplementedError. This feature will be added in a future release.💫 Install & Run
Currently, the PRimAITE wheel can only be installed from GitHub. This may change in the future with release to PyPi.
Windows (PowerShell)
Prerequisites:
Install:
Unix
Prerequisites:
Install:
Contributors
Full Changelog: https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE/commits/v2.0.0
This discussion was created from the release v2.0.0.
All reactions