Git Product home page Git Product logo

cyclonedx-gomod's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cyclonedx-gomod's Issues

Version Normalization Interferes with Hash Calculation

Module hashes take coordinates (path@version) into consideration.

We trim the +incompatible suffix and optionally the v prefix from versions, but we do it before we calculate the hashes. This causes the resulting hashes to be different if the version was modified, even though none of the module's file have changed.

Version normalization really is just cosmetics. cyclonedx-gomod itself doesn't need it, and neither does Go. For this reason, it should happen just before writing the BOM.

Also, maybe we shouldn't trim +incompatible at all.

Build container images for multiple Go versions

Because the Go (major) version can influence package/module selection, and we currently only build container images for a single Go version, the images are not as useful as they could be.

We should provide images for each officially supported Go version (that is, for the two latest major versions). The Go version included should be expressed via tags, e.g. v1-go1.16, v1.1.0-go1.17 and so on. Minor- and bugfix versions of Go are not relevant for this use case.

Question: make LoadModulesFromBinary public?

Hello ๐Ÿ‘‹

I maintain ko, a tool for building Go applications into lightweight container images. It's got somewhat basic support today for generating "SBOMs", which is effectively to extract the Go binary and run go version -m on it, and print that to stdout. It's not pretty but it works.

I'd love to augment this with "real" SBOM support in as many formats as I can get, and have SBOMs generated and uploaded to registries, instead of just extracted from binaries at request-time. (Or maybe some future where we ensure the binary's embedded information matches the pushed SBOM? Unclear.)

Anyway, I'd love to be able to skip writing code to translate the output of go version -m to CycloneDX SBOM if I can avoid it, and I see that this repo already has that written in an internal package, in LoadModulesFromBinary:

func LoadModulesFromBinary(binaryPath string) (string, []Module, map[string]string, error) {

Is there any interest in moving this to a non-internal package, where I could vendor it into ko?

Calculating hash for modules downloaded via `go mod why` fails on first attempt

v0.8.0 removed the requirement to run go mod download, because go mod why downloads all required modules anyway (and doesn't modify go.sum, as go mod download does).

However, for some reason, dirhash.HashDir fails for modules that have been downloaded by go mod why prior:

2021/06/02 08:43:06 generating sbom
2021/06/02 08:43:06 enumerating modules
go: downloading go.uber.org/zap v1.17.0
go: downloading github.com/hashicorp/go-version v1.3.0
go: downloading github.com/go-chi/chi/v5 v5.0.3
go: downloading github.com/spf13/cobra v1.1.3
go: downloading github.com/spf13/viper v1.7.1
go: downloading gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
go: downloading github.com/stretchr/testify v1.7.0
go: downloading github.com/go-resty/resty/v2 v2.6.0
go: downloading github.com/google/uuid v1.2.0
go: downloading github.com/fsnotify/fsnotify v1.4.7
go: downloading github.com/hashicorp/hcl v1.0.0
go: downloading github.com/magiconair/properties v1.8.1
go: downloading github.com/mitchellh/mapstructure v1.1.2
go: downloading github.com/pelletier/go-toml v1.2.0
go: downloading github.com/spf13/afero v1.1.2
go: downloading github.com/spf13/cast v1.3.0
go: downloading github.com/spf13/jwalterweatherman v1.0.0
go: downloading github.com/spf13/pflag v1.0.5
go: downloading github.com/subosito/gotenv v1.2.0
go: downloading gopkg.in/ini.v1 v1.51.0
go: downloading gopkg.in/yaml.v2 v2.4.0
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/inconshreveable/mousetrap v1.0.0
go: downloading go.uber.org/atomic v1.7.0
go: downloading go.uber.org/multierr v1.6.0
go: downloading golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44
go: downloading golang.org/x/text v0.3.3
go: downloading golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
2021/06/02 08:43:17 normalizing module versions
2021/06/02 08:43:17 determining version of main module
2021/06/02 08:43:17 converting main module xxx
2021/06/02 08:43:17 converting module xxx
2021/06/02 08:43:17 converting module github.com/fsnotify/[email protected]
2021/06/02 08:43:17 generating sbom failed: failed to convert module github.com/fsnotify/[email protected]: failed to calculate h1 hash: open /pkg/mod/cache/download/cloud.google.com/go/@v/list: no such file or directory

Strangely enough, the file at /pkg/mod/cache/download/cloud.google.com/go/@v/list exists, and so does github.com/fsnotify/[email protected] in the module cache. When running cyclonedx-gomod again, it works.

Make building blocks importable.

It would be nice if the building block can be importable.
I think if the necessary directories are put into pkg dir instead of internal (mostly all of them except cli), it should be work.

Rework CLI

Overall, there are three ways in which SBOMs can be generated for Go projects:

  1. Module based (go list -m, go mod why -m)
    • This is what we're currently doing
  2. Application based (go list -deps ./cmd/myapp)
    • This is what has been discussed in #20
  3. Binary based (go version -m ./myapp.exe)

The CLI should clearly separate these cases, especially since some options will not apply to all ways.
Which way is chosen should be an active decision, as each way has implications that users should be aware of.

Status

Include build constraints

Once we support a "distribution mode" (for a lack of better terms; see #20 (comment) - variant 1), we need to express for which build constraints the SBOM has been generated.

Constraints could be included via properties of the main component, e.g.

<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:5f05aa95-d0d9-43aa-bf11-7c9ee2ce9325" version="1">
  <metadata>
    <component>
      <name>github.com/CycloneDX/cyclonedx-gomod</name>
      <version>vX.X.X</version>
      <properties>
        <property name="cdx:gomod:buildconstraint:goos">linux</property>
        <property name="cdx:gomod:buildconstraint:goarch">amd64</property>
        <property name="cdx:gomod:buildconstraint:tags">tag1,tag2,tag3</property>
      </properties>
    </component>
  </metadata>
  <components></components>
</bom>

Or, alternatively:

<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:5f05aa95-d0d9-43aa-bf11-7c9ee2ce9325" version="1">
  <metadata>
    <component>
      <name>github.com/CycloneDX/cyclonedx-gomod</name>
      <version>vX.X.X</version>
      <properties>
        <property name="cdx:gomod:buildconstraint:goos">linux</property>
        <property name="cdx:gomod:buildconstraint:goarch">amd64</property>
        <property name="cdx:gomod:buildconstraint:tag">tag1</property>
        <property name="cdx:gomod:buildconstraint:tag">tag2</property>
        <property name="cdx:gomod:buildconstraint:tag">tag3</property>
      </properties>
    </component>
  </metadata>
  <components></components>
</bom>

This requires cyclonedx-go to support v1.3 of the spec (CycloneDX/cyclonedx-go#1).

Additionally, these constraints could be added to the main component's PURL as well, via qualifiers:

pkg:golang/github.com/CycloneDX/[email protected]?goos=windows&goarch=amd64&tags=tag1,tag2,tag3

Implement logging

Currently, the program doesn't output anything besides errors or the BOM itself. For debugging and observation purposes, it might be helpful to know what the program is doing.

Decouple license detection

See discussion in #100 starting at #100 (comment).

Possible solutions:

  1. Decouple default license detection logic into a separate module (as roughly outlined in #100 (comment))
    • "Cleanest" option, won't unnecessarily pollute the module graph
    • I'd like to avoid this for numerous reasons:
      • It introduces additional hurdles and complexity
      • License detection is an integral part of app and mod. Opting out of license detection is one use-case of many
  2. Decouple default license detection logic into a separate package
    • Unless explicitly imported, it won't be compiled into the final binary (or vendored when using go mod vendor)
    • Code will still be downloaded by go get, go mod download etc. and may still produce noise in SAST tools
  3. Switch to a more lightweight license detection library
    • Will almost definitely have a negative impact on detected license accurary which I'd like to avoid for a feature release
    • I'm quite happy with the results of go-license-detector and don't see a reason to switch

Add option to strip "v" prefix from versions

Depending on which systems consume the BOM, having the v prefix in the version may or may not be compatible with whatever those systems try to accomplish. Sonatype's OSSIndex for example expects versions without that prefix, and will raise false positives otherwise.

There should be a command line flag that allows for stripping of that prefix.

Add support for dependency graph

CycloneDX supports dependency graphs.

Coincidentally, Go's go mod graph command provides a module graph in pretty much the same structure:

$ go mod graph
github.com/CycloneDX/cyclonedx-gomod github.com/CycloneDX/[email protected]
github.com/CycloneDX/cyclonedx-gomod github.com/google/[email protected]
github.com/CycloneDX/cyclonedx-gomod golang.org/x/[email protected]
github.com/CycloneDX/[email protected] github.com/bradleyjkemp/cupaloy/[email protected]
github.com/CycloneDX/[email protected] github.com/stretchr/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
github.com/bradleyjkemp/cupaloy/[email protected] github.com/davecgh/[email protected]
github.com/bradleyjkemp/cupaloy/[email protected] github.com/pmezard/[email protected]
github.com/bradleyjkemp/cupaloy/[email protected] github.com/stretchr/[email protected]
github.com/bradleyjkemp/cupaloy/[email protected] github.com/stretchr/[email protected]
github.com/stretchr/[email protected] github.com/davecgh/[email protected]
github.com/stretchr/[email protected] github.com/pmezard/[email protected]
github.com/stretchr/[email protected] github.com/stretchr/[email protected]
github.com/stretchr/[email protected] gopkg.in/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
github.com/stretchr/[email protected] github.com/davecgh/[email protected]
github.com/stretchr/[email protected] github.com/pmezard/[email protected]
github.com/stretchr/[email protected] github.com/stretchr/[email protected]
github.com/stretchr/[email protected] gopkg.in/[email protected]
gopkg.in/[email protected] gopkg.in/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]
golang.org/x/[email protected] golang.org/x/[email protected]

An MVP implementation could simply take this output, convert <path>@<version> expressions to package URLs and be done with it.

Will have to figure out how to deal with replacements though. We currently treat replaced modules as ancestors in the replacement component's pedigree. However, the module graph will still reference the replaced module, not the replacement.

Include packages in application SBOM

By using go list, we get to know which packages are actually used, but we currently don't include this information in the SBOM.

Using the info we already have, we can construct a structure according to modules > packages > files, for example:

{
    "bom-ref": "pkg:golang/github.com/ProtonMail/[email protected]",
    "type": "library",
    "name": "github.com/ProtonMail/go-crypto",
    "version": "v0.0.0-20210428141323-04723f9f07d7",
    "scope": "required",
    "hashes": [
        {
            "alg": "SHA-256",
            "content": "62825b7a72bd0baed29339037e642e5659f4e328078f7be365f77d14bf869904"
        }
    ],
    "purl": "pkg:golang/github.com/ProtonMail/[email protected]",
    "components": [
        {
            "bom-ref": "pkg:golang/github.com/ProtonMail/go-crypto#[email protected]",
            "type": "library",
            "name": "bitcurves",
            "version": "v0.0.0-20210428141323-04723f9f07d7",
            "scope": "required",
            "purl": "pkg:golang/github.com/ProtonMail/go-crypto#[email protected]",
            "components": [
                {
                    "type": "file",
                    "name": "bitcurve.go",
                    "version": "v0.0.0-2472c8e5f796",
                    "scope": "required",
                    "hashes": [
                        {
                            "alg": "MD5",
                            "content": "b4689d8871aa46bb387ef148944f8da8"
                        },
                        {
                            "alg": "SHA-1",
                            "content": "2472c8e5f796d8463738938fea98398dabba08ad"
                        }
                        // ...
                    ]
                }
            ]
        }
    ]
}

Including the packages should probably be enabled per default, but including individual files should still be optional.

Add support for creating SBOMs from binaries

Go embeds module version information in the binaries it builds. go version can be used to retrieve that information:

usage: go version [-m] [-v] [file ...]

[...]

The -m flag causes go version to print each executable's embedded
module version information, when available. In the output, the module
information consists of multiple lines following the version line, each
indented by a leading tab character.

[...]

See https://golang.org/cmd/go/#hdr-Print_Go_version

We can use this to build a SBOM.

Incorrect/Extra Data included in sbom.

I tried out this tool on an open source repo I maintain called cosign. The repo is here: https://github.com/sigstore/cosign

I ran the tool at cosign commit 749c7e3e5d80f3fa976f31084317a556718c3e54.
The cyclonedx-gomod version I used was 35b214b43eabfdf6b47499427b93c23ae1f903aa.

I ran: $ cyclonedx-gomod -json > gomod.json

The resulting sbom is available here: https://gist.github.com/dlorenc/17c0582acb0560807e561e436cf76a1e

The tool worked, but a quick look at the data shows some packages that are not included in my application. For example:

"components": [
    {
      "bom-ref": "pkg:golang/bazil.org/[email protected]",
      "type": "library",
      "name": "bazil.org/fuse",
      "version": "v0.0.0-20180421153158-65cc252bf669",
      "scope": "required",
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "14d091a578aab86d5aa32a9c2165459a94d2295731d9b403dfcb9965e1ad765c"
        }
      ],
      "purl": "pkg:golang/bazil.org/[email protected]"
    },

bazil.org/fuse does not appear in my application at all, including it's dependency tree. I do not vendor my code normally (I saw the warnings about this tool only partially supporting vendoring). But if I run go mod vendor, I do not see bazil.org/fuze anywhere in the vendor tree. I can build and run my code without that package, so I think it's a bug that it appears in the SBOM.

You can see a test branch with the vendor directory here: https://github.com/dlorenc/cosign/tree/vendor/vendor/github.com

Note that this is just the first component in the list and the first that I checked. There may be other things missing or incorrect.

Am I misunderstanding the fields? Is there some reason this is included?

Note: This does appear in my go.sum file, but not in the vendor directory and it never makes it into my compiled application, as can be shown by the vendor directory. This means it is used somehow in the dependency constraint calculation by "go mod".

Note that there are

Use license evidence for detected licenses

Quoting the README:

There is currently no standard way for developers to declare their module's license.
Detecting licenses based on files in a repository is a non-trivial task, which is why cyclonedx-gomod
uses pkg.go.dev to resolve module licenses (please read their license disclaimer).

While pkg.go.dev's license matching may be accurate most of the time, BOMs should state facts.
This is why license resolution is an opt-in feature (using the -licenses flag).
If you are a vendor and legally required to provide 100% accurate BOMs, do not use this feature.

We need to include this disclaimer, because the components/licenses node we're currently using represents an assertion.

Since v1.3 of the spec, there's now support for license evidence. Given that we perform error-prone license detection (or leverage services that do it for us), we should put detection results into the component/evidence/licenses node instead.

Include stdlib packages in application SBOM

I've generated a BOM of an application with both -std as well as without: with -std there's only a single Go stdlib component included, without it all included stdlib components seem to be missing from the BOM. I'm using the recent 1.0.0 version, compiled from master only few days ago.

For instance, crypto packages are thus missing from the BOM generated on the basis of the sources, yet scanning the binary reveals that at least some of the crypto packages from the Go stdlib have been bound into the final binary.

Am I doing something wrong or missing some CLI flag that will include stdlib packages en detail into the BOM generated from the sources?

Using single `main` file as entrypoint causes dependencies to be missed in some cases

Someone on Stack Overflow ran into an issue with v1.0.0-alpha.4 where the SBOM generated by app contains only a small subset of modules: https://stackoverflow.com/questions/69329242/cyclonedx-gomod-dbg-dependency-not-found-produces-almost-empty-bom

The issue appears to be that the bulk of packages is imported by files in package main that are not main.go. All files in cmd/lxkns are in package main. Because we only consider a single main file though, we're missing a lot of imports.

Most applications these days have a single main.go that simply calls a function from another package. Meaning package main doesn't really contain anything besides func main().

We can't just use patterns like cmd/lxkns/..., because there are cases where this won't yield the desired result either, providing more dependencies than we actually care about (especially if main.go happens to be in the module's root dir).

We could Walk the directory containing -main and select all .go files with package main declaration, and pass them to go list. However, my testing revealed that this then bypasses build constraints (imports by main_windows.go are loaded even though GOOS is set to linux etc.).

Optionally infer external references from CI environment

Add support for BOM verification

It should be possible to verify that a given module matches the facts stated in the corresponding BOM.

Possible factors to consider when verifying:

  • Component count
  • Component identity (name, version, hashes, scope?, type?)
  • The above should also include the main module (metadata.component in the BOM)
  • Dependency graph? (Are dependency relationships worth verifying?)
  • (Licenses [we can't do that yet, see #2])

Example usage could be:

$ cyclonedx-gomod verify --module . --bom cyclonedx-gomod-v0.3.0.bom.xml

Verification will be supported for Go modules only. No other ecosystems will be considered.

Remove dependency to `go-git`

Just use raw git commands instead. go-git introduces a lot of dependencies we don't otherwise use. Our usage of Git functions is also very shallow, nothing that would justify import such a powerful lib.

`bin`: Support macOS universal binaries

go version -m can't currently deal with macOS universal binaries.

However, with Go 1.18, we will get the necessary tools to implement support for them ourselves, using buildinfo.Read(io.ReaderAt).
Also, Go has had support for reading fat mach-o binaries since 1.3 using macho.OpenFat.

I tinkered a bit, and it's now almost trivial to get go version -m results for all embedded binaries:

import (
	"debug/buildinfo"
	"debug/macho"
	"io"
	"log"
	"os"
)

func LoadBuildInfo118(binaryPath string) error {
	ff, err := macho.OpenFat(binaryPath)
	if err != nil {
		return err
	}
	ff.Close()

	binaryFile, err := os.Open(binaryPath)
	if err != nil {
		return err
	}
	defer binaryFile.Close()

	for i, arch := range ff.Arches {
		header := ff.Arches[i].FatArchHeader

		bi, err := buildinfo.Read(io.NewSectionReader(binaryFile, int64(header.Offset), int64(header.Size)))
		if err != nil {
			return err
		}

		log.Printf("%s: %s@%s (%s)", arch.Cpu, bi.Main.Path, bi.Main.Version, bi.Main.Sum)
	}

	return nil
}

Example output for the universal binary of goreleaser:

2022/02/05 12:34:35 CpuAmd64: github.com/goreleaser/[email protected] (h1:gW8sdjDEo2H2ZgcJmWsNZUcaJSD4MLvA/bw7+GYQ8kU=)
2022/02/05 12:34:35 CpuArm64: github.com/goreleaser/[email protected] (h1:gW8sdjDEo2H2ZgcJmWsNZUcaJSD4MLvA/bw7+GYQ8kU=)

Still torn on what the correct output would be though. Two SBOMs? A merged SBOM?

license determination fails for dependency with version-embedding package import path

Using the beta 2 of cyclonedx-gomod on my public lxkns Github project seems to show a problem with license determination when the package import path contains version information. Of course, I might be mistaken here and this might not be a problem of cyclonedx-gomod but instead of the license checking dependency.

When running cyclonedx-gomod app -json -output ../lxkns-bom.json -main cmd/lxkns/ -licenses -std -verbose . on the checked-out lxkns repository, the bom entry for cenkalti's backoff module catches my eye:

{
      "bom-ref": "pkg:golang/github.com/cenkalti/backoff/[email protected]",
      "type": "library",
      "name": "github.com/cenkalti/backoff/v4",
      "version": "v4.1.1",
      "scope": "required",
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "1b61c07c09af9bf19c29a9f6a0e42905739ddad4f61b9ed99d91966b53f13c14"
        }
      ],
      "purl": "pkg:golang/github.com/cenkalti/backoff/[email protected]",
      "externalReferences": [
        {
          "url": "https://github.com/cenkalti/backoff",
          "type": "vcs"
        }
      ]
    },

A check with the repository shows a LICENSE file for branch v4: MIT license.

Is this just a detection problem or instead a versioned import path issue?

Use `go list` instead of `go mod graph` to build dependency graph

go mod graph apparently isn't really intended for generating an accurate dependency graph (that is, differentiating between direct and transitive dependencies). This becomes painfully obvious when running that command on modules that have go 1.17 in their go.mod file (golang/go#47648).

The output of go list -deps -json has a .Deps field which we could use to build a dependency graph instead. But go list as of today is still subject to build constraints. That will work for the new app command, but not for mod.

There is however an effort of supporting "unconstrained" use of go list: golang/go#42504

Add support for vendoring

We're currently using go list -json -m all to get all modules a given module depends on.

However, that doesn't work with vendoring:

$ go mod vendor
...
$ go list -json -m all
go list -m: can't compute 'all' using the vendor directory

Instead, we can use go mod vendor -v to list all vendored modules. For example, for cyclonedx-go:

$ go mod vendor -v
# github.com/bradleyjkemp/cupaloy/v2 v2.6.0
## explicit
github.com/bradleyjkemp/cupaloy/v2
github.com/bradleyjkemp/cupaloy/v2/internal
# github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew
# github.com/pmezard/go-difflib v1.0.0
github.com/pmezard/go-difflib/difflib
# github.com/stretchr/testify v1.7.0
## explicit
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
gopkg.in/yaml.v3

Lines prefixed with # denote modules as we'd see them with go list.
Lines following ## explicit are packages inside those modules, which we don't care about for now.

cyclonedx-gomod "DBG dependency not found ...", produces almost empty BOM

As suggested in this repository, I tried to reach out first via Stackoverflow cyclonedx-gomod "DBG dependency not found ...", produces almost empty BOM but I got no responses there for some time. If I got the wrong part of the SO fleet, then please direct me to the correct part of the SO community. I noticed that there is no tag dedicated to cylconedx.

Anyway: I'm unsuccessfully trying to generate a BOM from a Go module using cyclonedx-gomod. I've downloaded a binary version from the project's repository https://github.com/CycloneDX/cyclonedx-gomod/releases/tag/v1.0.0-alpha.4, for ARM64 to use on a Raspi 4 with Ubuntu.

Now, when I run cyclonedx-gomod app -json -output mymodule-bom.json -main cmd/myapp/main.go -licenses -std -verbose . while inside my module, I see lots of DBG complaints about dependencies, such as:

dependency not found dependant=github.com/thediveo/[email protected] dependency=github.com/spf13/[email protected]

However, these are public repositories and they have already been used for building, so they're present in the Go module cache. The resulting BOM JSON file consists of maybe four or five entries, but is completely useless because it lacks all dependencies.

What am I doing wrong?

Add support for license resolution

Go currently has no way to define a module's license. pkg.go.dev does display license information, but that's not really accurate and relies on Google's license detection.

Similarly, licenses for modules hosted on GitHub could be retrieved using the GitHub REST API. Responses of the /repos endpoint includes license information.

Another way would be to use license detection mechanisms like the one provided by go-license-detector. Although the detection appears to be quite good, we can't be 100% sure. The question arises if including licenses in the BOM that possibly aren't accurate is better than not including any at all.

For starters, this could be implemented as opt-in feature.

Optionally include Go standard library

Go binaries are statically linked and include the standard library / runtime. The PURL of the standard library would be pkg:golang/[email protected].

For application modules it makes sense to include this in the BOM. For library modules, it doesn't, because no binary is built. This should either be coupled to specific ComponentTypes or an opt-in feature.

The go directive in go.mod defines the minimum version required to build the module. An exact version probably needs to be acquired by calling go version.

Add integration tests

We should have integration tests to verify that generated BOMs

  • contain the facts we're expecting
  • are syntactically valid

Rough idea:

  • git clone a specific tag of any module with a reasonable amount of dependencies
  • go run main.go -module /path/to/module -o itest-bom.xml
  • Compare with snapshot / assert contents
  • cyclonedx validate --input-file itest-bom.xml --fail-on-error

Capture file licenses

We don't currently scan the files of a module for licenses.
As pointed out in the article below however, it is totally possible that some files are licensed differently than the module.
A simple suggested solution was to scan the first X lines of a file for the SPDX-License-Identifier field.

This was part of the feedback in https://zt.dev/posts/analysis-cyclonedx-gomod-sbom/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.