Script Context

Your script is handed a context object with which you will make your post-processing status and comment recommendations. It is always named ctx and is either a check-level context or a command-level context. Both share most of the same functionality in context.Context.

Check-Level Context

class context.CheckItemContext(cursor, item_id: str)

Bases: Context

Scan item (Check) level PP specific parts of a context.

Used when processing all values under a single scan item.

consolidate_value_additional_outputs() Dict

Reads all values under this check item and returns their additional outputs

  • Note that this does not set this item’s additional_output directly, you must do so yourself if you want (ctx.additional_output = ctx.consolidate_value_additional_outputs())

  • The value order should be treated as random–if two values set the same additional output, the latter will be accepted returned.

  • Exceptions are skipped. They should be checked with by looping over ctx.values() and checking value.has_exception() individually

  • Recommended comments and statues are treated specially and combined:

    • The child recommended comments are de-duplicated and joined into a list.

    • For status, we take the high-water mark, where the priority is:
      • NA

      • Noncompliant

      • Compliant

      • Manual review

is_check_level() bool

See Context.is_check_level

Command-Level Context

class context.CommandValueContext(cursor, value_id: str)

Bases: Context

Command-level PP specific parts of a context.

Used when processing a single command output value.

is_check_level() bool

See Context.is_check_level

Common Context

class context.Context(cursor: sqlite3.Cursor, *, value_id: str | None = None, item_id: str | None = None, scan_id: str | None = None)

Bases: object

All data needed to perform post processing

An instance of this is passed in to the postprocessing script with the variable name ctx. Virtually all scripts need access to the command output. Use raw for this value (i.e., ctx.raw in your script).

Constructed with a database cursor from which scan, item, and value data are lazily loaded on first access.

add_additional_output(name: str, output: str)

Similar to set_additional_output, but rather than creating a new data column, this adds more items to an existing column, or creates a new column with the data provided if one does not yet exist.

Parameters:
  • name – A free-form name to use for this data. Xylok internally uses names that begin with an underscore (_), so using names that begin this way may conflict with internal operation and may change without notice. If appending data to an existing key, make sure to use that name.

  • output – A string to use for this additional output. This string may appear in reports and spreadsheets, so nonprintable characters should be avoided.

add_software_item(name, version: str | None = '')

Add a software item (name and version).

answer(name: str, default: str | None = None) str | None

Returns the answer to the question as a string

Questions may come from the runner, execution environment, or benchmark. Answers are generally user supplied. If a user has not answered a question, the value given for default will be returned.

Parameters:

default – Value to return if there is no answer.

Returns:

Question answer if available or default if not

answer_is_false(name: str) bool

Check if the answer is vaguely “False.”

Accepted False values, case insensitive: - “false” - “no” - “n”

Returns:

True if the answer is falsey

answer_is_true(name: str) bool

Check if the answer is vaguely “True.”

Accepted True values, case insensitive: - “true” - “yes” - “y”

Returns:

True if the answer is truthy

property answers: Dict[str, str]

Dictionary of question processing_id -> answer for the runner, execution environment, and/or benchmark.

Prefer using answer() rather than accessing this directly.

For more specific information, open a scan for one of your devices and find the OS-BL-0000001 check. A fake interview question is included which displays the metadata available at the command and check levels.

clear_output()

Clears all output and additional output from PP script

property client: box.Box | None

Client this scan belongs to.

Fields include (but are not limited to):

  • is_classified - Boolean–if true, this network is classified

  • c_level - string “low,” “medium,” or “high”

  • i_level - string “low,” “medium,” or “high”

  • a_level - string “low,” “medium,” or “high”

Prefer using target for new code

Deprecated since version 2026.1.

property date: datetime | None

Return the date of the scan if available, otherwise returns today’s date.

Parameters:

fallback – bool: If False, don’t fallback to returning today’s date and instead return None

Returns:

Datetime of scan

get_additional_output()

Returns all additional outputs set for this context

Returns the current comment recommendation

None if not set

Returns the current status recommendation

None if not set

property human_id: str | None

ID of the check being performed (i.e. ‘RHEL-07-010118’), from stig_check__nist_stig_id.

ics: str = '***XYLOK ICS***'

Default ICS separator between multiple commands in a single raw output Can be manually set if needed for an individual script

ics_split(idx=None, *, ics=None, splitlines: bool = False) str | List[str]

Split raw output based on ctx.ics

If given an index, returns only that instance of the split. If not, returns a list of the raw output split by the ics.

If ics is given in this call, it will be set to ctx.ics and reused on the next call.

Parameters:

splitlines – If True, each ICS group will have splitlines() called on it, resulting in a list of strings for each output section.

Returns:

raw output at the given ICS separator or a list of all raw outputs based on the separator

is_check_level() bool

Lets a PP script check if it is running at as a check-level (scan item) or a value level (command value)

Returns:

True if at the check level

property questions: Dict[str, str]

Returns all questions and answers as a dictionary of processing_id -> answer

Returns:

Dictionary of all questions for this runner. It is recommended to use answer() instead, as it is more efficient and clearer.

property raw: str

Get the raw output for this command

Returns:

string version of the raw output of this command

recommend_comment(comment: str | List[str], issues: List[str] | None = None)

Recommend a comment for this check

Typically this is only used indirectly through the other recommend_* functions.

An optional recommended comment and “issue” list may be given, where the final user-seen comment will be of the form:

<comment>
- <issue 0>
- <issue 1>
- <issue 2>
- ...

For backwards compatibility, if comment is a list instead of a string, it will be used as the issue list and the header comment will be roughly “The following items were found which may have contributed to this item’s status:”

recommend_compliant(comment: str | List[str] = None, issues: List[str] | None = None)

Recommend this check be marked “compliant” (not a finding)

An optional recommended comment may be given, typically a reason why this check is compliant. In addition, a list of “issues” may be given, which might be multiple items that contributed to this status. See recommend_comment() for more details.

recommend_manual_review(comment: str | List[str] = None, issues: List[str] | None = None)

Recommend this check be reviewed manually

An optional recommended comment may be given, typically a reason why this check isn’t answerable automatically. In addition, a list of “issues” may be given, which might be multiple items that contributed to this status. See recommend_comment() for more details.

recommend_na(comment: str | List[str] = None, issues: List[str] | None = None)

Recommend this check be marked “not applicable”

An optional recommended comment may be given, typically a reason why this check isn’t applicable. In addition, a list of “issues” may be given, which might be multiple items that contributed to this status. See recommend_comment() for more details.

recommend_noncompliant(comment: str | List[str] = None, issues: List[str] | None = None)

Recommend this check be marked “non-compliant” (a finding)

An optional recommended comment may be given, typically a reason why this check isn’t compliant. In addition, a list of “issues” may be given, which might be multiple items that contributed to this status. See recommend_comment() for more details.

recommend_status(status, comment: str | List[str] = None, issues: List[str] | None = None)

Set the recommended status for this check explicitly

Generally other recommend_* calls are used in scripts.

See recommend_comment() for information on comment and issues.

property scan: Dict | None

Scan metadata dict. Loaded from the database on access.

Fields include (but are not limited to):

  • date - Date the scan was run

  • pk / id - Scan identifier

For more specific information, open a scan for one of your devices and find the OS-BL-0000001 check. A fake interview question is included which displays the metadata available at the command and check levels.

set_additional_output(name: str, output: str)

Set an additional data column

Parameters:
  • name – A free-form name to use for this data. Xylok internally uses names that begin with an underscore (_), so using names that begin this way may conflict with internal operation and may change without notice.

  • output – A string to use for this additional output. This string may appear in reports and spreadsheets, so nonprintable characters should be avoided.

set_device_manufacturer(manufacturer)

Set the make (manufacturer) for the device.

set_device_model(model)

Set the model for the device.

set_host_name(host_name)

Set the name for the device.

set_ip_address(ip_address)

Set the ip address(es) for the device.

set_mac_address(mac_address)

Set the mac address(es) for the device.

set_os_key(os_key)

Set the OS for the device.

set_pps_information(pps_information)

Get ports, protocols, & services information for the device.

set_serial_number(serial_number)

Set the serial_number for the device.

property target: box.Box | None

Metadata for this scan’s target

For more specific information, open a scan for one of your devices and find the OS-BL-0000001 check. A fake interview question is included which displays the metadata available at the command and check levels.

value(tag: str = '') CommandValue | None

Single Value under this item (or parent item, if called from a command-level PP)

If tag is given, the values considered are filtered to that tag. If more than one value matches, the first is returned.

Primarily used for check-level PP, but a command level can use it if useful.

Returns:

Single matching value or None if not found

values(tag: str = '') List[CommandValue]

Values under this item (or parent item, if called from a command-level PP)

If tag is given, the list is filtered to values with that tag

Primarily used for check-level PP, but a command level can use it if useful.

Returns:

List of matching values (list is empty if none match)

Additional Helpers and Constants

class context.CommandValue(id: str, item_id: str, pp_script: str, tags: List[str], raw_output: str, is_processed: bool, pp_output: str, additional_output: Dict[str, str])

A command value is the output and metadata information for a single command

Returns the current comment recommendation

None if not set

Returns the current status recommendation

None if not set

has_exception() bool

Returns True if the command PP failed with an exception

has_tag(tag: str) bool

Check if the given tag matches this command value

context.CommentKey = '_recommendation_comment'

additional_output key used for the recommended comment

context.ExceptionKey = '_exception'

additional_output key used for a captured exception

context.StatusCompliant = 'compliant'

Value used in the recommended status (StatusKey) for a compliant recommendation

context.StatusKey = '_recommendation_status'

additional_output key used for the recommended status

context.StatusManual = 'needs_manual_review'

Value used in the recommended status (StatusKey) for a “needs human manual review” recommendation

context.StatusNA = 'not_applicable'

Value used in the recommended status (StatusKey) for an NA recommendation

context.StatusNoncompliant = 'noncompliant'

Value used in the recommended status (StatusKey) for a non-compliant recommendation