Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 44
Development Guide
Welcome to the toolkit development guide!
The Kenna toolkit is a consolidated toolkit of functions for security professionals using Kenna and intended to be run in a docker container in production. During development, however, most developers prefer to set up an environment on their local system.
- you should have a ruby setup, preferably set up with rbenv. The current Ruby version used by the connector is 3.2.2.
- in the toolkit directory, install bundler using the command
gem install bundler - install the dependencies using bundler
bundle install
docker build . -t toolkit:latest
docker run -v $(pwd):/opt/app/toolkit --rm -it --entrypoint bash toolkit
A good place to start with development on the toolkit is by looking at the example task. Two methods matter:
self.metadata: a method on the Task class, which self-describes how the task can be used, and what options it takesrun: the method that operates on the data it's passed.
One easy thing to do for new developers is to copy the toolkit/tasks/connectors/_sample_task folder to a new folder and adjust the name of the folder and the task (which should always match) to something like 'hello'. This creates a new task that is automatically available in the toolkit and can be called simply by running (in the root)
bundle exec ruby ./toolkit.rb task=hello
We recommend splitting the code into 2 sections: the Task itself and an APIClient.
The APIClient is responsible only for interactions with the service (scanner) to obtain the data needed by the task.
The APIClient can also format the obtained data to ease the Task process. The Task is responsible for the
creation of Kenna objects, upload, and execution of Kenna processes.
The common folder layout is this:
|-- sample_task
| |-- lib
| | |-- sample_api_client.rb
| | |-- sample_custom_helpers.rb
| |-- sample_readme.md
| |-- sample_task.rb
sample_task.rbis expected to contain yourTaskclass which defines therunandself.metadatamethods.sample_readme.mdis the connector's documentation markdown file.- The
libfolder is where client classes and helper modules live.
We recommend balancing the code in several methods avoiding putting too much in the main run method.
The following is a simplified and fully commented code snippet of the entire process and can be used as guideline:
defruninitialize_options# Process set options from command line parametersclient=Client.new(user_id,user_token)# Instantiate the client using options passed as parameterspage=1loopdopage_data=client.get_page(page)# Get data from the client in batchespage_data.eachdo |issue| # For each resulting issue ...asset=extract_asset(issue)# Builds an asset for Kennafinding=extract_finding(issue)# Builds the finding (issue) object for Kennadefinition=extract_definition(issue)# Builds the issue definition (unique definitions)create_kdi_asset_finding(asset,finding)# Creates the association in current Kenna batchcreate_kdi_vuln_def(definition)# Creates the definition (deduplicated) in current Kenna batchend# Below line uploads current batch to Kennakdi_upload(@output_directory,"report_#{page}.json",@kenna_connector_id,@kenna_api_host,@kenna_api_key,@skip_autoclose,@retries,@kdi_version)breakifpage_data.empty?# Stop loop if there is no more datapage += 1end# Below line starts the import process in Kenna for all uploaded batcheskdi_connector_kickoff(@kenna_connector_id,@kenna_api_host,@kenna_api_key)rescueApiError=>e# Api exception handler for the entire processfail_taske.messageendIn the example above the methods extract_asset, extract_finding and extract_definition should return a hash with JSON data in the format specified by the KDI Json Format.
Depending on the final destination for the data upload, you need to use one of create_kdi_asset_finding or create_kdi_asset_vuln helper methods.
Please, refer to the provided sample for specific details on Client implementation, exception handling, and log tracing.
The connector process runs in a constrained environment and must wisely use the memory and processor resources, making use of batching or pagination techniques.
Usually batch_size and/or page_size are added to the connector parameters with common defaults, normally a number between 100 and 500. In the code, these parameters should be used to split API calls to the source application as well as Kenna, contributing this way to memory usage reduction on both ends.
The Toolkit provides several helper methods included in the Kenna::Toolkit::BaseTask class, which is the common ancestor for Task classes.
classBaseTaskincludeKenna::Toolkit::HelpersincludeKenna::Toolkit::KdiHelpers
...
endYou can find the source code in toolkit/lib/helpers.rb and toolkit/lib/kdi/kdi_helpers.rb.
Most commonly used methods in Helpers are:
print(message = nil)# Log useful informationprint_good(message = nil)# Log something was successfullprint_error(message = nil)# Log and error (doesn't break task execution)print_debug(message = nil)# Log message only if@options[:debug] == truefail_task(message)# Log message as error and terminate execution returning a non zero exit coderemove_html_tags(string)# Return the argument string whithout any html tags
Most commonly used methods in KdiHelpers are:
create_kdi_asset(asset_hash)# Create kdi asset with the hash argument and keep it in memory up to next uploadcreate_kdi_asset_vuln(asset_hash, vuln_hash)# Create kdi asset with associated vulncreate_kdi_asset_finding(asset_hash, finding_hash)# Create kdi asset with associated findingkdi_upload(output_dir, filename, kenna_connector_id, ...)# Upload the current batch of assets, vulns and findings to Kennakdi_connector_kickoff(kenna_connector_id, kenna_api_host, ...)# Instruct Kenna to process all previous pending uploads
Follow instructions in the README.md to submit a pull request. Your PR will get merged faster if all checks pass! Please ensure you've covered your change sufficiently with specs.
- Mock out all web requests using webmock
- Follow the spec guidelines on betterspecs.org
- See the existing specs for examples of connector specs.