From bcbc095e035ee7ef8ef39eb04f5478986ef571bf Mon Sep 17 00:00:00 2001 From: Sumit Morchhale Date: Thu, 15 Jan 2026 12:29:49 +0530 Subject: [PATCH 1/4] Set env variable for sca resolver for delta sca --- internal/commands/scan.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 2dd7c3ca4..1bda3ebf4 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -136,6 +136,7 @@ const ( BranchPrimaryPrefix = "--branch-primary=" OverridePolicyManagement = "override-policy-management" defaultScanEnqueueRetryDelay = 5 + scaResolverCxOneAuthToken = "CXONE_AUTH_TOKEN" ) var ( @@ -1888,7 +1889,16 @@ func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName strin args = append(args, parsedscaResolverParams...) } log.Println(fmt.Sprintf("Using SCA resolver: %s %v", scaResolver, args)) - out, err := exec.Command(scaResolver, args...).Output() + accessToken, err := wrappers.GetAccessToken() + if err != nil { + return err + } + cmd := exec.Command(scaResolver, args...) + if accessToken != "" { + logger.PrintIfVerbose("Setting authorization token for SCA resolver") + cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", scaResolverCxOneAuthToken, accessToken)) + } + out, err := cmd.Output() logger.PrintIfVerbose(string(out)) if err != nil { return errors.Errorf("%s", err) From 025fd2fe1f9dea0aa581c080e913c3fb85d9df93 Mon Sep 17 00:00:00 2001 From: Sumit Morchhale Date: Thu, 15 Jan 2026 14:22:03 +0530 Subject: [PATCH 2/4] fix unit test cases --- internal/commands/scan_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index a88a2c78a..163633b28 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -13,6 +13,7 @@ import ( "reflect" "strings" "testing" + "time" "github.com/checkmarx/ast-cli/internal/commands/util" errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors" @@ -269,6 +270,9 @@ func TestCreateScanWithScaResolver(t *testing.T) { } func TestCreateScanWithScaResolverFailed(t *testing.T) { + setupMockAccessToken() + defer cleanupMockAccessToken() + baseArgs := []string{ "scan", "create", @@ -315,6 +319,9 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + setupMockAccessToken() + defer cleanupMockAccessToken() + err := runScaResolver(tt.sourceDir, tt.scaResolver, tt.scaResolverParams, tt.projectName) assert.Assert(t, strings.Contains(err.Error(), tt.expectedError), err.Error()) }) @@ -4943,3 +4950,18 @@ func TestGetGitCommitHistoryValue_WithWarnings(t *testing.T) { }) } } + +func setupMockAccessToken() { + wrappers.CachedAccessToken = "mock-token-for-testing" + wrappers.CachedAccessTime = time.Now() + viper.Set(commonParams.TokenExpirySecondsKey, 300) +} + +func cleanupMockAccessToken() { + wrappers.CachedAccessToken = "" + wrappers.CachedAccessTime = time.Time{} + + wrappers.ClearCache() + // Reset to default value (300 seconds as per params/binds.go) + viper.Set(commonParams.TokenExpirySecondsKey, 300) +} From 9dce4dae259e2d2a18fbbb15ad06f71d6c5bb8e8 Mon Sep 17 00:00:00 2001 From: Sumit Morchhale Date: Thu, 15 Jan 2026 17:27:18 +0530 Subject: [PATCH 3/4] add check for feature flag for setting auth --- internal/commands/scan.go | 21 +++++++++-------- internal/commands/scan_test.go | 37 ++++++++++++++++++++++-------- internal/wrappers/feature-flags.go | 1 + 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 1bda3ebf4..a370ee510 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1868,7 +1868,7 @@ func filterMatched(filters []string, fileName string) bool { return matched } -func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName string) error { +func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName string, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error { if scaResolver != "" { scaFile, err := ioutil.TempFile("", "sca") scaResolverResultsFile = scaFile.Name() + ".json" @@ -1889,14 +1889,17 @@ func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName strin args = append(args, parsedscaResolverParams...) } log.Println(fmt.Sprintf("Using SCA resolver: %s %v", scaResolver, args)) - accessToken, err := wrappers.GetAccessToken() - if err != nil { - return err - } cmd := exec.Command(scaResolver, args...) - if accessToken != "" { - logger.PrintIfVerbose("Setting authorization token for SCA resolver") - cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", scaResolverCxOneAuthToken, accessToken)) + scaDeltaScanEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ScaDeltaScanEnabled) + if scaDeltaScanEnabled.Status { + accessToken, err := wrappers.GetAccessToken() + if err != nil { + return err + } + if accessToken != "" { + logger.PrintIfVerbose("Setting authorization token for SCA Delta Scan") + cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", scaResolverCxOneAuthToken, accessToken)) + } } out, err := cmd.Output() logger.PrintIfVerbose(string(out)) @@ -2011,7 +2014,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW // execute scaResolver only in sca type of scans if strings.Contains(actualScanTypes, commonParams.ScaType) { - scaErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName) + scaErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) if scaErr != nil { if unzip { _ = cleanTempUnzipDirectory(directoryPath) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 163633b28..1fad7af7a 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -270,9 +270,6 @@ func TestCreateScanWithScaResolver(t *testing.T) { } func TestCreateScanWithScaResolverFailed(t *testing.T) { - setupMockAccessToken() - defer cleanupMockAccessToken() - baseArgs := []string{ "scan", "create", @@ -304,7 +301,7 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { scaResolver: "./ScaResolver", scaResolverParams: "params", projectName: "ProjectName", - expectedError: "/ScaResolver: no such file or directory", + expectedError: "ScaResolver", }, { name: "Invalid scaResolverParams format", @@ -312,17 +309,15 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { scaResolver: "./ScaResolver", scaResolverParams: "\"unclosed quote", projectName: "ProjectName", - expectedError: "/ScaResolver: no such file or directory", // Actual error from command execution + expectedError: "ScaResolver", // Actual error from command execution }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - setupMockAccessToken() - defer cleanupMockAccessToken() - - err := runScaResolver(tt.sourceDir, tt.scaResolver, tt.scaResolverParams, tt.projectName) + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(tt.sourceDir, tt.scaResolver, tt.scaResolverParams, tt.projectName, featureFlagsWrapper) assert.Assert(t, strings.Contains(err.Error(), tt.expectedError), err.Error()) }) } @@ -333,10 +328,32 @@ func TestCreateScanWithScaResolverNoScaResolver(t *testing.T) { var scaResolver = "" var scaResolverParams = "params" var projectName = "ProjectName" - err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName) + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) assert.Assert(t, err == nil) } +func TestScaResolverWithSCADeltaScanEnabled(t *testing.T) { + setupMockAccessToken() + defer cleanupMockAccessToken() + + mock.Flag = wrappers.FeatureFlagResponseModel{ + Name: wrappers.ScaDeltaScanEnabled, + Status: true, + } + defer func() { + mock.Flag = wrappers.FeatureFlagResponseModel{} + }() + var sourceDir = "/sourceDir" + var scaResolver = "./NonExistentScaResolver" + var scaResolverParams = "params" + var projectName = "ProjectName" + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) + assert.Assert(t, err != nil, "Expected error when resolver doesn't exist") + assert.Assert(t, strings.Contains(err.Error(), "ScaResolver"), "Error should mention ScaResolver: %v", err.Error()) +} + func TestCreateScanWithScanTypes(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch"} execCmdNilAssertion(t, append(baseArgs, "--scan-types", "sast")...) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index ad1b3afab..8b2579b27 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -19,6 +19,7 @@ const SscsCommitHistoryEnabled = "SSCS_COMMIT_HISTORY_ENABLED" const DirectAssociationEnabled = "DIRECT_APP_ASSOCIATION_ENABLED" const maxRetries = 3 const IncreaseFileUploadLimit = "INCREASE_FILE_UPLOAD_LIMIT" +const ScaDeltaScanEnabled = "SCA_DELTASCAN_ENABLED" var DefaultFFLoad bool = false From f26f33e22d213c8e5a3a5ba81025b8bf77e8b1d0 Mon Sep 17 00:00:00 2001 From: Sumit Morchhale Date: Thu, 15 Jan 2026 17:30:32 +0530 Subject: [PATCH 4/4] remove unnecessary changes --- internal/commands/scan_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 1fad7af7a..8d0ba7889 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -301,7 +301,7 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { scaResolver: "./ScaResolver", scaResolverParams: "params", projectName: "ProjectName", - expectedError: "ScaResolver", + expectedError: "/ScaResolver: no such file or directory", }, { name: "Invalid scaResolverParams format", @@ -309,7 +309,7 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { scaResolver: "./ScaResolver", scaResolverParams: "\"unclosed quote", projectName: "ProjectName", - expectedError: "ScaResolver", // Actual error from command execution + expectedError: "/ScaResolver: no such file or directory", // Actual error from command execution }, }