From ce2f76ca74a186548e57bfecccc28da88fbb0c8b Mon Sep 17 00:00:00 2001 From: atishj99 Date: Thu, 2 Jul 2026 16:54:49 +0530 Subject: [PATCH 1/2] combining all changes --- internal/commands/scan.go | 5 ++--- internal/commands/scan_test.go | 10 +++++----- internal/commands/util/remediation.go | 2 +- internal/services/projects.go | 1 - internal/wrappers/feature-flags-http.go | 13 +++++++++++++ internal/wrappers/feature-flags.go | 9 ++++----- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 583c596b5..9e8b2e7c2 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -65,7 +65,7 @@ const ( containerVolumeFlag = "-v" containerNameFlag = "--name" containerRemove = "--rm" - containerImage = "checkmarx/kics:v2.1.20" + containerImage = "checkmarx/kics@sha256:643071cf0c1657eaea695a48b49d2d61b7e625bb87c51505530e624e0c0a1ad1" // v2.1.20 containerScan = "scan" containerScanPathFlag = "-p" containerScanPath = "/path" @@ -1184,9 +1184,8 @@ func overrideSastConfigValue(sastFastScanChanged, sastIncrementalChanged, sastLi func addAiscScan(featureFlagWrapper wrappers.FeatureFlagsWrapper, resubmitConfig []wrappers.Config) map[string]interface{} { // Add the aisc resubmit config, currently no value is passed in config - aiSupplyChainEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagWrapper, wrappers.AISupplyChainEnabled) aiSupplyChainGAEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagWrapper, wrappers.AISupplyChainGAEnabled) - if scanTypeEnabled(commonParams.AiscType) && aiSupplyChainEnabled.Status && aiSupplyChainGAEnabled.Status { + if scanTypeEnabled(commonParams.AiscType) && aiSupplyChainGAEnabled.Status { aiscMapConfig := make(map[string]interface{}) aiscConfig := wrappers.AISCConfig{} aiscMapConfig[resultsMapType] = commonParams.AiscType diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 971e3d02c..e44f607ee 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -836,7 +836,7 @@ func TestAddAiscScan_WhenAiscEnabledAndFeatureFlagEnabled_ShouldReturnConfig(t * var resubmitConfig []wrappers.Config mock.Flag = wrappers.FeatureFlagResponseModel{ - Name: wrappers.AISupplyChainEnabled, + Name: wrappers.AISupplyChainGAEnabled, Status: true, } defer clearFlags() @@ -862,7 +862,7 @@ func TestAddAiscScan_WhenAiscDisabled_ShouldReturnNil(t *testing.T) { wrappers.ClearCache() var resubmitConfig []wrappers.Config mock.Flag = wrappers.FeatureFlagResponseModel{ - Name: wrappers.AISupplyChainEnabled, + Name: wrappers.AISupplyChainGAEnabled, Status: true, } defer clearFlags() @@ -878,7 +878,7 @@ func TestAddAiscScan_WhenFeatureFlagDisabled_ShouldReturnNil(t *testing.T) { wrappers.ClearCache() var resubmitConfig []wrappers.Config mock.Flag = wrappers.FeatureFlagResponseModel{ - Name: wrappers.AISupplyChainEnabled, + Name: wrappers.AISupplyChainGAEnabled, Status: false, } defer clearFlags() @@ -900,7 +900,7 @@ func TestAddAiscScan_WithResubmitConfig_ShouldHandleCorrectly(t *testing.T) { }, } mock.Flag = wrappers.FeatureFlagResponseModel{ - Name: wrappers.AISupplyChainEnabled, + Name: wrappers.AISupplyChainGAEnabled, Status: true, } defer clearFlags() @@ -919,7 +919,7 @@ func TestAddAiscScan_ConfigStructure_ShouldHaveCorrectFormat(t *testing.T) { wrappers.ClearCache() var resubmitConfig []wrappers.Config mock.Flag = wrappers.FeatureFlagResponseModel{ - Name: wrappers.AISupplyChainEnabled, + Name: wrappers.AISupplyChainGAEnabled, Status: true, } defer clearFlags() diff --git a/internal/commands/util/remediation.go b/internal/commands/util/remediation.go index 7322a5fa8..a74c180ef 100644 --- a/internal/commands/util/remediation.go +++ b/internal/commands/util/remediation.go @@ -27,7 +27,7 @@ const ( filesContainerVolume = ":/files" resultsContainerLocation = "/kics/" containerRemove = "--rm" - ContainerImage = "checkmarx/kics:v2.1.20" + ContainerImage = "checkmarx/kics@sha256:643071cf0c1657eaea695a48b49d2d61b7e625bb87c51505530e624e0c0a1ad1" // v2.1.20 containerNameFlag = "--name" remediateCommand = "remediate" resultsFlag = "--results" diff --git a/internal/services/projects.go b/internal/services/projects.go index 875568746..090e6e78d 100644 --- a/internal/services/projects.go +++ b/internal/services/projects.go @@ -198,7 +198,6 @@ func updateProject(project *wrappers.ProjectResponseModel, } else { projModel.MainBranch = project.MainBranch } - projModel.RepoURL = project.RepoURL if projectTags == "" && projectPrivatePackage == "" && isBranchPrimary == false { logger.PrintIfVerbose("No tags or branch to update. Skipping project update.") diff --git a/internal/wrappers/feature-flags-http.go b/internal/wrappers/feature-flags-http.go index 3f0c77314..e98b60294 100644 --- a/internal/wrappers/feature-flags-http.go +++ b/internal/wrappers/feature-flags-http.go @@ -4,8 +4,11 @@ import ( "encoding/json" "fmt" "net/http" + "strconv" "strings" + "time" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/pkg/errors" "github.com/spf13/viper" @@ -87,6 +90,16 @@ func (f FeatureFlagsHTTPWrapper) GetSpecificFlag(flagName string) (*FeatureFlagR return &model, nil case http.StatusNotFound: return nil, errors.New("feature flags not found") + case http.StatusTooManyRequests: + waitSeconds := defaultRateLimitWaitSeconds + if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" { + if parsed, parseErr := strconv.Atoi(retryAfter); parseErr == nil && parsed > 0 { + waitSeconds = parsed + } + } + logger.PrintIfVerbose(fmt.Sprintf("Feature flags rate limited (429). Waiting %d seconds before retry.", waitSeconds)) + time.Sleep(time.Duration(waitSeconds) * time.Second) + return nil, errors.New("failed to load feature flags for tenant") default: return nil, errors.New("failed to load feature flags for tenant") } diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index a5718fbd4..ec0a31bd4 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -22,9 +22,6 @@ const maxRetries = 3 const IncreaseFileUploadLimit = "INCREASE_FILE_UPLOAD_LIMIT" const ScaDeltaScanEnabled = "SCA_DELTASCAN_ENABLED" -// AISupplyChainEnabled is the feature flag for AI Supply Chain Engine. -const AISupplyChainEnabled = "AI_SUPPLY_CHAIN_ENGINE_ENABLED" - // AISupplyChainGAEnabled is the feature flag for AI Supply Chain Engine GA. const AISupplyChainGAEnabled = "AI_SUPPLY_CHAIN_ENGINE_GA_ENABLED" @@ -113,8 +110,10 @@ func GetSpecificFeatureFlag(featureFlagsWrapper FeatureFlagsWrapper, flagName st if len(featureFlags) == 0 || DefaultFFLoad { _ = HandleFeatureFlags(featureFlagsWrapper) } - // Take the value from FeatureFlags - return &FeatureFlagResponseModel{Name: flagName, Status: featureFlags[flagName]}, nil + defaultValue := featureFlags[flagName] + featureFlagsCache[flagName] = defaultValue // prevent re-fetch on next call + return &FeatureFlagResponseModel{Name: flagName, Status: defaultValue}, nil + } UpdateSpecificFeatureFlagMap(flagName, *specificFlag) From 0be8a2f9b6d43d466733d5400b5b03fe508d8b6f Mon Sep 17 00:00:00 2001 From: atishj99 Date: Thu, 2 Jul 2026 18:08:00 +0530 Subject: [PATCH 2/2] fixing lint issue --- internal/commands/util/remediation.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/commands/util/remediation.go b/internal/commands/util/remediation.go index a74c180ef..c30438aff 100644 --- a/internal/commands/util/remediation.go +++ b/internal/commands/util/remediation.go @@ -27,6 +27,7 @@ const ( filesContainerVolume = ":/files" resultsContainerLocation = "/kics/" containerRemove = "--rm" + // ContainerImage is the KICS container image with pinned SHA256 digest. ContainerImage = "checkmarx/kics@sha256:643071cf0c1657eaea695a48b49d2d61b7e625bb87c51505530e624e0c0a1ad1" // v2.1.20 containerNameFlag = "--name" remediateCommand = "remediate"