infraweaver 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +244 -0
- package/dist/agents/claude.d.ts +113 -0
- package/dist/agents/claudePretoolGate.d.ts +137 -0
- package/dist/agents/dispatchMetrics.d.ts +77 -0
- package/dist/agents/gateServer.d.ts +7 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/nativeFsDenies.d.ts +46 -0
- package/dist/agents/opencode.d.ts +284 -0
- package/dist/agents/opencodePlugin.d.ts +96 -0
- package/dist/agents/opencodeShared.d.ts +40 -0
- package/dist/agents/postRun.d.ts +126 -0
- package/dist/agents/reviewer.d.ts +41 -0
- package/dist/agents/sessionLabeler.d.ts +97 -0
- package/dist/agents/shared.d.ts +246 -0
- package/dist/agents/subagentModels.d.ts +19 -0
- package/dist/agents/tokenQuota.d.ts +118 -0
- package/dist/agents/writeGateSource.d.ts +22 -0
- package/dist/agents/writePolicy.d.ts +79 -0
- package/dist/brand.d.ts +67 -0
- package/dist/cli.mjs +247846 -0
- package/dist/external.d.ts +227 -0
- package/dist/i18n/scaffolding.d.ts +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +247061 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal.js +2398 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/main.d.ts +8 -0
- package/dist/mcp/arkConfig.d.ts +1 -0
- package/dist/mcp/assess.d.ts +157 -0
- package/dist/mcp/capabilityContext.d.ts +71 -0
- package/dist/mcp/changeSummary.d.ts +52 -0
- package/dist/mcp/checkSuite.d.ts +27 -0
- package/dist/mcp/checkout.d.ts +92 -0
- package/dist/mcp/comment.d.ts +127 -0
- package/dist/mcp/commitInfo.d.ts +11 -0
- package/dist/mcp/crosswalk.d.ts +178 -0
- package/dist/mcp/crosswalkDigest.d.ts +1 -0
- package/dist/mcp/cyberEssentials.d.ts +24 -0
- package/dist/mcp/dashboard.d.ts +125 -0
- package/dist/mcp/dependencies.d.ts +12 -0
- package/dist/mcp/frameworks.d.ts +74 -0
- package/dist/mcp/geminiSanitizer.d.ts +28 -0
- package/dist/mcp/git.d.ts +60 -0
- package/dist/mcp/guardrails.d.ts +222 -0
- package/dist/mcp/issue.d.ts +20 -0
- package/dist/mcp/issueComments.d.ts +11 -0
- package/dist/mcp/issueEvents.d.ts +11 -0
- package/dist/mcp/issueInfo.d.ts +11 -0
- package/dist/mcp/labels.d.ts +14 -0
- package/dist/mcp/localContext.d.ts +26 -0
- package/dist/mcp/moduleExtraction.d.ts +79 -0
- package/dist/mcp/moduleTests.d.ts +106 -0
- package/dist/mcp/modules.d.ts +198 -0
- package/dist/mcp/output.d.ts +16 -0
- package/dist/mcp/pathSafety.d.ts +14 -0
- package/dist/mcp/policy.d.ts +50 -0
- package/dist/mcp/pr.d.ts +64 -0
- package/dist/mcp/prInfo.d.ts +11 -0
- package/dist/mcp/providerSchema.d.ts +52 -0
- package/dist/mcp/review.d.ts +212 -0
- package/dist/mcp/reviewComments.d.ts +245 -0
- package/dist/mcp/roots.d.ts +60 -0
- package/dist/mcp/scope.d.ts +26 -0
- package/dist/mcp/selectMode.d.ts +20 -0
- package/dist/mcp/server.d.ts +61 -0
- package/dist/mcp/shared.d.ts +62 -0
- package/dist/mcp/shell.d.ts +58 -0
- package/dist/mcp/staleFix.d.ts +138 -0
- package/dist/mcp/terraform/azurePrices.d.ts +8 -0
- package/dist/mcp/terraform/baseline.d.ts +57 -0
- package/dist/mcp/terraform/concernResult.d.ts +38 -0
- package/dist/mcp/terraform/cost.d.ts +55 -0
- package/dist/mcp/terraform/cspm.d.ts +80 -0
- package/dist/mcp/terraform/currency.d.ts +110 -0
- package/dist/mcp/terraform/decisions.d.ts +178 -0
- package/dist/mcp/terraform/eidas.d.ts +100 -0
- package/dist/mcp/terraform/evidence.d.ts +343 -0
- package/dist/mcp/terraform/findings.d.ts +76 -0
- package/dist/mcp/terraform/fixMemory.d.ts +81 -0
- package/dist/mcp/terraform/governance.d.ts +56 -0
- package/dist/mcp/terraform/hcl.d.ts +115 -0
- package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
- package/dist/mcp/terraform/idleFloor.d.ts +78 -0
- package/dist/mcp/terraform/keyless.d.ts +68 -0
- package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
- package/dist/mcp/terraform/nativeRules.d.ts +38 -0
- package/dist/mcp/terraform/nativeScan.d.ts +11 -0
- package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
- package/dist/mcp/terraform/normalization.d.ts +52 -0
- package/dist/mcp/terraform/oscal.d.ts +103 -0
- package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
- package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
- package/dist/mcp/terraform/paths.d.ts +28 -0
- package/dist/mcp/terraform/plan.d.ts +157 -0
- package/dist/mcp/terraform/planDrift.d.ts +199 -0
- package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
- package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
- package/dist/mcp/terraform/refactor.d.ts +183 -0
- package/dist/mcp/terraform/registry.d.ts +108 -0
- package/dist/mcp/terraform/risk.d.ts +41 -0
- package/dist/mcp/terraform/scanSession.d.ts +116 -0
- package/dist/mcp/terraform/scannerCache.d.ts +15 -0
- package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
- package/dist/mcp/terraform/scannerJson.d.ts +13 -0
- package/dist/mcp/terraform/scanners.d.ts +205 -0
- package/dist/mcp/terraform/signing.d.ts +61 -0
- package/dist/mcp/terraform/stateLocking.d.ts +18 -0
- package/dist/mcp/terraform/subprocess.d.ts +43 -0
- package/dist/mcp/terraform/suppressions.d.ts +90 -0
- package/dist/mcp/terraform/taxonomy.d.ts +39 -0
- package/dist/mcp/terraform/tfquery.d.ts +47 -0
- package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
- package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
- package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
- package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
- package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
- package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
- package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
- package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
- package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
- package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
- package/dist/mcp/terraform/tools/plan.d.ts +59 -0
- package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
- package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
- package/dist/mcp/terraform/tools/scan.d.ts +114 -0
- package/dist/mcp/terraform/tools/validate.d.ts +31 -0
- package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
- package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
- package/dist/mcp/terraform/tools.d.ts +16 -0
- package/dist/mcp/terraform/transformPacks.d.ts +267 -0
- package/dist/mcp/terraform/types.d.ts +226 -0
- package/dist/mcp/terraform/verification.d.ts +81 -0
- package/dist/mcp/terraform/vex.d.ts +115 -0
- package/dist/mcp/terraform/writeOnly.d.ts +67 -0
- package/dist/mcp/terraform.d.ts +51 -0
- package/dist/mcp/terratest.d.ts +85 -0
- package/dist/mcp/untrustedContent.d.ts +76 -0
- package/dist/mcp/upload.d.ts +8 -0
- package/dist/models.d.ts +181 -0
- package/dist/modes/address-reviews.d.ts +2 -0
- package/dist/modes/assess.d.ts +2 -0
- package/dist/modes/build.d.ts +2 -0
- package/dist/modes/compliance-audit.d.ts +2 -0
- package/dist/modes/cost-optimization.d.ts +2 -0
- package/dist/modes/drift-detect.d.ts +2 -0
- package/dist/modes/fix.d.ts +2 -0
- package/dist/modes/incremental-review.d.ts +2 -0
- package/dist/modes/index.d.ts +24 -0
- package/dist/modes/modernize-deprecated.d.ts +2 -0
- package/dist/modes/plan.d.ts +2 -0
- package/dist/modes/policy-gate.d.ts +2 -0
- package/dist/modes/prFormats.d.ts +3 -0
- package/dist/modes/refactor.d.ts +2 -0
- package/dist/modes/refresh-remediation.d.ts +2 -0
- package/dist/modes/remediate-and-refactor.d.ts +2 -0
- package/dist/modes/remediate.d.ts +2 -0
- package/dist/modes/resolve-conflicts.d.ts +2 -0
- package/dist/modes/review.d.ts +2 -0
- package/dist/modes/summarize-pr.d.ts +2 -0
- package/dist/modes/task.d.ts +2 -0
- package/dist/modes/terraform-code-review.d.ts +2 -0
- package/dist/modes/types.d.ts +9 -0
- package/dist/modes/update-dependencies.d.ts +2 -0
- package/dist/prep/index.d.ts +7 -0
- package/dist/prep/installNodeDependencies.d.ts +2 -0
- package/dist/prep/installPythonDependencies.d.ts +2 -0
- package/dist/prep/types.d.ts +31 -0
- package/dist/reviewQuality.d.ts +107 -0
- package/dist/skills/terraform-best-practices/SKILL.md +379 -0
- package/dist/toolState.d.ts +123 -0
- package/dist/utils/activity.d.ts +40 -0
- package/dist/utils/agent.d.ts +47 -0
- package/dist/utils/agentHangReport.d.ts +38 -0
- package/dist/utils/annotations.d.ts +17 -0
- package/dist/utils/apiFetch.d.ts +11 -0
- package/dist/utils/apiKeys.d.ts +48 -0
- package/dist/utils/apiUrl.d.ts +28 -0
- package/dist/utils/assets.d.ts +8 -0
- package/dist/utils/baseRefConfig.d.ts +121 -0
- package/dist/utils/billingErrors.d.ts +85 -0
- package/dist/utils/body.d.ts +34 -0
- package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
- package/dist/utils/byokFallback.d.ts +85 -0
- package/dist/utils/changeImpact.d.ts +101 -0
- package/dist/utils/claudeSubscription.d.ts +30 -0
- package/dist/utils/cli.d.ts +10 -0
- package/dist/utils/cloudClient.d.ts +33 -0
- package/dist/utils/cloudFetchCore.d.ts +42 -0
- package/dist/utils/cloudReport.d.ts +114 -0
- package/dist/utils/codexHome.d.ts +29 -0
- package/dist/utils/codexOAuth.d.ts +60 -0
- package/dist/utils/diffCoverage.d.ts +63 -0
- package/dist/utils/env.d.ts +46 -0
- package/dist/utils/errorReport.d.ts +17 -0
- package/dist/utils/exitHandler.d.ts +8 -0
- package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
- package/dist/utils/gitAuth.d.ts +84 -0
- package/dist/utils/gitAuthServer.d.ts +24 -0
- package/dist/utils/github.d.ts +104 -0
- package/dist/utils/globals.d.ts +3 -0
- package/dist/utils/infraweaverConfig.d.ts +56 -0
- package/dist/utils/install.d.ts +37 -0
- package/dist/utils/instructions.d.ts +48 -0
- package/dist/utils/keylessOidc.d.ts +28 -0
- package/dist/utils/leapingComment.d.ts +11 -0
- package/dist/utils/learnings.d.ts +62 -0
- package/dist/utils/learningsTruncate.d.ts +25 -0
- package/dist/utils/lifecycle.d.ts +57 -0
- package/dist/utils/log.d.ts +111 -0
- package/dist/utils/modelResolver.d.ts +63 -0
- package/dist/utils/moduleFetch.d.ts +39 -0
- package/dist/utils/normalizeEnv.d.ts +30 -0
- package/dist/utils/openCodeModels.d.ts +11 -0
- package/dist/utils/openaiCompatible.d.ts +26 -0
- package/dist/utils/opentofuMcp.d.ts +50 -0
- package/dist/utils/overrides.d.ts +40 -0
- package/dist/utils/packageManager.d.ts +49 -0
- package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
- package/dist/utils/payload.d.ts +249 -0
- package/dist/utils/prSummary.d.ts +61 -0
- package/dist/utils/presets.d.ts +36 -0
- package/dist/utils/progressComment.d.ts +146 -0
- package/dist/utils/providerErrors.d.ts +31 -0
- package/dist/utils/proxyModel.d.ts +76 -0
- package/dist/utils/rangeDiff.d.ts +51 -0
- package/dist/utils/redact.d.ts +33 -0
- package/dist/utils/registryAuth.d.ts +52 -0
- package/dist/utils/remediationCommand.d.ts +58 -0
- package/dist/utils/retry.d.ts +38 -0
- package/dist/utils/reviewCleanup.d.ts +14 -0
- package/dist/utils/run.d.ts +9 -0
- package/dist/utils/runContext.d.ts +112 -0
- package/dist/utils/runContextData.d.ts +42 -0
- package/dist/utils/runErrorRenderer.d.ts +64 -0
- package/dist/utils/runLifecycle.d.ts +89 -0
- package/dist/utils/runStartupLog.d.ts +15 -0
- package/dist/utils/secrets.d.ts +34 -0
- package/dist/utils/setup.d.ts +90 -0
- package/dist/utils/shell.d.ts +44 -0
- package/dist/utils/skills.d.ts +10 -0
- package/dist/utils/subprocess.d.ts +81 -0
- package/dist/utils/terraformMcp.d.ts +46 -0
- package/dist/utils/time.d.ts +15 -0
- package/dist/utils/timer.d.ts +23 -0
- package/dist/utils/todoTracking.d.ts +16 -0
- package/dist/utils/token.d.ts +52 -0
- package/dist/utils/toolLicensing.d.ts +56 -0
- package/dist/utils/toolSelection.d.ts +73 -0
- package/dist/utils/toon.d.ts +16 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/versioning.d.ts +7 -0
- package/dist/utils/vertex.d.ts +16 -0
- package/dist/utils/workflow.d.ts +13 -0
- package/package.json +132 -0
- package/src/agents/claude.ts +1588 -0
- package/src/agents/claudePretoolGate.ts +286 -0
- package/src/agents/dispatchMetrics.ts +162 -0
- package/src/agents/gateServer.ts +178 -0
- package/src/agents/index.ts +10 -0
- package/src/agents/nativeFsDenies.ts +164 -0
- package/src/agents/opencode.ts +1600 -0
- package/src/agents/opencodePlugin.ts +304 -0
- package/src/agents/opencodeShared.ts +134 -0
- package/src/agents/postRun.ts +615 -0
- package/src/agents/reviewer.ts +134 -0
- package/src/agents/sessionLabeler.ts +185 -0
- package/src/agents/shared.ts +377 -0
- package/src/agents/subagentModels.ts +40 -0
- package/src/agents/tokenQuota.ts +203 -0
- package/src/agents/writeGateSource.ts +148 -0
- package/src/agents/writePolicy.ts +132 -0
- package/src/brand.ts +84 -0
- package/src/cli.ts +117 -0
- package/src/commands/gha.ts +188 -0
- package/src/commands/mcp.ts +126 -0
- package/src/commands/verifyEvidence.ts +100 -0
- package/src/entry.ts +7 -0
- package/src/entryPost.ts +109 -0
- package/src/external.ts +308 -0
- package/src/i18n/scaffolding.ts +191 -0
- package/src/index.ts +7 -0
- package/src/internal/index.ts +74 -0
- package/src/lifecycle.ts +2 -0
- package/src/main.ts +815 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
- package/src/mcp/__fixtures__/infraweaver-test-repo-pr-1.diff.json +67 -0
- package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
- package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
- package/src/mcp/arkConfig.ts +7 -0
- package/src/mcp/assess.ts +723 -0
- package/src/mcp/capabilityContext.ts +80 -0
- package/src/mcp/changeSummary.ts +145 -0
- package/src/mcp/checkSuite.ts +261 -0
- package/src/mcp/checkout.ts +1015 -0
- package/src/mcp/comment.ts +683 -0
- package/src/mcp/commitInfo.ts +57 -0
- package/src/mcp/crosswalk.ts +1253 -0
- package/src/mcp/crosswalkDigest.ts +5 -0
- package/src/mcp/cyberEssentials.ts +60 -0
- package/src/mcp/dashboard.ts +232 -0
- package/src/mcp/dependencies.ts +190 -0
- package/src/mcp/frameworks.ts +236 -0
- package/src/mcp/geminiSanitizer.ts +212 -0
- package/src/mcp/git.ts +1116 -0
- package/src/mcp/guardrails.ts +771 -0
- package/src/mcp/issue.ts +74 -0
- package/src/mcp/issueComments.ts +48 -0
- package/src/mcp/issueEvents.ts +100 -0
- package/src/mcp/issueInfo.ts +72 -0
- package/src/mcp/labels.ts +35 -0
- package/src/mcp/localContext.ts +65 -0
- package/src/mcp/localServer.ts +217 -0
- package/src/mcp/moduleExtraction.ts +368 -0
- package/src/mcp/moduleTests.ts +421 -0
- package/src/mcp/modules.ts +752 -0
- package/src/mcp/output.ts +71 -0
- package/src/mcp/pathSafety.ts +28 -0
- package/src/mcp/policy.ts +226 -0
- package/src/mcp/pr.ts +238 -0
- package/src/mcp/prInfo.ts +91 -0
- package/src/mcp/providerSchema.ts +175 -0
- package/src/mcp/review.ts +1081 -0
- package/src/mcp/reviewComments.ts +1137 -0
- package/src/mcp/roots.ts +217 -0
- package/src/mcp/scope.ts +82 -0
- package/src/mcp/selectMode.ts +207 -0
- package/src/mcp/server.ts +498 -0
- package/src/mcp/shared.ts +120 -0
- package/src/mcp/shell.ts +631 -0
- package/src/mcp/staleFix.ts +557 -0
- package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
- package/src/mcp/terraform/azurePrices.ts +38 -0
- package/src/mcp/terraform/baseline.ts +172 -0
- package/src/mcp/terraform/concernResult.ts +111 -0
- package/src/mcp/terraform/cost.ts +175 -0
- package/src/mcp/terraform/cspm.ts +326 -0
- package/src/mcp/terraform/currency.ts +354 -0
- package/src/mcp/terraform/decisions.ts +590 -0
- package/src/mcp/terraform/eidas.ts +134 -0
- package/src/mcp/terraform/evidence.ts +771 -0
- package/src/mcp/terraform/findings.ts +383 -0
- package/src/mcp/terraform/fixMemory.ts +253 -0
- package/src/mcp/terraform/governance.ts +231 -0
- package/src/mcp/terraform/hcl.ts +273 -0
- package/src/mcp/terraform/iacLanguages.ts +431 -0
- package/src/mcp/terraform/idleFloor.ts +304 -0
- package/src/mcp/terraform/keyless.ts +123 -0
- package/src/mcp/terraform/moduleDocs.ts +303 -0
- package/src/mcp/terraform/nativeRules.ts +152 -0
- package/src/mcp/terraform/nativeScan.ts +67 -0
- package/src/mcp/terraform/noiseProfile.ts +183 -0
- package/src/mcp/terraform/normalization.ts +265 -0
- package/src/mcp/terraform/oscal.ts +283 -0
- package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
- package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
- package/src/mcp/terraform/paths.ts +59 -0
- package/src/mcp/terraform/plan.ts +377 -0
- package/src/mcp/terraform/planDrift.ts +520 -0
- package/src/mcp/terraform/policyAuthor.ts +886 -0
- package/src/mcp/terraform/prowlerOcsf.ts +380 -0
- package/src/mcp/terraform/refactor.ts +879 -0
- package/src/mcp/terraform/registry.ts +317 -0
- package/src/mcp/terraform/risk.ts +99 -0
- package/src/mcp/terraform/scanSession.ts +242 -0
- package/src/mcp/terraform/scannerCache.ts +86 -0
- package/src/mcp/terraform/scannerEgress.ts +141 -0
- package/src/mcp/terraform/scannerJson.ts +22 -0
- package/src/mcp/terraform/scanners.ts +1134 -0
- package/src/mcp/terraform/signing.ts +151 -0
- package/src/mcp/terraform/stateLocking.ts +106 -0
- package/src/mcp/terraform/subprocess.ts +102 -0
- package/src/mcp/terraform/suppressions.ts +551 -0
- package/src/mcp/terraform/taxonomy.ts +0 -0
- package/src/mcp/terraform/tfquery.ts +159 -0
- package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
- package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
- package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
- package/src/mcp/terraform/tools/emitCost.ts +130 -0
- package/src/mcp/terraform/tools/emitSarif.ts +108 -0
- package/src/mcp/terraform/tools/fixMemory.ts +82 -0
- package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
- package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
- package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
- package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
- package/src/mcp/terraform/tools/plan.ts +384 -0
- package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
- package/src/mcp/terraform/tools/readFindings.ts +138 -0
- package/src/mcp/terraform/tools/scan.ts +303 -0
- package/src/mcp/terraform/tools/validate.ts +160 -0
- package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
- package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
- package/src/mcp/terraform/tools.ts +62 -0
- package/src/mcp/terraform/transformPacks.ts +594 -0
- package/src/mcp/terraform/types.ts +382 -0
- package/src/mcp/terraform/verification.ts +150 -0
- package/src/mcp/terraform/vex.ts +367 -0
- package/src/mcp/terraform/writeOnly.ts +252 -0
- package/src/mcp/terraform.ts +52 -0
- package/src/mcp/terratest.ts +215 -0
- package/src/mcp/untrustedContent.ts +126 -0
- package/src/mcp/upload.ts +123 -0
- package/src/models.ts +753 -0
- package/src/modes/address-reviews.ts +35 -0
- package/src/modes/assess.ts +27 -0
- package/src/modes/build.ts +86 -0
- package/src/modes/compliance-audit.ts +25 -0
- package/src/modes/cost-optimization.ts +36 -0
- package/src/modes/drift-detect.ts +31 -0
- package/src/modes/fix.ts +29 -0
- package/src/modes/incremental-review.ts +103 -0
- package/src/modes/index.ts +94 -0
- package/src/modes/modernize-deprecated.ts +36 -0
- package/src/modes/plan.ts +21 -0
- package/src/modes/policy-gate.ts +27 -0
- package/src/modes/prFormats.ts +325 -0
- package/src/modes/refactor.ts +74 -0
- package/src/modes/refresh-remediation.ts +40 -0
- package/src/modes/remediate-and-refactor.ts +42 -0
- package/src/modes/remediate.ts +78 -0
- package/src/modes/resolve-conflicts.ts +32 -0
- package/src/modes/review.ts +135 -0
- package/src/modes/summarize-pr.ts +42 -0
- package/src/modes/task.ts +26 -0
- package/src/modes/terraform-code-review.ts +68 -0
- package/src/modes/types.ts +17 -0
- package/src/modes/update-dependencies.ts +44 -0
- package/src/prep/index.ts +96 -0
- package/src/prep/installNodeDependencies.ts +251 -0
- package/src/prep/installPythonDependencies.ts +235 -0
- package/src/prep/types.ts +38 -0
- package/src/reviewQuality.ts +237 -0
- package/src/runCli.ts +335 -0
- package/src/skills/terraform-best-practices/SKILL.md +379 -0
- package/src/toolState.ts +241 -0
- package/src/utils/activity.ts +210 -0
- package/src/utils/agent.ts +245 -0
- package/src/utils/agentHangReport.ts +180 -0
- package/src/utils/annotations.ts +56 -0
- package/src/utils/apiFetch.ts +19 -0
- package/src/utils/apiKeys.ts +305 -0
- package/src/utils/apiUrl.ts +42 -0
- package/src/utils/assets.ts +123 -0
- package/src/utils/baseRefConfig.ts +254 -0
- package/src/utils/billingErrors.ts +210 -0
- package/src/utils/body.ts +168 -0
- package/src/utils/buildInfraweaverFooter.ts +104 -0
- package/src/utils/byokFallback.ts +137 -0
- package/src/utils/changeImpact.ts +330 -0
- package/src/utils/claudeSubscription.ts +93 -0
- package/src/utils/cli.ts +36 -0
- package/src/utils/cloudClient.ts +57 -0
- package/src/utils/cloudFetchCore.ts +139 -0
- package/src/utils/cloudReport.ts +316 -0
- package/src/utils/codexHome.ts +204 -0
- package/src/utils/codexOAuth.ts +154 -0
- package/src/utils/codexRefreshDetect.ts +36 -0
- package/src/utils/diffCoverage.ts +404 -0
- package/src/utils/env.ts +84 -0
- package/src/utils/errorReport.ts +94 -0
- package/src/utils/exitHandler.ts +35 -0
- package/src/utils/fixDoubleEscapedString.ts +9 -0
- package/src/utils/ghaCore.ts +13 -0
- package/src/utils/gitAuth.ts +268 -0
- package/src/utils/gitAuthServer.ts +186 -0
- package/src/utils/github.ts +676 -0
- package/src/utils/globals.ts +9 -0
- package/src/utils/humanEditCapture.ts +198 -0
- package/src/utils/infraweaverConfig.ts +202 -0
- package/src/utils/install.ts +279 -0
- package/src/utils/instructions.ts +640 -0
- package/src/utils/keylessOidc.ts +47 -0
- package/src/utils/leapingComment.ts +20 -0
- package/src/utils/learnings.ts +145 -0
- package/src/utils/learningsTruncate.ts +42 -0
- package/src/utils/lifecycle.ts +198 -0
- package/src/utils/log.ts +452 -0
- package/src/utils/modelResolver.ts +105 -0
- package/src/utils/moduleFetch.ts +138 -0
- package/src/utils/normalizeEnv.ts +106 -0
- package/src/utils/openCodeModels.ts +86 -0
- package/src/utils/openaiCompatible.ts +52 -0
- package/src/utils/opentofuMcp.ts +61 -0
- package/src/utils/overrides.ts +100 -0
- package/src/utils/packageManager.ts +257 -0
- package/src/utils/patchWorkflowRunFields.ts +173 -0
- package/src/utils/payload.ts +1206 -0
- package/src/utils/prSummary.ts +148 -0
- package/src/utils/presets.ts +105 -0
- package/src/utils/progressComment.ts +266 -0
- package/src/utils/providerErrors.ts +189 -0
- package/src/utils/proxyModel.ts +239 -0
- package/src/utils/rangeDiff.ts +182 -0
- package/src/utils/redact.ts +86 -0
- package/src/utils/registryAuth.ts +115 -0
- package/src/utils/remediationCommand.ts +144 -0
- package/src/utils/retry.ts +180 -0
- package/src/utils/reviewCleanup.ts +116 -0
- package/src/utils/run.ts +100 -0
- package/src/utils/runContext.ts +276 -0
- package/src/utils/runContextData.ts +121 -0
- package/src/utils/runErrorRenderer.ts +282 -0
- package/src/utils/runFixture.ts +91 -0
- package/src/utils/runLifecycle.ts +360 -0
- package/src/utils/runStartupLog.ts +67 -0
- package/src/utils/secrets.ts +208 -0
- package/src/utils/setup.ts +368 -0
- package/src/utils/shell.ts +132 -0
- package/src/utils/skills.ts +67 -0
- package/src/utils/subprocess.ts +474 -0
- package/src/utils/terraformMcp.ts +99 -0
- package/src/utils/time.ts +59 -0
- package/src/utils/timer.ts +72 -0
- package/src/utils/todoTracking.ts +168 -0
- package/src/utils/token.ts +294 -0
- package/src/utils/toolLicensing.ts +152 -0
- package/src/utils/toolSelection.ts +239 -0
- package/src/utils/toon.ts +76 -0
- package/src/utils/version.ts +10 -0
- package/src/utils/versioning.ts +44 -0
- package/src/utils/vertex.ts +94 -0
- package/src/utils/workflow.ts +25 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import type { ExternalFinding } from "#app/mcp/terraform/cspm";
|
|
3
|
+
import type { Severity } from "#app/mcp/terraform/types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Prowler OCSF ingestion (CSPM phase 1).
|
|
7
|
+
*
|
|
8
|
+
* Prowler is an Apache-2.0 live-cloud CSPM scanner. Infraweaver CONSUMES its
|
|
9
|
+
* findings and never runs it: the customer runs Prowler in their own CI with
|
|
10
|
+
* their own cloud credentials and Infraweaver ingests the resulting JSON. The
|
|
11
|
+
* zero-credential invariant is unchanged — this module only parses a file.
|
|
12
|
+
*
|
|
13
|
+
* Prowler writes OCSF `DetectionFinding` objects (class_uid 2004) as a single
|
|
14
|
+
* JSON ARRAY, not NDJSON. Field locations follow the OCSF 1.x DetectionFinding
|
|
15
|
+
* schema; `severity_id` is the OCSF enum (0 Unknown, 1 Informational, 2 Low,
|
|
16
|
+
* 3 Medium, 4 High, 5 Critical, 6 Fatal), which is deliberately NOT routed
|
|
17
|
+
* through `normalizeExternalSeverity()` — that function reads bare numbers as
|
|
18
|
+
* CVSS scores and would silently downgrade a Critical (5) to medium.
|
|
19
|
+
*
|
|
20
|
+
* Output is the existing `ExternalFinding` shape, so everything downstream —
|
|
21
|
+
* correlation, concern building, grouping, the Cloud report — is unchanged.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** OCSF `type_uid` for DetectionFinding: Create — what Prowler emits. */
|
|
25
|
+
export const DETECTION_FINDING_CREATE = 200401;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Lenient schema: only what we actually read, everything optional except the
|
|
29
|
+
* check id. A finding that fails this is routed to unmapped-alerts rather than
|
|
30
|
+
* failing the run — an external feed must never break a scan.
|
|
31
|
+
*/
|
|
32
|
+
const ProwlerResource = type({
|
|
33
|
+
"uid?": "string",
|
|
34
|
+
"name?": "string",
|
|
35
|
+
"type?": "string",
|
|
36
|
+
"region?": "string",
|
|
37
|
+
"labels?": "string[]",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const ProwlerFinding = type({
|
|
41
|
+
"metadata?": type({
|
|
42
|
+
"event_code?": "string",
|
|
43
|
+
"product?": type({ "name?": "string", "version?": "string" }),
|
|
44
|
+
}),
|
|
45
|
+
"status_code?": "string",
|
|
46
|
+
"status?": "string",
|
|
47
|
+
"status_detail?": "string",
|
|
48
|
+
"message?": "string",
|
|
49
|
+
"severity?": "string",
|
|
50
|
+
"severity_id?": "number",
|
|
51
|
+
"finding_info?": type({ "title?": "string", "desc?": "string" }),
|
|
52
|
+
"remediation?": type({ "desc?": "string", "references?": "string[]" }),
|
|
53
|
+
"resources?": ProwlerResource.array(),
|
|
54
|
+
"cloud?": type({
|
|
55
|
+
"provider?": "string",
|
|
56
|
+
"account?": type({ "uid?": "string" }),
|
|
57
|
+
"region?": "string",
|
|
58
|
+
}),
|
|
59
|
+
"type_uid?": "number",
|
|
60
|
+
"unmapped?": "object",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export type ProwlerFindingInput = typeof ProwlerFinding.infer;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* True for a parsed value that looks like a Prowler OCSF feed: a non-empty array
|
|
67
|
+
* whose first item is a DetectionFinding or carries Prowler's product name.
|
|
68
|
+
* Checked BEFORE the native `infraweaver.external-findings/v1` validator, which is
|
|
69
|
+
* safe because the native feed is an OBJECT and this requires a non-empty ARRAY —
|
|
70
|
+
* the two shapes cannot collide, so existing feeds keep their exact behaviour.
|
|
71
|
+
*/
|
|
72
|
+
export function isProwlerOcsf(parsed: unknown): boolean {
|
|
73
|
+
if (!Array.isArray(parsed) || parsed.length === 0) return false;
|
|
74
|
+
const first = parsed[0] as Record<string, unknown> | undefined;
|
|
75
|
+
if (!first || typeof first !== "object") return false;
|
|
76
|
+
if (first.type_uid === DETECTION_FINDING_CREATE) return true;
|
|
77
|
+
const metadata = first.metadata as
|
|
78
|
+
| { product?: { name?: unknown } }
|
|
79
|
+
| undefined;
|
|
80
|
+
return (
|
|
81
|
+
typeof metadata?.product?.name === "string" &&
|
|
82
|
+
/prowler/i.test(metadata.product.name)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Detect a Prowler output file that was never closed. Prowler streams `[`, then
|
|
88
|
+
* findings, and only seeks back to write `]` when the scan completes — so a
|
|
89
|
+
* crashed or still-running scan leaves an unterminated array that `JSON.parse`
|
|
90
|
+
* rejects with a message no operator can act on.
|
|
91
|
+
*/
|
|
92
|
+
export function isUnterminatedJsonArray(raw: string): boolean {
|
|
93
|
+
const trimmed = raw.trim();
|
|
94
|
+
return trimmed.startsWith("[") && !trimmed.endsWith("]");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** OCSF severity_id → our scale. Explicitly NOT the CVSS band reading. */
|
|
98
|
+
const SEVERITY_BY_ID: Record<number, Severity> = {
|
|
99
|
+
0: "info", // Unknown — the honest floor, never assumed severe
|
|
100
|
+
1: "info", // Informational
|
|
101
|
+
2: "low",
|
|
102
|
+
3: "medium",
|
|
103
|
+
4: "high",
|
|
104
|
+
5: "critical",
|
|
105
|
+
6: "critical", // Fatal
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const SEVERITY_BY_NAME: Record<string, Severity> = {
|
|
109
|
+
critical: "critical",
|
|
110
|
+
fatal: "critical",
|
|
111
|
+
high: "high",
|
|
112
|
+
medium: "medium",
|
|
113
|
+
low: "low",
|
|
114
|
+
informational: "info",
|
|
115
|
+
info: "info",
|
|
116
|
+
unknown: "info",
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Resolve a finding's severity: the OCSF severity NAME first (what Prowler
|
|
121
|
+
* writes), then the numeric enum, then `medium` — matching the default the
|
|
122
|
+
* existing external-findings path uses when a feed says nothing.
|
|
123
|
+
*/
|
|
124
|
+
export function prowlerSeverity(finding: ProwlerFindingInput): Severity {
|
|
125
|
+
const name = finding.severity?.trim().toLowerCase();
|
|
126
|
+
if (name && SEVERITY_BY_NAME[name]) return SEVERITY_BY_NAME[name] as Severity;
|
|
127
|
+
if (typeof finding.severity_id === "number") {
|
|
128
|
+
const byId = SEVERITY_BY_ID[finding.severity_id];
|
|
129
|
+
if (byId) return byId;
|
|
130
|
+
}
|
|
131
|
+
return "medium";
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Framework keys we accept from `unmapped.compliance`. FREE frameworks only —
|
|
136
|
+
* everything else (CIS, ISO, PCI, SOC2, …) is dropped at parse time and never
|
|
137
|
+
* reaches storage or the UI. Two independent reasons, both binding:
|
|
138
|
+
*
|
|
139
|
+
* 1. LICENCE. CIS/ISO/PCI content is paywalled or no-derivatives; we do not
|
|
140
|
+
* redistribute it in any form, not even requirement ids sourced from a
|
|
141
|
+
* third-party pack.
|
|
142
|
+
* 2. NO STANDARDS OVERLOAD. The catalogue is a hard ceiling, not a starting
|
|
143
|
+
* point — users see the 12 infra themes first; framework ids appear only on
|
|
144
|
+
* control drill-down.
|
|
145
|
+
*
|
|
146
|
+
* Matching is prefix-based and case-insensitive because Prowler keys carry a
|
|
147
|
+
* version suffix (`ENS-RD2022`, `NIST-800-53-REVISION-5`).
|
|
148
|
+
*/
|
|
149
|
+
const FREE_FRAMEWORK_PREFIXES = [
|
|
150
|
+
"ens",
|
|
151
|
+
"nis2",
|
|
152
|
+
"gdpr",
|
|
153
|
+
"c5",
|
|
154
|
+
"nist-800-53",
|
|
155
|
+
"nist_800_53",
|
|
156
|
+
"nist-csf",
|
|
157
|
+
"nist_csf",
|
|
158
|
+
] as const;
|
|
159
|
+
|
|
160
|
+
/** True when a Prowler compliance key names a framework we may lawfully carry. */
|
|
161
|
+
export function isFreeFrameworkKey(key: string): boolean {
|
|
162
|
+
const k = key.trim().toLowerCase();
|
|
163
|
+
return FREE_FRAMEWORK_PREFIXES.some((p) => k.startsWith(p));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The free-framework compliance references a finding carries, as
|
|
168
|
+
* `FRAMEWORK: req-id` strings. Paywalled frameworks are dropped silently and by
|
|
169
|
+
* design. Returns [] when the finding carries none.
|
|
170
|
+
*/
|
|
171
|
+
export function freeComplianceRefs(finding: ProwlerFindingInput): string[] {
|
|
172
|
+
const compliance = (finding.unmapped as { compliance?: unknown } | undefined)
|
|
173
|
+
?.compliance;
|
|
174
|
+
if (!compliance || typeof compliance !== "object") return [];
|
|
175
|
+
const refs: string[] = [];
|
|
176
|
+
for (const [key, value] of Object.entries(
|
|
177
|
+
compliance as Record<string, unknown>,
|
|
178
|
+
)) {
|
|
179
|
+
if (!isFreeFrameworkKey(key)) continue;
|
|
180
|
+
if (!Array.isArray(value)) continue;
|
|
181
|
+
for (const req of value) {
|
|
182
|
+
if (typeof req === "string" && req.trim())
|
|
183
|
+
refs.push(`${key}: ${req.trim()}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return refs;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface ProwlerParseResult {
|
|
190
|
+
/** FAIL findings mapped into the shared external-finding shape. */
|
|
191
|
+
findings: ExternalFinding[];
|
|
192
|
+
summary: {
|
|
193
|
+
total: number;
|
|
194
|
+
/** mapped to concerns (status_code FAIL, not muted). */
|
|
195
|
+
failed: number;
|
|
196
|
+
passed: number;
|
|
197
|
+
manual: number;
|
|
198
|
+
/** muted by the customer's Prowler mutelist — user intent we honour. */
|
|
199
|
+
muted: number;
|
|
200
|
+
/** items that did not match the DetectionFinding shape at all. */
|
|
201
|
+
malformed: number;
|
|
202
|
+
/** items whose `status_code` is one we do not model — distinct from malformed,
|
|
203
|
+
* so an operator can tell "new Prowler status" from "not a finding". */
|
|
204
|
+
unknown_status: number;
|
|
205
|
+
/** `metadata.product.version`, when the feed declared one. */
|
|
206
|
+
product_version: string | null;
|
|
207
|
+
/** set when type_uid drifted from the expected DetectionFinding value. */
|
|
208
|
+
schema_warning: string | null;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Parse a Prowler OCSF array into external findings + an honest tally.
|
|
214
|
+
*
|
|
215
|
+
* Only `status_code === "FAIL"` findings become concerns. PASS/MANUAL and muted
|
|
216
|
+
* findings are COUNTED but never mapped: a passing check is not a defect, and
|
|
217
|
+
* Prowler's mutelist is user-authored intent. The counts still matter — phase-2
|
|
218
|
+
* requirement coverage needs to say "3 checks FAIL, 12 PASS" rather than
|
|
219
|
+
* treating absence as unknown.
|
|
220
|
+
*
|
|
221
|
+
* Pure: no fs, no network.
|
|
222
|
+
*/
|
|
223
|
+
export function parseProwlerOcsf(
|
|
224
|
+
items: readonly unknown[],
|
|
225
|
+
): ProwlerParseResult {
|
|
226
|
+
const findings: ExternalFinding[] = [];
|
|
227
|
+
let failed = 0;
|
|
228
|
+
let passed = 0;
|
|
229
|
+
let manual = 0;
|
|
230
|
+
let muted = 0;
|
|
231
|
+
let malformed = 0;
|
|
232
|
+
let unknown_status = 0;
|
|
233
|
+
let productVersion: string | null = null;
|
|
234
|
+
let schemaWarning: string | null = null;
|
|
235
|
+
|
|
236
|
+
for (const raw of items) {
|
|
237
|
+
const parsed = ProwlerFinding(raw);
|
|
238
|
+
if (parsed instanceof type.errors) {
|
|
239
|
+
malformed++;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const finding = parsed as ProwlerFindingInput;
|
|
243
|
+
productVersion ??= finding.metadata?.product?.version ?? null;
|
|
244
|
+
// Version drift is a warning, never a failure — a newer Prowler that still
|
|
245
|
+
// writes recognisable findings should keep working.
|
|
246
|
+
if (
|
|
247
|
+
schemaWarning === null &&
|
|
248
|
+
typeof finding.type_uid === "number" &&
|
|
249
|
+
finding.type_uid !== DETECTION_FINDING_CREATE
|
|
250
|
+
) {
|
|
251
|
+
schemaWarning = `unexpected OCSF type_uid ${finding.type_uid} (expected ${DETECTION_FINDING_CREATE}); parsed anyway`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const status = finding.status_code?.trim().toUpperCase();
|
|
255
|
+
// The schema is deliberately lenient (every field optional), so ANY object
|
|
256
|
+
// satisfies it — `status_code` is what actually distinguishes a
|
|
257
|
+
// DetectionFinding from arbitrary JSON. Without it, this is not a finding.
|
|
258
|
+
if (!status) {
|
|
259
|
+
malformed++;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
// `status: "Suppressed"` marks a muted finding; status_code still carries the
|
|
263
|
+
// real result, so check muting BEFORE the FAIL branch.
|
|
264
|
+
// PASS/MANUAL are tallied on their real result first: a muted PASS is still a
|
|
265
|
+
// PASS, and requirement coverage ("3 FAIL, 12 PASS") is computed off that
|
|
266
|
+
// tally, so folding it into `muted` would understate what actually ran.
|
|
267
|
+
if (status === "PASS") {
|
|
268
|
+
passed++;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (status === "MANUAL") {
|
|
272
|
+
manual++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
// `status: "Suppressed"` marks a finding the customer mutelisted; status_code
|
|
276
|
+
// still carries the real (FAIL) result. Mutelist entries are user-authored
|
|
277
|
+
// intent we honour, so it is counted and never reported as a defect.
|
|
278
|
+
if (finding.status?.trim().toLowerCase() === "suppressed") {
|
|
279
|
+
muted++;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (status !== "FAIL") {
|
|
283
|
+
unknown_status++;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const checkId = finding.metadata?.event_code?.trim();
|
|
288
|
+
if (!checkId) {
|
|
289
|
+
malformed++;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
failed++;
|
|
293
|
+
|
|
294
|
+
const resource = finding.resources?.[0];
|
|
295
|
+
const remediationParts = [finding.remediation?.desc?.trim()].filter(
|
|
296
|
+
Boolean,
|
|
297
|
+
) as string[];
|
|
298
|
+
for (const ref of finding.remediation?.references ?? []) {
|
|
299
|
+
if (typeof ref === "string" && ref.trim())
|
|
300
|
+
remediationParts.push(ref.trim());
|
|
301
|
+
}
|
|
302
|
+
const compliance = freeComplianceRefs(finding);
|
|
303
|
+
if (compliance.length > 0)
|
|
304
|
+
remediationParts.push(`Compliance: ${compliance.join("; ")}`);
|
|
305
|
+
const hints = tagHints(resource?.labels);
|
|
306
|
+
|
|
307
|
+
const message = finding.status_detail?.trim() || finding.message?.trim();
|
|
308
|
+
const remediation = remediationParts.join(" ");
|
|
309
|
+
findings.push({
|
|
310
|
+
rule_id: checkId,
|
|
311
|
+
provider: finding.cloud?.provider?.trim().toLowerCase() || "prowler",
|
|
312
|
+
severity: prowlerSeverity(finding),
|
|
313
|
+
title: finding.finding_info?.title?.trim() || checkId,
|
|
314
|
+
...(message ? { message } : {}),
|
|
315
|
+
...(remediation ? { remediation } : {}),
|
|
316
|
+
// NB: OCSF `resources[].type` is a CLOUD type ("AwsS3Bucket"), not a
|
|
317
|
+
// Terraform type ("aws_s3_bucket"). Passing it through as `resource.type`
|
|
318
|
+
// would make the correlator's type-narrowed passes silently never match,
|
|
319
|
+
// so it is deliberately omitted and correlation runs on uid/name instead.
|
|
320
|
+
resource: {
|
|
321
|
+
...(resource?.uid ? { arn: resource.uid } : {}),
|
|
322
|
+
...(resource?.name ? { id: resource.name } : {}),
|
|
323
|
+
...(hints.length > 0 ? { tags: hints } : {}),
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
findings,
|
|
330
|
+
summary: {
|
|
331
|
+
total: items.length,
|
|
332
|
+
failed,
|
|
333
|
+
passed,
|
|
334
|
+
manual,
|
|
335
|
+
muted,
|
|
336
|
+
malformed,
|
|
337
|
+
unknown_status,
|
|
338
|
+
product_version: productVersion,
|
|
339
|
+
schema_warning: schemaWarning,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Tag keys whose value NAMES a specific resource. OCSF unrolls cloud tags into
|
|
346
|
+
* `labels` as `key:value`, but only an identity tag is correlation evidence: an
|
|
347
|
+
* `env=production` or `owner=platform-team` tag describes a whole fleet, so
|
|
348
|
+
* matching on it would pin every finding in that fleet to whichever single
|
|
349
|
+
* Terraform block happened to contain the word.
|
|
350
|
+
*/
|
|
351
|
+
const IDENTITY_TAG_KEYS = new Set(["name", "resourcename", "resource_name"]);
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* The identity-bearing cloud tags a Prowler finding carries, lower-cased, as
|
|
355
|
+
* last-resort correlation hints.
|
|
356
|
+
*
|
|
357
|
+
* Two filters, both about not mis-mapping: only identity keys (above), and only
|
|
358
|
+
* values long enough to identify something — a short value like `eu` would match
|
|
359
|
+
* half the repo. A wrong mapping is worse than an honest unmapped alert, because
|
|
360
|
+
* it puts a real cloud finding on an unrelated line of someone's code.
|
|
361
|
+
*/
|
|
362
|
+
export function tagHints(labels: readonly string[] | undefined): string[] {
|
|
363
|
+
const hints = new Set<string>();
|
|
364
|
+
for (const label of labels ?? []) {
|
|
365
|
+
if (typeof label !== "string") continue;
|
|
366
|
+
const idx = label.indexOf(":");
|
|
367
|
+
// No key at all — not attributable to an identity tag, so not evidence.
|
|
368
|
+
if (idx < 0) continue;
|
|
369
|
+
const key = label.slice(0, idx).trim().toLowerCase().replace(/[\s-]/g, "");
|
|
370
|
+
if (!IDENTITY_TAG_KEYS.has(key)) continue;
|
|
371
|
+
// Take everything after the FIRST colon: an ARN-valued Name tag keeps its
|
|
372
|
+
// colons, and the whole ARN is the identity.
|
|
373
|
+
const value = label
|
|
374
|
+
.slice(idx + 1)
|
|
375
|
+
.trim()
|
|
376
|
+
.toLowerCase();
|
|
377
|
+
if (value.length >= 4) hints.add(value);
|
|
378
|
+
}
|
|
379
|
+
return [...hints];
|
|
380
|
+
}
|