Skip to content

Conversation

@munishchouhan
Copy link
Member

@munishchouhan munishchouhan commented Oct 9, 2025

Unified Security Scanner for Containers and Plugins

Summary

This PR consolidates container image scanning and Nextflow plugin scanning into a single unified scanner container, eliminating the need for separate images and simplifying the scanning infrastructure.

Motivation

Previously, Wave used two separate Docker images for security scanning:

  • wave.scan.image.name - for scanning container images with Trivy
  • wave.scan.plugin.image.name - for scanning Nextflow plugins (trivy + oras + unzip)

This approach had several drawbacks:

  • Maintenance overhead of two images
  • Complexity in Wave code with conditional logic for scan types
  • Potential version drift between scanner images
  • Increased deployment complexity

Changes

1. Unified Scanner Container (scanner/)

New: scanner/scan.sh

  • Intelligent bash script that handles both container and plugin scans
  • Automatically detects scan type and adjusts parameter parsing
  • Container scans (7 params): scan.sh container <image> <workdir> <platform> <timeout> <severity> <format>
  • Plugin scans (6 params): scan.sh plugin <plugin> <workdir> <timeout> <severity> <format>
  • Downloads plugins using oras, extracts with unzip, scans with trivy rootfs
  • Only adds --platform flag when actually provided (not for plugins)

Updated: scanner/Dockerfile

  • Based on aquasec/trivy with added bash, oras, and unzip
  • Sets scan.sh as entrypoint
  • Single image handles both scan types

New: scanner/README.md

  • Complete documentation for building and using the unified scanner
  • Usage examples, migration guide, troubleshooting

2. Wave Application Changes

ScanStrategy.groovy

  • Added buildScanCommand() method for unified command generation
  • Automatically detects scan type from image name (nextflow/plugin pattern)
  • Passes 6 parameters for plugins (no platform), 7 for containers
  • Deprecated old methods (scanCommand, trivyCommand, scanPluginCommand) for backward compatibility

KubeScanStrategy.groovy

  • Simplified to use unified buildScanCommand() method
  • Uses single scanConfig.scanImage for all scan types
  • Removed conditional logic for plugin vs container

DockerScanStrategy.groovy

  • Updated to use unified buildScanCommand() method
  • Simplified docker wrapper (no custom entrypoint needed)
  • Removed separate handling for plugins

ScanConfig.groovy

  • Deprecated scanPluginImage configuration property
  • Falls back to scanImage if scanPluginImage not specified
  • Maintains backward compatibility

3. Test Coverage

New: BuildScanCommandTest.groovy

  • Comprehensive test suite with 13 test cases
  • Tests container scans with/without platform and severity
  • Tests plugin scans with/without severity
  • Tests scan type auto-detection
  • Tests timeout conversions, path handling, empty parameters
  • All tests passing

Technical Details

Parameter Handling

The implementation uses different parameter counts based on scan type:

Container Scan (7 parameters):

[scanType, image, workDir, platform, timeout, severity, format]

Plugin Scan (6 parameters - no platform):

[scanType, plugin, workDir, timeout, severity, format]

The scan.sh script detects the scan type and adjusts parameter positions accordingly, ensuring correct parsing without ambiguity.

Backward Compatibility

  • Existing wave.scan.plugin.image.name configuration still works (deprecated)
  • Old scan methods marked @Deprecated but remain functional
  • No breaking changes to public APIs

Configuration Changes

Before:

wave:
  scan:
    image:
      name: "trivy:0.57.1"
    plugin:
      image:
        name: "trivy-oras:0.57.1-1.2.0"

After:

wave:
  scan:
    image:
      name: "unified-scanner:latest"  # Handles both types
    # plugin.image.name is optional/deprecated

Benefits

  1. Single Image - One container handles all security scanning
  2. Simplified Maintenance - One image to build, test, and deploy
  3. Reduced Complexity - Less conditional logic in Wave code
  4. Consistent Behavior - Same Trivy version for all scans
  5. Easier Deployment - Single image to manage in registries
  6. Better Testing - Unified test coverage for all scan types

Testing

  • ✅ Unit tests: 13 tests in BuildScanCommandTest - all passing
  • ✅ Parameter validation for both scan types
  • ✅ Platform handling (included for containers, excluded for plugins)
  • ✅ Severity and timeout parameter handling
  • ✅ Scan type auto-detection logic
  • ✅ Path handling (absolute and relative)

Migration Guide

For existing deployments:

  1. Build the unified scanner image from scanner/ directory:

    cd scanner
    docker build -t your-registry/wave-scanner:latest .
    docker push your-registry/wave-scanner:latest
  2. Update Wave configuration:

    wave:
      scan:
        image:
          name: "your-registry/wave-scanner:latest"
  3. (Optional) Remove the deprecated plugin.image.name configuration

  4. Restart Wave application to pick up changes

Example Usage

Container Scan:

docker run wave-scanner:latest \
  container \
  alpine:latest \
  /scan \
  linux/amd64 \
  15 \
  "CRITICAL,HIGH" \
  default

Plugin Scan:

docker run wave-scanner:latest \
  plugin \
  public.cr.seqera.io/nextflow/plugin/nf-amazon:1.0.0 \
  /scan \
  15 \
  "CRITICAL,HIGH" \
  default

Files Changed

  • scanner/scan.sh (new) - Unified orchestration script
  • scanner/Dockerfile (modified) - Added bash, new entrypoint
  • scanner/README.md (new) - Comprehensive documentation
  • src/main/groovy/io/seqera/wave/service/scan/ScanStrategy.groovy - Added unified command builder
  • src/main/groovy/io/seqera/wave/service/scan/KubeScanStrategy.groovy - Simplified implementation
  • src/main/groovy/io/seqera/wave/service/scan/DockerScanStrategy.groovy - Simplified implementation
  • src/main/groovy/io/seqera/wave/configuration/ScanConfig.groovy - Deprecated plugin config
  • src/test/groovy/io/seqera/wave/service/scan/BuildScanCommandTest.groovy (new) - Comprehensive tests

Breaking Changes

None. The implementation maintains full backward compatibility.

Future Work

  • Remove deprecated methods in next major version
  • Consider adding support for additional scan formats (cyclonedx)
  • Enhance logging for better observability
  • Add metrics for scan performance

Checklist

  • Code compiles successfully
  • Unit tests added and passing
  • Backward compatibility maintained
  • Documentation updated
  • Configuration changes documented
  • Migration guide provided

🤖 Generated with Claude Code

Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan munishchouhan changed the base branch from master to WV-228-Add-nf-plugin-security-scan October 9, 2025 13:33
@munishchouhan munishchouhan changed the title Wv 228 add nf plugin security scan v2 COMP-469 add nf plugin security scan v2 Oct 9, 2025
@munishchouhan munishchouhan self-assigned this Oct 9, 2025
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan
Copy link
Member Author

tested
Screenshot 2025-10-09 at 16 20 17
Screenshot 2025-10-09 at 16 19 43

@munishchouhan munishchouhan changed the title COMP-469 add nf plugin security scan v2 COMP-469 Unified Security Scanner for Containers and Plugins Oct 9, 2025
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan
Copy link
Member Author

tested failed scans:
Screenshot 2025-10-10 at 10 37 26
Screenshot 2025-10-10 at 10 36 44

@munishchouhan
Copy link
Member Author

@pditommaso please review

@pditommaso
Copy link
Collaborator

Let's merge to see the overall impact

@munishchouhan munishchouhan merged commit 4d637bf into WV-228-Add-nf-plugin-security-scan Oct 15, 2025
7 checks passed
@munishchouhan munishchouhan deleted the WV-228-Add-nf-plugin-security-scan-v2 branch October 15, 2025 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants