Skip to content

Recurring Pentests

h3-cli: How to create scheduled actions using the h3-cli

The instructions below walk through how to use the h3-cli to configure a pentest to run on a recurrning schedule.

1. Spin up an h3-cli agent (internal pentests only)

If you plan to run internal pentests (which is the default), you will need to spin up a persistent agent process on the Docker Host inside your network where you plan to run NodeZero.

The h3-cli agent is a long-lived daemon process that periodically polls the H3 API and automatically launches NodeZero on the local machine whenever a new pentest is created and assigned to that agent.

If you are running external pentests, the agent is not required and you can skip this step.

Follow the instructions in STEP 1 of this guide to spin up an agent using the h3-cli. You can ignore all the other steps in that guide; only step 1 is required.

2. Create a scheduled action to run a pentest on a recurring schedule

The command below will create a schedule called my-schedule that will automatically run a pentest every Monday at 5pm UTC.

h3 create-scheduled-action my-schedule '0 17 * * 1' run-pentest '{"agent_name": "my-agent", "op_name": "Scheduled via agent"}'

The command uses a CRON expression, 0 17 * * 1, to specify the recurring schedule for the pentest.

Breaking it down:

  • my-schedule is the name of the schedule. A schedule may contain multiple actions. For example you can configure timing windows for pentesting around by business hours, by scheduling a pentest to launch on Monday at 5pm, pause every day at 8am, resume at 5pm, and finally terminate on Friday if it still running.
  • 0 17 * * 1 is the CRON expression. CRON expressions specify the {minute} {hour} {day-of-month} {month} {day-of-week} to run a given action. Visit the [link](( for more information about CRON expressions.
    • NOTE: Only hourly resolution is supported. The {minute} component of the CRON expression is always forced to be 0 on the backend.
    • CRON expressions are in UTC time. So the example CRON expression above is set to 5pm UTC.
  • run-pentest is the action. Supported actions are:
    • run-pentest: launches a new pentest (if one is not currently active for this schedule)
    • pause-pentest: pauses the active pentest associated with the schedule
    • resume-pentest: resumes the active pentest associated with the schedule
    • cancel-pentest: cancel the active pentest associated with the schedule
  • '{"agent_name": "my-agent"}': additional parameters for the action. These parameters are the same as those you would use if you were running the action directly from the command line.

A named schedule can have only one active pentest at a time. This prevents a schedule from kicking off a new pentest when its previous pentest has not yet completed.

3. Verify your schedule is registered with H3

Use the following command to view your pentest schedules:

h3 schedules

If all is well, you should see an entry for your schedule my-schedule.

4. Test your scheduled action by triggering it now

To ensure everything is wired up as expected, you can trigger your scheduled action immediately with the following command:

h3 trigger-scheduled-action my-schedule run-pentest 

This will trigger the run-pentest action for the my-schedule schedule, which will cause a pentest to be created. The agent running on your NodeZero Docker Host will see the new pentest and automatically run NodeZero.

You can monitor the agent process by tailing the log:

tail -f /tmp/my-agent.log

In a minute or so you should see the agent kick off the NodeZero Launch Script for the newly created pentest. The NodeZero Launch Script will download and launch the NodeZero Docker container on the local machine, just as if you had copy+pasted the curl command from the H3 Web Portal.

You can view the newly created pentest via:

h3 pentest 

If you'd like to kill the NodeZero Launch Script process before it downloads and launches NodeZero, you can use pkill:

pkill -f h3-run-nodezero

5. Troubleshooting

If you don't see NodeZero get launched in the agent log, use h3 schedules to see if any errors occurred when the action was triggered:

h3 schedules

The command output will resemble the readout below. Look at the last_triggered_* fields to help diagnose any problems:

  "name": "my-schedule",
  "state": "ENABLED",
  "created_at": "2023-02-06T06:52:04.660895",
  "last_updated_at": "2023-02-10T23:16:36.722392",
  "actions": [
      "action": "run-pentest",
      "params": {
        "agent_name": "my-agent",
        "op_name": "Scheduled via agent"
      "cron_expression": "0 17 * * 1",
      "cron_description": "At 05:00 PM, only on Monday",
      "last_triggered_at": "2023-02-10T22:08:05.010069",
      "last_triggered_time_ago": "an hour ago",
      "last_triggered_error": null

For further assistance, contact H3 support via the chat icon in the H3 Web Portal.

6. Create a second scheduled action to cancel the pentest

Let's add a second action to our schedule for canceling the pentest. We'll schedule it to run 1hr after the pentest is launched.

h3 create-scheduled-action my-schedule '0 18 * * 1' cancel-pentest

Once again we can test the action by triggering it immediately:

h3 trigger-scheduled-action my-schedule cancel-pentest 

After a moment you should see your pentest get canceled and move into the post-processing state.

7. More examples and helpful commands

The commands below show how to create a schedule that will:

  • launch pentests on Mondays at 5pm UTC
  • pause the running pentest every weekday at 8am UTC
  • resume the paused pentest every weekday at 5pm UTC
  • cancel the pentest if it's still running on Friday at 8am UTC
h3 create-scheduled-action my-schedule '0 17 * * 1' run-pentest '{"agent_name": "my-agent", "op_name": "Scheduled via agent"}'
h3 create-scheduled-action my-schedule '0 8 * * 2-4' pause-pentest 
h3 create-scheduled-action my-schedule '0 17 * * 2-4' resume-pentest 
h3 create-scheduled-action my-schedule '0 8 * * 5' cancel-pentest 

You can update a scheduled action by simply running the create-scheduled-action again with the new settings. For example, if you wish to change the schedule above such that it cancels the pentest at 7am UTC instead of 8am:

h3 create-scheduled-action my-schedule '0 7 * * 5' cancel-pentest 

Or if you wish to delete a scheduled action, use the delete-scheduled-action command:

h3 delete-scheduled-action my-schedule cancel-pentest

You can create multiple schedules by simply assigning a different schedule name. For example, here's a separate schedule that launches a pentest on Friday at 5pm UTC and cancels it Monday at 8am UTC:

h3 create-scheduled-action my-weekend-schedule '0 17 * * 5' run-pentest '{"agent_name": "my-agent", "op_name": "Weekend Pentest"}'
h3 create-scheduled-action my-weekend-schedule '0 8 * * 1' cancel-pentest 

You can view all of your schedules via:

h3 schedules

You can disable a schedule and all its actions via disable-schedule:

h3 disable-schedule my-schedule

And finally you can re-enable a schedule via enable-schedule:

h3 enable-schedule my-schedule