Skip to main content

An alternative CLI and API-Client for sysReptor

Project description

repctl - a CLI for SysReptor

repctl is a CLI tool for sysreptor.

Note that there is the reptor CLI from the creators of SysReptor which has a lot more features, but doesn't cover the specific use-case the author faced. repctl might eventually catch up, but no promises! 😜

Brought to you by Mint Secure GmbH

This tool was developed during an internship at Mint Secure. Thanks for open-sourcing it!

Configuration

repctl needs a SysReptor api-key to access your instance. You can pass it via --api-key to any command or set an API_KEY environment variable. To make this convenient, repctl loads environment variables from a .env file in the current working directory or from ~/.config/repctl.env.

Features / Use-Case / Motivation

At the moment repctl serves a very specific use-case:

Finding Templates are created from markdown files containing frontmatter.

These finding templates are used when automatically creating findings from tool outputs. (For now, ScubaGear is the only supported tool, more to come in the future).

Loading templates

$ repctl load-templates --help
                                                                                                                                         
usage: repctl load-templates [-h] reptorurl input

positional arguments:
  reptorurl   BaseUrl of SysReptor Instance, e.g.: https://sysreptor.example.com
  input       Snippet file or directory containing snippets (searched recursively for .md files)

options:
  -h, --help  show this help message and exit

This is mostly interesting if you want to maintain your finding templates as code, or you want to automate deriving finding templates from some other source. You can manually or programmatically prepare your finding templates as markdown files with front matter - which we will hereafter call snippet files - and then load (and update) them into SysReptor using repctl. Details on the format of these markdown files will follow shortly.

Prerequisites

You will need at least one SysReptor Design that defines a finding field called repctlTemplateId. This is needed so repctl can correlate the finding template in SysReptor with your markdown files when loading updates.

Format of Snippets

Let's look at a snippet file:

---
templateId: cve-2025-999   # Used to support updates and multiple languages 
lang: en-US   # Snippets with the same id are aggregated to support multiple languages 
isMain: true  
sysReptorFields: 
  reptorField1: 42
  reptorField2: true
title: The title of your Template
tags:
 - tag1
annotations:  # Dedicated space for your own metadata, repctl ignores this
  metaFiled: metadata
contentField: myDescription  # The markdown below is loaded into this field
---

## Hello World!

Markdown goes here !

Since are reading this, you are probably already familiar with SysReptor templates, so much of the yaml fields in the front matter should make sense to you.

The more interesting parts are these:

If you load multiple snippet files with the same templateId simultaneously, repctl will aggregate them into one finding template. There may only be one snippet with isMain set to true and every language should of course only be used once for any given templateId.

repctl load-templates will recursively scan for .md files when passed a directory!

The created / updated finding template will contain all fields in sysReptorFields, the repctlTemplateId field and additionally a field with the key specified in contentField. The value of that field is the markdown body of the snippet. So our example snippet would look like this when represented as json:

{ 
    "reptorField1": 42,
    "reptorField2": true,
    "myDescription": "## Hello World\nMarkdown goes here!\n",
    "repctlTemplateField":"cve-2025-999-7ae1fdaa9ec020aa0a030c1135768d2012faf888"
}

[!IMPORTANT]
Any fields you specify in your snippets must exist as finding fields in at least one design before loading them! Otherwise, SysReptor discards them.

Loading ScubaGear findings into a SysReptor Project

$ repctl load-findings scubagear --help
usage: repctl load-findings scubagear [-h] [--lang LANG] project_url input

positional arguments:
  project_url  URL of the project on your SysReptor instance. (Simply copy it from your browser!)
  input        Input file: ScubaResults_<id>.json

options:
  -h, --help   show this help message and exit
  --lang LANG  Language code to use for templates, default: de-DE

Create a project in your SysReptor Instance and copy the url from your browser. It doesn't matter in what exact part of the UI you are on, repctl parses the URL, extracts the project id and extrapolates the api url for your instance.

Then all you have to do is pass the url and the ScubaResults_<id>.json from your ScubaGear outputs.

[!IMPORTANT]
You will need to create and load finding templates for all ScubaGear Policies and PolicyGroups before you can load a ScubaGear result. More Details below.

Details for ScubaGear

Pseudo-Findings

The policies checked by ScubaGear policies are organized in groups. repctl creates a "pseudo" finding for every group, which you can use to include information about the policy group in your report. If no template with an appropriate templateId exists, this step will be skipped.

templateIds

The ScubaGear loader expects to find a finding template with templateId
scubagear-<policy id> for every policy checked by the ScubaGear scan, e.g.:
scubagear-MS.SHAREPOINT.4.2v1.

For the group pseudo-findings, the expected templateId is:
scubagear-<lowercase product>-<group id>, e.g.:
scubagear-powerplatform-3.

Finding Fields

The ScubaGear loader populates the following fields, they are "added" and potentially override those you specified in your finding templates:

criticality, result, details

If you are familiar with ScubaGear, you should know what they mean.

Implementation Details

The repctlTemplateId field

SysReptor doesn't allow you to specify your own IDs for templates, The "real" ids are generated upon creation by the server. To allow repctl to find the right templates, it leverages the "search" feature of the template API. It stores the templateId as this "special" field and uses it as the search query when updating or creating findings from the template.

To avoid unfortunate collisions, like for example a chosen templateId also appearing in a field of another template and thus making the search-result non-unique, repctl appends the sha1-hash of the templateId to itself before storing it as repctlTemplateId. When searching for a template id, it computes the hash again and submits it as the search query.

Creating loaders for more tools

There is an interface for finding loaders in repctl.findings. Feel free to contribute. We might also add a full-blown plugin-interface at some point.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

repctl-0.1.0.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

repctl-0.1.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file repctl-0.1.0.tar.gz.

File metadata

  • Download URL: repctl-0.1.0.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for repctl-0.1.0.tar.gz
Algorithm Hash digest
SHA256 613ae356100a0cc86e80277daa076001db211252fe7fc26d76d4ad0589324159
MD5 c9d116969b450bc4a93278665dc7e2d1
BLAKE2b-256 06fbbd56bb7c31e3a0a4207e4202c90b1b913dc1eff70e98b4324fddbb70f805

See more details on using hashes here.

File details

Details for the file repctl-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: repctl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for repctl-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a3aa4409cdf6990207e680902d29c2e32b8eceec5c27e502dc6fa3d54adae1d
MD5 33db5695dc6fa1ff5ea178a1ff21f8fa
BLAKE2b-256 500897460caaba2c7ad5b0f1e589b5d55251c544d04fe2180bc6a585396edc92

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page