Custom frameworks

How a framework Pentr does not ship is added.

Pentr maps findings to the six frameworks listed on Frameworks. The product has no screen or endpoint for defining a framework, uploading one, or changing the controls or tables of a shipped one.

How a framework is loaded

A framework is a YAML file. When a run is sealed, when a report is generated and at every SARIF or CSV download, the application loads <frameworks_dir>/<name>.yaml, where <name> is the engagement's framework value. The six shipped files are soc2, iso27001, ens, pci_dss, owasp_asvs and nist_csf, and those six names are what the New engagement wizard offers.

frameworks_dir is a server setting, PENTR_FRAMEWORKS_DIR, which defaults to report/frameworks in the application. Sealing does not read the setting and always loads from report/frameworks. The directory is part of the application's deployment. No endpoint, console screen or organization setting writes to it.

A framework that does not ship is therefore added to the application itself: a YAML file in report/frameworks/, in the shape below, deployed with the application. The wizard's list of frameworks is fixed in the console, so a new file appears there only when that list names it. The API accepts the name directly.

The file

A complete file with two controls:

framework:
  name: "Example Baseline"
  version: "1.0"
  description: "A two-control example"

controls:
  - id: "EB-1"
    name: "Access control"
    description: "Access to systems is limited to authorized users."
    categories: []
  - id: "EB-2"
    name: "Vulnerability management"
    description: "Known vulnerabilities are identified and remediated."
    categories: []

category_mappings:
  default_credentials: ["EB-1"]
  weak_credentials: ["EB-1"]
  outdated_software: ["EB-2"]
  cve: ["EB-2"]

attack_mappings:
  T1078: ["EB-1"]
  T1110: ["EB-1"]
  T1190: ["EB-2"]

wstg_mappings:
  WSTG-ATHN-02: ["EB-1"]
  WSTG-CONF-02: ["EB-2"]

framework

Required, with three required keys. A file missing any of them fails to load.

  • name — the display name. The PDF's Compliance Crosswalk prints it beside each finding's control ids.
  • version — loaded, and not printed in any output.
  • description — loaded, and not printed in any output.

controls

The list of controls, in the order the report lists them. The report has one row per control declared here.

  • id — required. The value the three mapping tables refer to, and the value printed beside findings.
  • name — required. Printed in the PDF's Control Mappings table.
  • description — required, and not printed.
  • categories — optional. Not used for mapping; see the per-control categories list.

category_mappings

The keyword table. Each key is a category, and its value is a list of control ids. The mapper produces sixteen categories: sql_injection, xss, command_injection, code_injection, open_port, default_credentials, weak_credentials, privilege_escalation, outdated_software, ssl_tls_issue, data_exposure, misconfiguration, authentication_bypass, information_disclosure, cve and malware. A key outside that list is loaded and never matches.

attack_mappings

MITRE ATT&CK technique ids to control ids. Matching is exact, so a sub-technique such as T1110.001 needs a row of its own.

wstg_mappings

OWASP WSTG ids to control ids, matched exactly.

The three tables are optional, and a missing one is treated as empty. The loader does not check that a control id in a table is declared under controls. An undeclared id still appears beside the finding in the report, the exports and the sealed manifest, and it has no row in the Control Mappings table.

The engagement's framework field

An engagement's framework is a string. Creating an engagement through the API does not compare it with the files in the frameworks directory, and no endpoint changes it afterwards. A run whose framework names no file runs normally: the name is written into the rendered rules-of-engagement document, and nothing else in the run reads it back.

The missing file surfaces after the run:

  • Sealing fails when it loads the framework. The failure is logged and the run is left unsealed, so it has no locker to export. See Sealing.
  • Requesting the report fails with a server error, and no report is recorded. SARIF and CSV downloads need a recorded report, so they are refused too.

Last updated 2026-09-24