diff --git a/CHANGELOG.md b/CHANGELOG.md index db24ac79a..b02de034f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +## [1.1.45](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.43) - 2025-12-10 + +### Changed +- Updated the Coana CLI to v `14.12.122`. + +### Added +- Added `--reach-use-only-pregenerated-sboms` to run the Tier 1 reachability based only on pre-computed CDX and SPDX SBOMs (all other manifests are excluded). + ## [1.1.44](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.43) - 2025-12-09 ### Changed diff --git a/package.json b/package.json index f2eb63788..8b51e98a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket", - "version": "1.1.44", + "version": "1.1.45", "description": "CLI for Socket.dev", "homepage": "https://github.com/SocketDev/socket-cli", "license": "MIT AND OFL-1.1", @@ -94,7 +94,7 @@ "@babel/preset-typescript": "7.27.1", "@babel/runtime": "7.28.4", "@biomejs/biome": "2.2.4", - "@coana-tech/cli": "14.12.118", + "@coana-tech/cli": "14.12.122", "@cyclonedx/cdxgen": "11.11.0", "@dotenvx/dotenvx": "1.49.0", "@eslint/compat": "1.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79fb7fa94..b8e688dc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,8 +124,8 @@ importers: specifier: 2.2.4 version: 2.2.4 '@coana-tech/cli': - specifier: 14.12.118 - version: 14.12.118 + specifier: 14.12.122 + version: 14.12.122 '@cyclonedx/cdxgen': specifier: 11.11.0 version: 11.11.0 @@ -677,8 +677,8 @@ packages: '@bufbuild/protobuf@2.6.3': resolution: {integrity: sha512-w/gJKME9mYN7ZoUAmSMAWXk4hkVpxRKvEJCb3dV5g9wwWdxTJJ0ayOJAVcNxtdqaxDyFuC0uz4RSGVacJ030PQ==} - '@coana-tech/cli@14.12.118': - resolution: {integrity: sha512-0Aa9OxWFo0p9Np4vRycrr0kx1F9y4He+2x4tk9YT7V+SoW7Dit6Tz3pXJ3fouj7l3K/baPII/SLrqaPIBVDuPA==} + '@coana-tech/cli@14.12.122': + resolution: {integrity: sha512-pkrIhDXkLvGkwViAVk/Hyy7rN6acSXyQQX2OcKRzWd+vL/SfcWftTtj7wGa76cUlIo8R7QQIJJHMv9wemUth/Q==} hasBin: true '@colors/colors@1.5.0': @@ -5315,7 +5315,7 @@ snapshots: '@bufbuild/protobuf@2.6.3': optional: true - '@coana-tech/cli@14.12.118': {} + '@coana-tech/cli@14.12.122': {} '@colors/colors@1.5.0': optional: true diff --git a/src/commands/ci/handle-ci.mts b/src/commands/ci/handle-ci.mts index 7b0c8a02a..4f85e04e8 100644 --- a/src/commands/ci/handle-ci.mts +++ b/src/commands/ci/handle-ci.mts @@ -60,6 +60,7 @@ export async function handleCi(autoManifest: boolean): Promise { reachEcosystems: [], reachExcludePaths: [], reachSkipCache: false, + reachUseOnlyPregeneratedSboms: false, reachVersion: undefined, runReachabilityAnalysis: false, }, diff --git a/src/commands/scan/cmd-scan-create.mts b/src/commands/scan/cmd-scan-create.mts index d0962b4db..402ecbd92 100644 --- a/src/commands/scan/cmd-scan-create.mts +++ b/src/commands/scan/cmd-scan-create.mts @@ -244,6 +244,7 @@ async function run( reachDisableAnalysisSplitting, reachDisableAnalytics, reachSkipCache, + reachUseOnlyPregeneratedSboms, reachVersion, readOnly, reportLevel, @@ -273,6 +274,7 @@ async function run( reachDisableAnalysisSplitting: boolean reachDisableAnalytics: boolean reachSkipCache: boolean + reachUseOnlyPregeneratedSboms: boolean reachVersion: string | undefined } @@ -458,7 +460,8 @@ async function run( isUsingNonDefaultTimeout || isUsingNonDefaultVersion || reachDisableAnalysisSplitting || - reachSkipCache + reachSkipCache || + reachUseOnlyPregeneratedSboms // Validate target constraints when --reach is enabled. const reachTargetValidation = reach @@ -573,6 +576,7 @@ async function run( reachEcosystems, reachExcludePaths, reachSkipCache: Boolean(reachSkipCache), + reachUseOnlyPregeneratedSboms: Boolean(reachUseOnlyPregeneratedSboms), reachVersion, runReachabilityAnalysis: Boolean(reach), }, diff --git a/src/commands/scan/cmd-scan-create.test.mts b/src/commands/scan/cmd-scan-create.test.mts index 2ef7c6cdf..4d4c00422 100644 --- a/src/commands/scan/cmd-scan-create.test.mts +++ b/src/commands/scan/cmd-scan-create.test.mts @@ -63,6 +63,7 @@ describe('socket scan create', async () => { --reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Defaults to all ecosystems. --reach-exclude-paths List of paths to exclude from reachability analysis, as either a comma separated value or as multiple flags. --reach-skip-cache Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis. + --reach-use-only-pregenerated-sboms When using this option, the scan is created based only on pre-generated CDX and SPDX files in your project. --reach-version Override the version of @coana-tech/cli used for reachability analysis. Default: . Uploads the specified dependency manifest files for Go, Gradle, JavaScript, diff --git a/src/commands/scan/cmd-scan-reach.mts b/src/commands/scan/cmd-scan-reach.mts index 2f26af431..c9b701244 100644 --- a/src/commands/scan/cmd-scan-reach.mts +++ b/src/commands/scan/cmd-scan-reach.mts @@ -128,6 +128,7 @@ async function run( reachDisableAnalysisSplitting, reachDisableAnalytics, reachSkipCache, + reachUseOnlyPregeneratedSboms, reachVersion, } = cli.flags as { cwd: string @@ -143,6 +144,7 @@ async function run( reachDisableAnalysisSplitting: boolean reachDisableAnalytics: boolean reachSkipCache: boolean + reachUseOnlyPregeneratedSboms: boolean reachVersion: string | undefined } @@ -263,6 +265,7 @@ async function run( reachEcosystems, reachExcludePaths, reachSkipCache: Boolean(reachSkipCache), + reachUseOnlyPregeneratedSboms: Boolean(reachUseOnlyPregeneratedSboms), reachVersion, }, targets, diff --git a/src/commands/scan/cmd-scan-reach.test.mts b/src/commands/scan/cmd-scan-reach.test.mts index 28acf92b2..b3cb1e4c8 100644 --- a/src/commands/scan/cmd-scan-reach.test.mts +++ b/src/commands/scan/cmd-scan-reach.test.mts @@ -46,6 +46,7 @@ describe('socket scan reach', async () => { --reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Defaults to all ecosystems. --reach-exclude-paths List of paths to exclude from reachability analysis, as either a comma separated value or as multiple flags. --reach-skip-cache Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis. + --reach-use-only-pregenerated-sboms When using this option, the scan is created based only on pre-generated CDX and SPDX files in your project. --reach-version Override the version of @coana-tech/cli used for reachability analysis. Default: . Runs the Socket reachability analysis without creating a scan in Socket. diff --git a/src/commands/scan/create-scan-from-github.mts b/src/commands/scan/create-scan-from-github.mts index 39fb14983..b5d370053 100644 --- a/src/commands/scan/create-scan-from-github.mts +++ b/src/commands/scan/create-scan-from-github.mts @@ -258,6 +258,7 @@ async function scanOneRepo( reachEcosystems: [], reachExcludePaths: [], reachSkipCache: false, + reachUseOnlyPregeneratedSboms: false, reachVersion: undefined, runReachabilityAnalysis: false, }, diff --git a/src/commands/scan/handle-create-new-scan.mts b/src/commands/scan/handle-create-new-scan.mts index acf550a19..2e023e10e 100644 --- a/src/commands/scan/handle-create-new-scan.mts +++ b/src/commands/scan/handle-create-new-scan.mts @@ -1,5 +1,7 @@ import path from 'node:path' +import micromatch from 'micromatch' + import { debugDir, debugFn } from '@socketsecurity/registry/lib/debug' import { logger } from '@socketsecurity/registry/lib/logger' import { pluralize } from '@socketsecurity/registry/lib/words' @@ -22,6 +24,41 @@ import type { ReachabilityOptions } from './perform-reachability-analysis.mts' import type { REPORT_LEVEL } from './types.mts' import type { OutputKind } from '../../types.mts' import type { Remap } from '@socketsecurity/registry/lib/objects' +import type { SocketSdkSuccessResult } from '@socketsecurity/sdk' + +// Keys for CDX and SPDX in the supported files response. +const CDX_SPDX_KEYS = ['cdx', 'spdx'] + +function getCdxSpdxPatterns( + supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], +): string[] { + const patterns: string[] = [] + for (const key of CDX_SPDX_KEYS) { + const supported = supportedFiles[key] + if (supported) { + for (const entry of Object.values(supported)) { + patterns.push(`**/${entry.pattern}`) + } + } + } + return patterns +} + +function filterToCdxSpdxAndFactsFiles( + filepaths: string[], + supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], +): string[] { + const patterns = getCdxSpdxPatterns(supportedFiles) + return filepaths.filter(filepath => { + const basename = path.basename(filepath).toLowerCase() + // Include .socket.facts.json files. + if (basename === constants.DOT_SOCKET_DOT_FACTS_JSON) { + return true + } + // Include CDX and SPDX files. + return micromatch.some(filepath, patterns) + }) +} export type HandleCreateNewScanConfig = { autoManifest: boolean @@ -187,14 +224,20 @@ export async function handleCreateNewScan({ const reachabilityReport = reachResult.data?.reachabilityReport + // Ensure the .socket.facts.json isn't duplicated in case it happened + // to be in the scan folder before the analysis was run. + const filteredPackagePaths = packagePaths.filter( + p => + path.basename(p).toLowerCase() !== constants.DOT_SOCKET_DOT_FACTS_JSON, + ) + + // When using pregenerated SBOMs only, filter to CDX/SPDX files. + const pathsForScan = reach.reachUseOnlyPregeneratedSboms + ? filterToCdxSpdxAndFactsFiles(filteredPackagePaths, supportedFiles) + : filteredPackagePaths + scanPaths = [ - ...packagePaths.filter( - // Ensure the .socket.facts.json isn't duplicated in case it happened - // to be in the scan folder before the analysis was run. - p => - path.basename(p).toLowerCase() !== - constants.DOT_SOCKET_DOT_FACTS_JSON, - ), + ...pathsForScan, ...(reachabilityReport ? [reachabilityReport] : []), ] diff --git a/src/commands/scan/perform-reachability-analysis.mts b/src/commands/scan/perform-reachability-analysis.mts index b89931ec7..44dfa81d9 100644 --- a/src/commands/scan/perform-reachability-analysis.mts +++ b/src/commands/scan/perform-reachability-analysis.mts @@ -23,6 +23,7 @@ export type ReachabilityOptions = { reachEcosystems: PURL_Type[] reachExcludePaths: string[] reachSkipCache: boolean + reachUseOnlyPregeneratedSboms: boolean reachVersion: string | undefined } @@ -187,6 +188,9 @@ export async function performReachabilityAnalysis( ? ['--exclude-dirs', ...reachabilityOptions.reachExcludePaths] : []), ...(reachabilityOptions.reachSkipCache ? ['--skip-cache-usage'] : []), + ...(reachabilityOptions.reachUseOnlyPregeneratedSboms + ? ['--use-only-pregenerated-sboms'] + : []), ] // Build environment variables. diff --git a/src/commands/scan/reachability-flags.mts b/src/commands/scan/reachability-flags.mts index ee11ded0f..dd4b852f4 100644 --- a/src/commands/scan/reachability-flags.mts +++ b/src/commands/scan/reachability-flags.mts @@ -61,4 +61,10 @@ export const reachabilityFlags: MeowFlags = { description: 'Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis.', }, + reachUseOnlyPregeneratedSboms: { + type: 'boolean', + default: false, + description: + 'When using this option, the scan is created based only on pre-generated CDX and SPDX files in your project.', + }, }