SBOM Generation Guide for Dart and Flutter - pub

Learn how to generate Software Bill of Materials for Dart and Flutter projects. Complete guide with pubspec.lock examples and CycloneDX output.

Source vs Build SBOMs

Dart’s package manager (pub) provides excellent lockfile support through pubspec.lock. This makes source SBOM generation reliable for both Dart and Flutter projects.

  • Source SBOMs are generated from pubspec.lock
  • Build SBOMs can be generated from the .dart_tool/package_config.json

For most Dart/Flutter projects, generating from pubspec.lock is preferred because it contains exact resolved versions and content hashes.

Lockfile Deep Dive

pubspec.yaml (Manifest)

The pubspec.yaml file declares your dependencies:

name: my_app
description: A sample Dart/Flutter application
version: 1.0.0

environment:
  sdk: '>=3.0.0 <4.0.0'
  flutter: '>=3.16.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.0
  provider: ^6.1.0
  shared_preferences: ^2.2.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0
  build_runner: ^2.4.0

pubspec.lock

The pubspec.lock file contains resolved dependencies:

# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
  http:
    dependency: "direct main"
    description:
      name: http
      sha256: "761a297c042deedc1ffbb156d6e2f13c3eb84c6cf7cb8dc2d5f2d5b0b8cb9c7b"
      url: "https://pub.dev"
    source: hosted
    version: "1.2.0"
  http_parser:
    dependency: transitive
    description:
      name: http_parser
      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
      url: "https://pub.dev"
    source: hosted
    version: "4.0.2"
  provider:
    dependency: "direct main"
    description:
      name: provider
      sha256: "7e4a68b2a6e459ff1a3ce8a35c79cd2ad9b96742e5a81c8a83e1d7e3e9c27f22"
      url: "https://pub.dev"
    source: hosted
    version: "6.1.1"
sdks:
  dart: ">=3.0.0 <4.0.0"
  flutter: ">=3.16.0"

Key information:

  • dependency: “direct main”, “direct dev”, or “transitive”
  • sha256: Content hash for integrity verification
  • source: “hosted” (pub.dev), “git”, or “path”
  • version: Exact resolved version

Flutter-Specific Dependencies

Flutter projects have additional dependency types:

Flutter SDK Dependencies

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

These are part of the Flutter SDK and typically not included in SBOMs as they’re versioned with Flutter itself.

Platform-Specific Dependencies

Flutter plugins may have native dependencies:

dependencies:
  url_launcher: ^6.2.0  # Has iOS/Android native code
  sqflite: ^2.3.0       # SQLite bindings

The native code dependencies aren’t captured in pubspec.lock. Consider documenting them separately.

Generating an SBOM

SBOM generation is the first step in the SBOM lifecycle. After generation, you typically need to enrich your SBOM with package metadata and augment it with your organization’s details.

The sbomify GitHub Action is a swiss army knife for SBOMs that automatically selects the best generation tool for your ecosystem, enriches the output with package metadata, and optionally augments it with your business information—all in one step.

For Dart/Flutter, sbomify uses cdxgen or Syft under the hood (Trivy doesn’t support Dart).

Standalone (no account needed):

- uses: sbomify/github-action@master
  env:
    LOCK_FILE: pubspec.lock
    OUTPUT_FILE: sbom.cdx.json
    COMPONENT_NAME: my-flutter-app
    COMPONENT_VERSION: ${{ github.ref_name }}
    ENRICH: true
    UPLOAD: false

Using github.ref_name automatically captures your git tag (e.g., v1.2.3) as the SBOM version. For rolling releases without tags, use github.sha instead. See our SBOM versioning guide for best practices.

With sbomify platform (adds augmentation and upload):

- uses: sbomify/github-action@master
  env:
    TOKEN: ${{ secrets.SBOMIFY_TOKEN }}
    COMPONENT_ID: my-component-id
    LOCK_FILE: pubspec.lock
    OUTPUT_FILE: sbom.cdx.json
    AUGMENT: true
    ENRICH: true

Alternative Tools

If you prefer to run SBOM generation tools manually:

cdxgen (recommended for manual use):

npm install -g @cyclonedx/cdxgen
cdxgen -t dart -o sbom.cdx.json

Syft:

syft . -o cyclonedx-json=sbom.cdx.json

sbom (Dart-native, SPDX only):

dart pub add --dev sbom

Note: The sbom Dart package currently only supports SPDX format, not CycloneDX.

Trivy currently has limited Dart support. Use cdxgen or Syft for CycloneDX output.

When using these tools directly, you’ll need to handle enrichment and augmentation separately.

GitLab CI

generate-sbom:
  image: sbomifyhub/sbomify-action
  variables:
    LOCK_FILE: pubspec.lock
    OUTPUT_FILE: sbom.cdx.json
    UPLOAD: "false"
    ENRICH: "true"
  script:
    - /sbomify.sh
  artifacts:
    paths:
      - sbom.cdx.json

Handling Special Cases

Git Dependencies

Packages from Git repositories:

dependencies:
  my_package:
    git:
      url: https://github.com/example/my_package.git
      ref: v1.0.0

In pubspec.lock:

my_package:
  dependency: "direct main"
  description:
    path: "."
    ref: v1.0.0
    resolved-ref: "abc123def456..."
    url: "https://github.com/example/my_package.git"
  source: git
  version: "1.0.0"

Path Dependencies

Local packages:

dependencies:
  my_local_package:
    path: ../my_local_package

These won’t have pub.dev metadata. Document them with ADDITIONAL_PACKAGES if needed.

Hosted Dependencies (Private)

For private package servers:

dependencies:
  my_private_package:
    hosted:
      name: my_private_package
      url: https://packages.example.com
    version: ^1.0.0

Ensure your CI has authentication configured:

# Set up authentication
dart pub token add https://packages.example.com

Monorepo Support (Melos)

For Dart/Flutter monorepos using Melos:

# melos.yaml
name: my_workspace
packages:
  - packages/*
  - apps/*

Generate SBOMs per package or use Melos to run across all:

melos exec -- "cdxgen -t dart -o sbom.cdx.json"

pub.dev Metadata Enrichment

pub.dev provides rich metadata for packages:

  • License information
  • Repository URLs
  • Author information
  • Documentation links

When using ENRICH: true, this metadata is added to your SBOM automatically.

Best Practices

  1. Always commit pubspec.lock - Essential for reproducible builds
  2. Use caret syntax carefully - ^1.0.0 allows minor/patch updates
  3. Pin versions for production - Consider exact versions for releases
  4. Separate dev dependencies - Keep test/build tools in dev_dependencies
  5. Document native dependencies - Flutter plugins have native code not in pubspec
  6. Run dart pub outdated - Check for updates regularly

Security Considerations

# Check for vulnerable packages
dart pub deps --json | jq '.packages[].name' # Export for scanning

# Use Flutter's built-in checks
flutter pub outdated

Combine dependency checks with SBOM generation in CI:

- name: Check dependencies
  run: dart pub outdated --json > outdated.json

- name: Generate SBOM
  uses: sbomify/github-action@master
  env:
    LOCK_FILE: 'pubspec.lock'
    OUTPUT_FILE: 'sbom.cdx.json'
    ENRICH: true

Further Resources

For more SBOM tools and resources, see our SBOM Resources page, which includes general SBOM utilities for generation, distribution, and analysis.