v2.0.0 #10
ChrisMcCarthyDev
started this conversation in
Show and tell
v2.0.0
#10
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
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 setup
after doingpip install
to 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_framework
andagent_identifier
configurable 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
AgentSessionABC
class withSB3Agent
andRLlib
subclasses and aHardCodedAgentSessionABC
class 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
PrimaiteSession
class 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
NODE
andACL
action spaces have been changed from multi-discrete to discrete action spaces.NODE
andACL
action 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
NODE
action space:The below code block is an example of a dictionary entry for the
ACL
action space:Combined Action Spaces
A new
ANY
action space option has been introduced. This allows the agent to do bothNODE
actions andACL
actions 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
ANY
action space:is_valid_acl_action_extra
,is_valid_node_action
andis_valid_acl_action
in theprimaite.agents.utils
module help to slim down the dictionary to contain the relevant actions only.For example, a node action to do
PATCHING
on a node's hardware state CANNOT happen so it is not added to the dictionary.transform_action_node_readable
andtransform_action_acl_readable
in theprimaite.agents.utils
module converts the enumerated node action into a more readable form. The readable form is used by functions such asis_valid_node_action
to 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
Primaite
env 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 thePrimaite
env 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
MultiDiscrete
gym spaces.The same thing is possible for link traffic amounts.
Changes to the Access Control List
The
acl
dictionary inAccessControlList
is now a list. This accommodates changes made toACL
action space and the positioning ofACLRules
inside the list to signal their level of priority.Blue Agent actions on Nodes
Previously, when a node's
hardware state == HARDWARE_STATE.OFF
there was no validation inactive_node.py
andservice_node.py
. This meant the agent could change a Nodes' runningservice_state
orsoftware_state
even though the Node wasOFF
.Logic has now been implemented to check if a node is
OFF
before executing any actions on the Node by the blue agent such as a change ofservice state
,file system state
orsoftware 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.PRIMAITE
Python package was renamed toprimaite
to adhere to PEP-8 Package & Module Names.src/primaite/VERSION
file 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.in
file was added to define which non-python files are to be included in the build (e.g. package data andVERSION
file).pyproject.toml
file. See Engineering Notes/pyproject.toml below for more info.Enum classes now in Pascal Case
All Enum classes in
primaite.common.enums
have 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=True
as an arg).To run a PrimAITE session using legacy files, pass the
--legacy-tc
and/or the--legacy-ldc
options 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
Node
class 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_values
Instance variables
Lay Down config file
id
->node_id
portsList
->ports_list
serviceList
->service_list
baseType
->base_type
nodeType
->node_type
hardwareState
->hardware_state
ipAddress
->ip_address
softwareState
->software_state
fileSystemState
->file_system_state
Primaite 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_state
Transactions
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.py
topyproject.toml
following 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
RLlibAgentError
with 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.
Beta Was this translation helpful? Give feedback.
All reactions