Input contract
Transport
- Standard input only - The Runner MUST supply input as a single JSON document over the interpreter’s
stdin. No other channels (for example, command‑line arguments, files, environment variables) MAY be used for step‑specific data. - Single document - Exactly one document MUST be provided. Streaming multiple JSON documents or concatenated commands is forbidden.
- UTF‑8 encoding - The JSON document MUST be encoded as UTF‑8.
- No framing layer - The Runner MUST NOT send any framing bytes (length prefixes, newline delimiters, and more) outside of the JSON document itself.
Structure of the interpreter command/invocation contract
This section defines the Runner to Interpreter invocation contract, which is transmitted as a single JSON document through standard input. The contract is intentionally split into two parts:
- Runner-defined envelope fields that are stable across all interpreters and provide consistent execution semantics.
- An interpreter-defined
commandobject whose structure, validation rules, and semantics are defined by the selected interpreter.
An interpreter MUST treat all fields outside command as belonging to the Runner-defined envelope. An interpreter MUST treat the command field as interpreter-specific and MUST validate it according to the interpreter’s published contract discovery specification (refer to the Interpreter discovery section for further details).
Top-level object
The input document MUST be a JSON object with the following fields.
Required fields
nameThe fully qualified interpreter name (for example,chef-platform/inspec-interpreter).inputsA key value map used to indicate the values from the job context being presented to the interpreter. They MAY use variable substitution, environment variables, and/or templating of step-scoped values. Values MAY be any JSON type, but interpreters SHOULD treat them as data inputs rather than executable content.commandThe interpreter-specific command payload. The schema of this object is defined by the interpreter.
Optional fields
skillSkill version constraints used by the Runner to select an installed skill package. This field is part of the Runner envelope and isn’t interpreter-defined.minVersion,maxVersionInterpreter compatibility constraints. These values define a compatibility window for the interpreter implementation the Runner selects. They’re part of the Runner envelope.runContextExecution context metadata supplied by the Runner (job identifiers, node identifiers, correlation identifiers, timestamps, and environment descriptors). Interpreters MAY use this for logging and correlation, but MUST NOT treat it as authoritative policy.outputFieldRulesOptional output extraction and transformation rules supplied by the Runner. This field describes how the Runner will extract values from step results and store them in the job context for subsequent steps. It’s part of the Runner envelope.expectedInputsOptional input schema and validation metadata supplied by the Runner. This field declares which job context variables are expected to exist for the step and how they should be interpreted by the Runner. It’s part of the Runner envelope.limitsOptional resource constraints, including timeout and other execution caps. The Runner enforces limits. Interpreters MAY use this information for internal guardrails but MUST NOT assume that the Runner will permit execution beyond defined limits.accessModeOptional execution access mode (for example,agentoragentless) used by the Runner and interpreter to determine execution and command restrictions when supported.
Interpreter-defined command
The command field is the only portion of the input contract whose internal structure is defined by the interpreter.
- The interpreter MUST define the schema for
commandand publish it through the interpreter contract discovery mechanism in the Interpreter discovery section. - The interpreter MUST validate
commandaccording to its published schema. - The interpreter SHOULD return a clear diagnostic error when validation fails.
The command value MAY be a JSON object, array, or string if the interpreter’s contract permits it. The interpreter’s contract discovery output is authoritative for the allowed structure.
Example interpreter invocation contract
The following example illustrates the complete invocation contract for an interpreter. The command section is interpreter-specific; all other fields are part of the Runner envelope.
# Complete interpreter invocation contract (example)
name: "chef-platform/example-interpreter"
skill:
minVersion: "1.0.0"
maxVersion: "2.0.0"
minVersion: "1.0.0"
maxVersion: "2.0.0"
inputs:
profile_path: "/tmp/compliance-profiles/cis-linux"
report_dir: "/tmp/inspec-reports"
control_id: "CIS-1.2.3"
waiver_id: "waiver-2024-001"
port: 22
enable_cache: true
command:
command: "exec"
profile: "{{profile_path}}"
target: "{{target_host}}"
backend_cache: "{{enable_cache}}"
controls:
- "{{control_id}}"
reporter:
- "cli"
- "json:{{report_dir}}/report-{{control_id}}.json"
input_file:
- "/tmp/inputs/production.yml"
waiver_file:
- "/tmp/waivers/{{waiver_id}}.yaml"
attributes:
environment: "production"
compliance_level: "high"
runContext:
jobId: "job-12345-abcdef"
environment: "production"
correlationId: "corr-67890"
nodeId: "node-linux-web-01"
timestamp: "2024-12-16T10:30:00Z"
outputFieldRules:
requiredFields:
- "status"
- "output"
fieldTypes:
status: "integer"
output: "object"
transformations:
reportPath: "output.report_file"
expectedInputs:
requiredInputs:
- "profile_path"
- "target_host"
optionalInputs:
- "controls"
- "reporter"
- "waiver_file"
inputSchema:
profile_path:
type: "string"
required: true
description: "Path to InSpec compliance profile"
pattern: "^/.*"
target_host:
type: "string"
required: true
description: "Target host in URI format"
pattern: "^(ssh|winrm|docker)://.*"
enable_cache:
type: "bool"
required: false
default: true
description: "Enable backend caching"
limits:
timeout: 300
maxMemory: "512MB"
maxCPU: "1.0"
maxDiskIO: "100MB/s"
accessMode: "agent"
Command payload examples
Shell interpreter command
The Shell interpreter executes commands on Linux and Windows nodes. The Courier documentation specifies that a job step using the Shell interpreter includes a command object with OS‑specific arrays of commands: linux and windows. An Interpreter Command payload for the Shell interpreter therefore has the form:
{
"Interpreter": {"Name": "shell-interpreter"},
"Context": {},
"Timeout": 120,
"Command": {
"linux": ["sleep 10"],
"windows": ["echo 'hello'"],
"dir": "/tmp", // Optional working directory (overrides default)
"expectedInputs": {},
"outputFieldRules": {}
}
}
The arrays of strings under linux and windows correspond to the syntax defined in the Shell interpreter documentation. The optional dir field allows overriding of the default working directory.
InSpec interpreter command
The Chef InSpec interpreter integrates with Chef InSpec for audit scans. The example below would invoke an InSpec audit with a scan command and arguments such as path to the profile. An Interpreter command payload might look like:
{
"Interpreter": {"Name": "inspec-interpreter"},
"Context": {},
"Timeout": 600,
"Command": {
"exec": "scan",
"args": {
"path": "https://github.com/dev-sec/ssh-baseline",
"waiver": null,
"input": null,
"username": null,
"token": null,
"source": null,
"sourceURL": null,
"reporterType": "json",
"reporterFileName": "scan-report.json",
"licenseKey": null,
"licenseServer": null,
"minSuccess": 90
}
}
}
Arguments correspond to the fields documented in the Chef InSpec interpreter description. The interpreter must validate required fields (for example, path) and ignore unknown fields unless strict mode is enabled.
Generic ping interpreter
The skeleton repository provides an example of a networking interpreter that performs a ping test. Its command payload might resemble:
{
"Interpreter": {"Name": "ping-interpreter"},
"Context": {},
"Timeout": 30,
"Command": {
"host": "example.com",
"count": 5,
"timeout": 10,
"packet_size": 64,
"interval": 1,
"ttl": 64
}
}
This command instructs the interpreter to ping example.com five times with a 10‑second timeout for each ping, 64‑byte packets, 1‑second intervals, and a Time To Live (TTL) of 64. Interpreters must document their schema and validate numeric ranges accordingly.
Unknown fields and versioning
Interpreters SHOULD ignore unknown fields in Command, Interpreter, or Context. They MAY fail on unknown fields if strict validation is desirable. Explicit protocol versioning isn’t included in this specification; compatibility is implicitly bound to the job definition version. Future revisions may introduce a Version field if necessary.