The zenoh_security_tools package contains the generate_configs executable which generates Zenoh session config files with access control, authentication and encryption parameters based on policies and keystores generated using sros2.
ros2 run zenoh_security_tools generate_configs -h
Generate Zenoh session configs with security artifacts.
Options:
-h,--help Print this help message and exit
-p,--policy TEXT REQUIRED The path to the Access Control Policy file.
-e,--enclaves TEXT The directory with the security enclaves for the various nodes in the policy file.
-d,--ros-domain-id UINT REQUIRED The ROS Domain ID.
-c,--session-config TEXT REQUIRED The path to the Zenoh session config file.
-r,--router-config TEXT REQUIRED The path to the Zenoh router config file.
The process of setting up security is very similar to this tutorial but instead of relying on security environment variables and passing enclaves to nodes, we'll
pass Zenoh session configs with the desired security parameters configured to rmw_zenoh.
These modified session configs are generated using the tool above.
The steps below will walk us through running rmw_zenoh with security enabled for a simple talker-lister system.
mkdir ~/sros2_democd ~/sros2_demo
ros2 security create_keystore demo_keystoreGenerate security files for the talker and listener nodes, and the zenohd router respectively.
ros2 security create_enclave demo_keystore /talker_listener/talker
ros2 security create_enclave demo_keystore /talker_listener/listener
ros2 security create_enclave demo_keystore /talker_listener/zenohdLaunch zenohd
ros2 run rmw_zenoh_cpp rmw_zenohdLaunch the listener
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run demo_nodes_cpp listenerLaunch the talker
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run demo_nodes_cpp talkerNow run the policy generator from sros2
ros2 security generate_policy policy_listener_talker.xmlFinally, terminate all processes.
Generate security configs without enclaves (only access control).
ros2 run zenoh_security_tools generate_configs \
--policy policy_listener_talker.xml \
--router-config <path to default router config>/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5 \
--session-config <path to default session config>/DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5 \
--ros-domain-id 0This will generate Zenoh session config files for each node in the policy_listener_talker.xml file.
export ZENOH_SESSION_CONFIG_URI=talker.json5
ros2 run demo_nodes_cpp talker
[INFO] [1740601932.350808475] [talker]: Publishing: 'Hello World: 1'
[INFO] [1740601933.350487483] [talker]: Publishing: 'Hello World: 2'export ZENOH_SESSION_CONFIG_URI=listener.json5
ros2 run demo_nodes_cpp listener
...
[INFO] [1740602312.492840958] [listener]: I heard: [Hello World: 1]
[INFO] [1740602313.492200366] [listener]: I heard: [Hello World: 2]You can validate access control by remapping the /chatter topic which should result in no messages being published.
export ZENOH_SESSION_CONFIG_URI=zenohd.json5
ros2 run rmw_zenoh_cpp rmw_zenohdexport ZENOH_SESSION_CONFIG_URI=talker.json5
ros2 run demo_nodes_cpp talker --ros-args -r chatter:=new_topicexport ZENOH_SESSION_CONFIG_URI=listener.json5
ros2 run demo_nodes_cpp listener --ros-args -r chatter:=new_topic
...
# listener should not receive anythingThis time we generate the configs with authentication and encryption configured using the enclaves generated by sros2.
ros2 run zenoh_security_tools generate_configs \
--policy policy_listener_talker.xml \
--router-config <path to default router config>/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5 \
--session-config <path to default session config>/DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5 \
--ros-domain-id 0 \
--enclaves ~/sros2_demo/demo_keystore/enclaves/talker_listenerNote
The executable assumes that the ~/sros2_demo/demo_keystore/enclaves/talker_listener directory contains folders with names matching node names defined in the policy_listener_talker.xml with the security files present.
Start the zenoh router with the zenohd.json config file.
export ZENOH_ROUTER_CONFIG_URI=zenohd.json5
ros2 run rmw_zenoh_cpp rmw_zenohdStart the talker
export ZENOH_SESSION_CONFIG_URI=talker.json5
ros2 run demo_nodes_cpp talkerStart the listener without setting the session config.
ros2 run demo_nodes_cpp listenerThe listener will not receive any messages.
Restart the listener with the session config.
export ZENOH_SESSION_CONFIG_URI=listener.json5
ros2 run demo_nodes_cpp listener
...
[INFO] [1740602312.492840958] [listener]: I heard: [Hello World: 10]
[INFO] [1740602313.492200366] [listener]: I heard: [Hello World: 11]The messages are received by the listener.