Skip to content

Commit 9c4223a

Browse files
committed
fixup! fixup! feat: add git node security --validate-reports
1 parent 35bd1bc commit 9c4223a

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

components/git/security.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ const securityOptions = {
8282
describe: 'Override the command used for --llm. The report prompt is sent on stdin.',
8383
type: 'string'
8484
},
85+
'llm-allow-paid-usage': {
86+
describe: 'Allow LLM providers that may incur token-based charges without prompting',
87+
type: 'boolean'
88+
},
8589
'node-repo': {
8690
default: process.cwd(),
8791
describe: 'Node.js checkout path the LLM should use to read SECURITY.md and doc/',

docs/git-node.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ only a local triage aid and still requires human review.
527527
git node security --validate-reports --llm=codex --llm-model=gpt-5.5
528528
git node security --validate-reports --llm=codex --no-validate-reports-confirm
529529
git node security --validate-reports --llm=codex --no-validate-reports-cache
530+
git node security --validate-reports --llm=codex --llm-allow-paid-usage --no-validate-reports-confirm
530531
git node security --validate-reports --llm=claude --node-repo=/path/to/node
531532
git node security --validate-reports --llm=copilot --node-repo=/path/to/node
532533
git node security --validate-reports --llm=copilot --llm-command="copilot -p"
@@ -570,6 +571,11 @@ then asks whether to continue to the next report. Use
570571
Use `--validate-reports-limit=<n>` to test the flow against a smaller number of
571572
reports.
572573

574+
Some LLM providers or custom commands may incur token-based charges beyond a
575+
regular subscription. The command asks for confirmation once before running those
576+
providers. Batch runs with `--no-validate-reports-confirm` must also pass
577+
`--llm-allow-paid-usage`.
578+
573579
#### LLM prompt and reasoning
574580

575581
The LLM prompt is designed to keep the model anchored to the Node.js threat
@@ -640,6 +646,7 @@ assessment.
640646
| `--llm=none\|codex\|claude\|copilot` | Print prompts for manual LLM use or ask an LLM CLI to assess each report. Defaults to `none`. |
641647
| `--llm-model=<model>` | Override the provider model and cache identity. |
642648
| `--llm-command=<command>` | Override the command used for LLM assessment. The prompt is sent on stdin. |
649+
| `--llm-allow-paid-usage` | Allow providers or custom commands that may incur token-based charges without prompting. Required for non-interactive paid-usage runs. |
643650
| `--node-repo=<path>` | Path to a Node.js checkout containing `SECURITY.md` and `doc/`. Defaults to the current directory. |
644651

645652
## `git node status`

lib/validate_reports.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const H1_TRIAGED_REPORTS_URL =
1717
const CACHE_FOLDER = '.ncu-cache/security-report-validation';
1818
const MANUAL_REVIEW_VALIDITY = 'needs-manual-review';
1919
const MANUAL_LLM_PROVIDER = 'none';
20+
const PAID_USAGE_LLM_PROVIDERS = new Set(['codex', 'claude']);
2021

2122
const CVSS_WEIGHTS = {
2223
AV: { N: 0.85, A: 0.62, L: 0.55, P: 0.2 },
@@ -855,6 +856,37 @@ function buildProviderCommand(provider, nodeRepo, commandOverride, model) {
855856
}
856857
}
857858

859+
function llmMayUsePaidTokens(provider, commandOverride) {
860+
return provider !== MANUAL_LLM_PROVIDER &&
861+
(commandOverride || PAID_USAGE_LLM_PROVIDERS.has(provider));
862+
}
863+
864+
async function confirmPaidLLMUsage(provider, argv, cli) {
865+
if (!llmMayUsePaidTokens(provider, argv['llm-command']) ||
866+
argv['llm-allow-paid-usage']) {
867+
return;
868+
}
869+
870+
const message = argv['llm-command']
871+
? 'The configured --llm-command may incur token-based usage charges. Continue?'
872+
: `${provider} may incur token-based usage charges beyond a regular ` +
873+
'subscription. Continue?';
874+
875+
if (!argv['validate-reports-confirm']) {
876+
throw new Error(
877+
'LLM provider may incur token-based usage charges. Pass ' +
878+
'--llm-allow-paid-usage to run non-interactively.'
879+
);
880+
}
881+
882+
const confirmed = await cli.prompt(message, {
883+
defaultAnswer: false
884+
});
885+
if (!confirmed) {
886+
throw new Error('LLM assessment cancelled by user');
887+
}
888+
}
889+
858890
function printLLMPrompt(result, prompt, cli) {
859891
cli.separator(`H1 ${result.id} LLM Prompt`);
860892
cli.log([
@@ -1100,6 +1132,8 @@ async function assessReportsWithLLM(reports, results, argv, cli) {
11001132
);
11011133

11021134
try {
1135+
await confirmPaidLLMUsage(provider, argv, cli);
1136+
11031137
for (let i = 0; i < reports.length; i++) {
11041138
const shouldContinue = await assessOneReportWithLLM({
11051139
report: reports[i],

0 commit comments

Comments
 (0)