CycloneDX / CycloneDX/cyclonedx-dotnet

Accept NuGet lockfiles (packages.lock.json) for generating BOMs

Open
#658 4 comments 17 reactions 0 assignees View on GitHub
stale
Dominant language
C#
Stars
294
Forks
123
PR merge metrics
No merged PRs in 30d

Description

NuGet restores are not necessarily repeatable due to configuration differences or updated package versions with floating versions (there is an excellent blog post [here](https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/)).

It would be great if this tool could accept packages.lock.json files as input for generating BOMs. This would allow for:
- Repeatable BOM generation against locked build configurations
- BOM generation from packages.lock.json even if source code was not available (perhaps in a later stage of a build pipeline, for example)

I will try to work on this if I find some time 👍🏻

Example packages.lock.json file:
```json
{
"version": 1,
"dependencies": {
".NETCoreApp,Version=v6.0": {
"Newtonsoft.Json": {
"type": "Direct",
"requested": "[13.0.2, )",
"resolved": "13.0.2",
"contentHash": "R2pZ3B0UjeyHShm9vG+Tu0EBb2lC8b0dFzV9gVn50ofHXh9Smjk6kTn7A/FdAsC8B5cKib1OnGYOXxRBz5XQDg=="
},
"NuGet.Protocol": {
"type": "Direct",
"requested": "[6.2.2, )",
"resolved": "6.2.2",
"contentHash": "HAhpbgwwauffx8aBxPbhm/RcsLBKwBgJ+8tg6jXSiuWehEzo57EAkKNrUulhVOHQZyZVWC/zL0uhRjaUv6RltQ==",
"dependencies": {
"NuGet.Packaging": "6.2.2"
}
},
"Serilog": {
"type": "Direct",
"requested": "[2.11.0, )",
"resolved": "2.11.0",
"contentHash": "ysv+hBzTul6Dp+Hvm10FlhJO3yMQcFKSAleus+LpiIzvNstpeV4Z7gGuIZ1OPNfIMulSHOjmLuGAEDKzpnV8ZQ=="
},
"Serilog.Sinks.Console": {
"type": "Direct",
"requested": "[4.0.1, )",
"resolved": "4.0.1",
"contentHash": "apLOvSJQLlIbKlbx+Y2UDHSP05kJsV7mou+fvJoRGs/iR+jC22r8cuFVMjjfVxz/AD4B2UCltFhE1naRLXwKNw==",
"dependencies": {
"Serilog": "2.10.0"
}
},
"System.CommandLine.DragonFruit": {
"type": "Direct",
"requested": "[0.2.0-alpha.19174.3, )",
"resolved": "0.2.0-alpha.19174.3",
"contentHash": "YtwUWDTkIaj9bUnF7/xifxZ04gp6XKF27Y8EmZpwjMpDeSh+V9uOVjtC1O3BAwQlst4Nr5d3Ytn02aWPOu82YQ==",
"dependencies": {
"System.CommandLine.Experimental": "0.2.0-alpha.19174.3",
"System.CommandLine.Rendering": "0.2.0-alpha.19174.3"
}
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.4.1",
"contentHash": "A5hI3gk6WpcBI0QGZY6/d5CCaYUxJgi7iENn1uYEng+Olo8RfI5ReGVkjXjeu3VR3srLvVYREATXa2M0X7FYJA=="
},
"NuGet.Common": {
"type": "Transitive",
"resolved": "6.2.2",
"contentHash": "GKFWxuDBcX9YWT6+IBNVVrnN0RA65U76DPllr9bYGv3WZ7xy420qeZDCcLfsFSGImJ0yPX55DGotSTIyWrDC/g==",
"dependencies": {
"NuGet.Frameworks": "6.2.2"
}
},
"NuGet.Configuration": {
"type": "Transitive",
"resolved": "6.2.2",
"contentHash": "HMsMLI2zBwpvAArZMHuyt5DO+lhXUcqFGC3GQj2Ykvbn7kzxZdbsBBpAKMpLT6DhYEhYdahTiDwe2cjchSvv4w==",
"dependencies": {
"NuGet.Common": "6.2.2",
"System.Security.Cryptography.ProtectedData": "4.4.0"
}
},
"NuGet.Frameworks": {
"type": "Transitive",
"resolved": "6.2.2",
"contentHash": "U+Ax+WbQTDzldYU7EWDB/SPDmQpYleK6I9mohdADyCTBzCLwVBJvt3CIexbhxctOYS8aeHkWZE58YaWOVOC4jA=="
},
"NuGet.Packaging": {
"type": "Transitive",
"resolved": "6.2.2",
"contentHash": "016aapXsWeKyhxEH+CVUbpvz492nSCB+Rt+q9SDbEBBhAcWvcx6noOxoplHvhfxLg2adlpuNFIL3PSGO6krxFg==",
"dependencies": {
"Newtonsoft.Json": "13.0.1",
"NuGet.Configuration": "6.2.2",
"NuGet.Versioning": "6.2.2",
"System.Security.Cryptography.Cng": "5.0.0",
"System.Security.Cryptography.Pkcs": "5.0.0"
}
},
"NuGet.Versioning": {
"type": "Transitive",
"resolved": "6.2.2",
"contentHash": "DkpzIh5F5R2BSZZoDg6mIBfIMFvSjShHvEzMfTKe9KxcGePO/IkyVKzAlDcu21UEq5H7OZ6wWtR+ox4458vxwg=="
},
"System.CommandLine.Experimental": {
"type": "Transitive",
"resolved": "0.2.0-alpha.19174.3",
"contentHash": "PTJCVcj0rkIYPZzKZbU4uLdEvosmnX2CQR98rY6+efIn96zRtbljl74sPFRFZlLxeLprt42FeZNsYH+QdxCHPA==",
"dependencies": {
"Microsoft.CSharp": "4.4.1"
}
},
"System.CommandLine.Rendering": {
"type": "Transitive",
"resolved": "0.2.0-alpha.19174.3",
"contentHash": "TbLA9yUwzdd/DRlyWS53x/NlOkJ0k1WI+YE8Ne2w/Wk+H9w3XqzRBVZBoL7b2JpHvW2s0mNi4tQRCCi5qgmxkQ==",
"dependencies": {
"System.CommandLine.Experimental": "0.2.0-alpha.19174.3"
}
},
"System.Formats.Asn1": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "MTvUIktmemNB+El0Fgw9egyqT9AYSIk6DTJeoDSpc3GIHxHCMo8COqkWT1mptX5tZ1SlQ6HJZ0OsSvMth1c12w=="
},
"System.Security.Cryptography.Cng": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==",
"dependencies": {
"System.Formats.Asn1": "5.0.0"
}
},
"System.Security.Cryptography.Pkcs": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "9TPLGjBCGKmNvG8pjwPeuYy0SMVmGZRwlTZvyPHDbYv/DRkoeumJdfumaaDNQzVGMEmbWtg07zUpSW9q70IlDQ==",
"dependencies": {
"System.Formats.Asn1": "5.0.0",
"System.Security.Cryptography.Cng": "5.0.0"
}
},
"System.Security.Cryptography.ProtectedData": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
}
}
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the packages.lock.json example and compare it with the repository's existing package-input and BOM-generation entry points. Done means the tool accepts NuGet lockfiles and produces a BOM from the locked dependency data even when the source project is unavailable; add coverage alongside the existing input-format tests if those are found.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.