Skip to content
Closed

chore #122

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ inputs:
hardening-disabled-rules:
description: Comma-separated list of hardening rule IDs to disable
required: false
fail-on-detected-risk:
description: |
When true (the default in prevent mode), fail the step if the cimon agent
reported a detected risk on shutdown — including cases where the rule
fired but the SIGKILL did not land in time (short-lived processes). This
ensures the workflow surface reflects what cimon prevented, instead of
relying solely on the offending process exiting non-zero.
Has no effect in detect mode (prevent=false).
required: false
default: 'true'

runs:
using: node24
Expand Down
40 changes: 40 additions & 0 deletions dist/post/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -127871,6 +127871,46 @@ async function run(config) {
if (retval !== 0) {
throw new Error(`Failed stopping Cimon process: ${retval}`);
}

// If the agent reported a detected risk in prevent mode, surface it as
// a step failure. The offending process may have already exited
// non-zero (in which case the workflow is already red), but a
// sufficiently short-lived process can complete before the kill lands,
// leaving the workflow green even though the rule fired. This check
// closes that gap so the workflow always reflects what cimon prevented.
const failOnDetectedRisk = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getBooleanInput('fail-on-detected-risk');
const preventMode = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getBooleanInput('prevent');
if (failOnDetectedRisk && preventMode) {
const risk = parseDetectedRisks(stopOutput);
if (risk && risk !== 'NoRisk') {
throw new Error(
`Cimon detected a risk in prevent mode (${risk}). See the ` +
`cimon log output and the job summary for the specific rule ` +
`and evidence. Set fail-on-detected-risk: false to disable ` +
`this check.`
);
}
}
}

/**
* Extract the latest `detectedRisks` value from the cimon agent's
* structured-JSON stop output. Returns null if not present.
*
* The agent emits one log line near shutdown shaped like:
* {"level":"info",...,"detectedRisks":"PreventedRisk","message":"Terminating execution"}
*
* In rare cases multiple such lines appear (e.g. multiple executions);
* we take the last one so the most-recent state wins.
*/
function parseDetectedRisks(text) {
const re = /"detectedRisks"\s*:\s*"([^"]+)"/g;
let match;
let last = null;
while ((match = re.exec(text)) !== null) {
last = match[1];
}
return last;
}

/**
Expand Down
40 changes: 40 additions & 0 deletions src/post/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,46 @@ async function run(config) {
if (retval !== 0) {
throw new Error(`Failed stopping Cimon process: ${retval}`);
}

// If the agent reported a detected risk in prevent mode, surface it as
// a step failure. The offending process may have already exited
// non-zero (in which case the workflow is already red), but a
// sufficiently short-lived process can complete before the kill lands,
// leaving the workflow green even though the rule fired. This check
// closes that gap so the workflow always reflects what cimon prevented.
const failOnDetectedRisk = core.getBooleanInput('fail-on-detected-risk');
const preventMode = core.getBooleanInput('prevent');
if (failOnDetectedRisk && preventMode) {
const risk = parseDetectedRisks(stopOutput);
if (risk && risk !== 'NoRisk') {
throw new Error(
`Cimon detected a risk in prevent mode (${risk}). See the ` +
`cimon log output and the job summary for the specific rule ` +
`and evidence. Set fail-on-detected-risk: false to disable ` +
`this check.`
);
}
}
}

/**
* Extract the latest `detectedRisks` value from the cimon agent's
* structured-JSON stop output. Returns null if not present.
*
* The agent emits one log line near shutdown shaped like:
* {"level":"info",...,"detectedRisks":"PreventedRisk","message":"Terminating execution"}
*
* In rare cases multiple such lines appear (e.g. multiple executions);
* we take the last one so the most-recent state wins.
*/
function parseDetectedRisks(text) {
const re = /"detectedRisks"\s*:\s*"([^"]+)"/g;
let match;
let last = null;
while ((match = re.exec(text)) !== null) {
last = match[1];
}
return last;
}

/**
Expand Down
Loading