Skip to content

Generation Software Bill of Materials (SBOM) #4757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

gamlerhart
Copy link
Contributor

@gamlerhart gamlerhart commented Mar 20, 2025

Motivation: In some companies, the development
team has to produce Software Bill of Materials (SBOM) for their project for compliance reasons:
To track dependencies and licenses across their organisation. Provide a Module that produces SBOMs
in JSON format.

Changes in the core: Extended the .getArtifact
to return the coursier.Resolution as well.
This is then used to get the license information.

Outside the core: Add a SBOM contrib module

  • Generate the most basic CycloneDX SBOM files Supporting Java modules for a start
  • Provide a basic upload to the Dependency Track server

@gamlerhart
Copy link
Contributor Author

gamlerhart commented Mar 21, 2025

I've these high level questions

  • I implemented the SBOM json from scratch, so that we can use the UPickle etc and do not add libraries:
    The alternative is to use the CycloneDX 'model' library, that mostly implements the JSON and some hashing.
    But that then adds this extra library etc: More stuff to download, more stuff in the classpath etc.
    So, the question is: What is preferred in general: Avoiding external libraries when possible? Or go for maximum comparability and include more external libraries?

  • I adding this to the 'contrib' section the right place? The alternative seems to have it as a complete external library. However, that adds extra maintenance burdens: Pushing it to Maven repos, compiling it, versioning it. So, having it in-sync seems better.

  • I've extended the returned data from the Coursier .artifacts method. I think that is ok, because that method wasn't yet published in 0.12.9?

(update: Android tests are fixed)

@gamlerhart gamlerhart marked this pull request as ready for review March 21, 2025 11:08
Copy link
Member

@lefou lefou left a comment

Choose a reason for hiding this comment

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

I've these high level questions

* I implemented the SBOM json from scratch, so that we can use the UPickle etc and do not add libraries:
  The alternative is to use the CycloneDX 'model' library, that mostly implements the JSON and some hashing.
  But that then adds this extra library etc: More stuff to download, more stuff in the classpath etc.
  So, the question is: What is preferred in general: Avoiding external libraries when possible? Or go for maximum comparability and include more external libraries?

I'd say it depends on how stable the CyconeDX format it. We don't have an issue with downloading additional dependencies, as long as we encapsulate them in an isolated classloader and properly manage their use (e.g. share same classloader for multple modules via a worker module).

But the model added here seems small enough and the benefit of being directly cacheable by Mill as a task result is something I find useful.

* I adding this to the 'contrib' section the right place? The alternative seems to have it as a complete external library. However, that adds extra maintenance burdens: Pushing it to Maven repos, compiling it, versioning it. So, having it in-sync seems better.

Contrib is exactly for when you don't want to host it yourself.

* I've extended the returned data from the Coursier `.artifacts` method. I think that is ok, because that method wasn't yet published in `0.12.9`?

I'd like to have @alexarchambault thoughts on that. I think we don't want to return tuples from Resolver.artifacts (until we can use named tuples). Maybe we want add a new method with a better name instead.

I added some comments below.

@gamlerhart gamlerhart force-pushed the sbom-for-java-deps branch from b740cdc to bdb28c2 Compare April 4, 2025 19:56
@gamlerhart
Copy link
Contributor Author

  • I'll stick with the upickl JSON for a start. That integrates well with Mill eco system. I consider the CyclonDX library only if there is too painful to directly write the Json.

case Right(res) =>
Result.Success(res)
case Right(artifacts) =>
Result.Success(ArtifactResolution(resolution, artifacts))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe coursier.Fetch.Result could be used for that, like

Suggested change
Result.Success(ArtifactResolution(resolution, artifacts))
Result.Success(Fetch.Result(resolution, artifacts.fullDetailedArtifacts0, artifacts.fullExtraArtifacts))

Copy link
Collaborator

Choose a reason for hiding this comment

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

And we could rename CoursierModule#artifacts to CoursierModule#fetch then

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used Fetch.Result and renamed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alexarchambault Ping. Updated to Fetch.Result

Motivation: In some companies, the development
team has to produce Software Bill of Materials (SBOM)
for their project for compliance reasons:
To track dependencies and licenses across their organisation.
Provide a Module that produces SBOMs
in JSON format.

Changes in the core: Extended the .getArtifact
to return the coursier.Resolution as well.
This is then used to get the license information.

Outside the core: Add a SBOM contrib module
- Generate the most basic CycloneDX SBOM files
  Supporting Java modules for a start
- Provide a basic upload to the Dependency Track server
.
Return a case class from artifacts instead of tuple
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.

3 participants