Skip to content

Conversation

@eyalk007
Copy link
Contributor

@eyalk007 eyalk007 commented Jan 13, 2026

  • The pull request is targeting the dev branch.
  • The code has been validated to compile successfully by running go vet ./....
  • The code has been formatted properly using go fmt ./....
  • All static analysis checks passed.
  • All tests have passed. If this feature is not already covered by the tests, new tests have been added.
  • Updated the Contributing page / ReadMe page / CI Workflow files if needed.
  • All changes are detailed at the description. if not already covered at JFrog Documentation, new documentation have been added.

Depends on:

- Add branchdiff.go with RunBranchDiffAudit function
- Scans target branch first, then source branch (sequential)
- SCA diff handled internally by CLI
- JAS diff handled by CompareJasResults
- Add MergeStatusCodes for partial results filtering
- Status codes merged (worst of target + source) for frogbot filtering
- Add logger field to AuditBasicParams with getter/setter
- RunAudit swaps global logger if custom logger provided
- Enables frogbot to capture logs per-scan for ordered output
- Add LogCollector that captures logs in isolated buffer per audit
- Enables parallel audits without log interleaving
- Uses goroutine-local logger from jfrog-client-go
- Propagate logger to child goroutines in JAS runner and SCA scan
- Remove unused diff completion log message
@eyalk007 eyalk007 self-assigned this Jan 13, 2026
@eyalk007 eyalk007 added the improvement Automatically generated release notes label Jan 13, 2026
)

// UnifyScaAndJasResults merges SCA and JAS diff results into a single SecurityCommandResults.
func UnifyScaAndJasResults(scaResults, jasDiffResults *SecurityCommandResults) *SecurityCommandResults {
Copy link
Contributor Author

@eyalk007 eyalk007 Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

myabe needs to be moved to frogbot considering the specific use
and selected parallel audit implementation, your call @attiasas

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mergeing results could stay here if the logic is adjusted to be more general like MergeCommandResults

@eyalk007 eyalk007 added the safe to test Approve running integration tests on a pull request label Jan 13, 2026
@github-actions github-actions bot removed the safe to test Approve running integration tests on a pull request label Jan 13, 2026
Copy link
Contributor

@attiasas attiasas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! checkout my comments, also:

  1. Update the PR description with the changes
  2. Adjust tests base on changes

@@ -0,0 +1,41 @@
package audit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be at jfrog/jfrog-client-go#1297?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the options

Move LogCollector to client-go - but it's really just a wrapper
Delete LogCollector entirely - Frogbot can use BufferedLogger directly from client-go

or we Keep it as is


// replace github.com/jfrog/froggit-go => github.com/jfrog/froggit-go master

replace github.com/jfrog/jfrog-client-go => github.com/eyalk007/jfrog-client-go v0.0.0-20260114112951-67b77f49255f
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to remove replace after merging dependend PR

Comment on lines 76 to 82
currentLogger := log.GetLogger()
scaTask := createScaScanTaskWithRunner(params.Runner, strategy, params)
wrappedScaTask := func(threadId int) error {
log.SetLoggerForGoroutine(currentLogger)
defer log.ClearLoggerForGoroutine()
return scaTask(threadId)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not change in createScaScanTaskWithRunner directly?

I don't get the chnage (looking only here) you call log.GetLogger and setting it for the routine but at the end you clear it? code is not clear why you do it. (looks like you are just setting default log to be default and clear it).

I suggest improving this part or at least adding comment about this

func addModuleJasScanTask(scanType jasutils.JasScanType, securityParallelRunner *utils.SecurityParallelRunner, task parallel.TaskFunc, scanResults *results.TargetResults, allowSkippingErrors bool) (generalError error) {
securityParallelRunner.JasScannersWg.Add(1)
if _, addTaskErr := securityParallelRunner.Runner.AddTaskWithError(task, func(err error) {
currentLogger := log.GetLogger()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as in scascan.
If this logic is used multiple times (same code), try to create static method to be used in multiple places

)

// UnifyScaAndJasResults merges SCA and JAS diff results into a single SecurityCommandResults.
func UnifyScaAndJasResults(scaResults, jasDiffResults *SecurityCommandResults) *SecurityCommandResults {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mergeing results could stay here if the logic is adjusted to be more general like MergeCommandResults


// CompareJasResults computes the diff between target and source JAS results.
// Returns only NEW findings in source that don't exist in target.
func CompareJasResults(targetResults, sourceResults *SecurityCommandResults) *SecurityCommandResults {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK about the func name, it does not compare, it filters Source results that exists at target

Comment on lines 74 to 85
diffResults := &SecurityCommandResults{
ResultsMetaData: ResultsMetaData{
EntitledForJas: sourceResults.EntitledForJas,
SecretValidation: sourceResults.SecretValidation,
CmdType: sourceResults.CmdType,
XrayVersion: sourceResults.XrayVersion,
XscVersion: sourceResults.XscVersion,
MultiScanId: sourceResults.MultiScanId,
StartTime: sourceResults.StartTime,
ResultContext: sourceResults.ResultContext,
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
diffResults := &SecurityCommandResults{
ResultsMetaData: ResultsMetaData{
EntitledForJas: sourceResults.EntitledForJas,
SecretValidation: sourceResults.SecretValidation,
CmdType: sourceResults.CmdType,
XrayVersion: sourceResults.XrayVersion,
XscVersion: sourceResults.XscVersion,
MultiScanId: sourceResults.MultiScanId,
StartTime: sourceResults.StartTime,
ResultContext: sourceResults.ResultContext,
},
}
diffResults := &SecurityCommandResults{
ResultsMetaData: sourceResults.ResultsMetaData,
},
}

why not just setting the exact same struct (will help to maintain and be sure all attributes are copied). something. is stopping us from doing that?

func extractLocationsOnly(run *sarif.Run, targetKeys map[string]bool) {
for _, result := range run.Results {
for _, location := range result.Locations {
key := getRelativeLocationFileName(location, run.Invocations) + getLocationSnippetText(location)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about file name changes? it will not catch this...
why are we first filtering only locations and than by fingerprints, can we do it in one go? (reducing go over results multile times)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For SAST: Uses fingerprints (precise_sink_and_sink_function) which are content-based, so renames don't matter

for secrets and iac -
This is a known limitation - AM doesn't handle file renames either. If you rename a file, existing findings in that file will show as "new" in the diff. This is acceptable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can write a todo and create a ticket for it, but i dont believe we should handle it now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Automatically generated release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants