Embed SBOM in native image via generated GraalVM Feature#53923
Embed SBOM in native image via generated GraalVM Feature#53923aloubyansky merged 4 commits intoquarkusio:mainfrom
Conversation
Generate a GraalVM Feature (`io.quarkus.runner.SbomEmbedFeature`) using Gizmo2 that embeds the application SBOM into the native image, following the GraalVM SBOM spec. Internal GraalVM APIs (CGlobalDataFactory, CGlobalDataFeature, Word) are referenced via ClassMethodDesc to avoid compile-time dependencies on internal packages that may change across GraalVM versions. The Feature is only generated when EmbeddedSbomMetadataBuildItem is present (i.e. when CycloneDX SBOM embedding is enabled). See: graalvm/mandrel#962 and quarkusio#53552 Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
CGlobalDataFactory and CGlobalData moved from com.oracle.svm.core.c to com.oracle.svm.guest.staging.c in GraalVM 25.1. The generated Feature now checks the GraalVM version at native image build time and calls the correct API. Also switch from Word.unsigned() to the public WordFactory.unsigned() and fix registerWithGlobalSymbol return type (void, not CGlobalData). Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
jerboaa
left a comment
There was a problem hiding this comment.
Seems OK to me. I think we are going to need a test for this functionality eventually as this could easily break.
One more thought:
#53552 potentially registers the SBOM as a native resource (so we could end up with two copies of the same SBOM in two different places). Not sure how to fix this duplication, though.
|
|
||
| @BuildStep | ||
| void generateSbomEmbedFeature( | ||
| Optional<EmbeddedSbomMetadataBuildItem> embeddedSbomMetadata, |
There was a problem hiding this comment.
Is there a reason to make it optional? Wouldn't a build step be skipped if required input wasn't available?
There was a problem hiding this comment.
That's what I thought as well, but it actually gets triggered with embeddedSbomMetadata being null. I also noticed you did the same in github.com//pull/53552 so I hoped you knew why it's happening. Perhaps it's worth further investigating (beyond the scope of this PR though).
Since there is no native-image support (yet) for inspecting the embedded SBOM we can use The test would only work on linux by the way.
That's a good point. We can probably serve the endpoint from the embedded SBOM but the code will be somewhat complex (I am thinking using a helper method that would be generated using gizmo to access the necessary GraalVM APIs).
Noted, I will add some info there.
I don't know to be honest. One would probably like GraalVM EE to win as its data would be more accurate due to taking in account the static analysis it performs. |
That's actually not obvious. There will be important info in the Quarkus SBOM (metadata, deployment and npm dependencies) that GraalVM won't have. Anyway, it will be a user's choice. |
This comment has been minimized.
This comment has been minimized.
I was thinking we could be using the |
|
Sorry if this sounds stupid, but as I don't know much about SBOM I understand when the docker image would be used |
@geoand in this case the SBOM (a json file essentially) is stored compressed in raw format in the native binary, so we need a tool to extract it from the binary and parse it. |
|
So essentially you want to use |
|
Correct. |
|
I think it's fine |
Add syft-based verification to CycloneDxNativeIT that confirms the SBOM is properly embedded in the native executable and readable by external tooling. The test runs anchore/syft in a container against the native binary and asserts the extracted SBOM contains the expected components. Skipped automatically when no container runtime is available. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Status for workflow
|
|
🙈 The PR is closed and the preview is expired. |
jerboaa
left a comment
There was a problem hiding this comment.
Looks fine. Thanks for the test.
This comment has been minimized.
This comment has been minimized.
Status for workflow
|
Generate a GraalVM Feature (
io.quarkus.runner.SbomEmbedFeature) using Gizmo2 that embeds the application SBOM into the native image, following the GraalVM SBOM spec.Internal GraalVM APIs (CGlobalDataFactory, CGlobalDataFeature, Word) are referenced via ClassMethodDesc to avoid compile-time dependencies on internal packages that may change across GraalVM versions.
CGlobalDataFactoryandCGlobalDatamoved fromcom.oracle.svm.core.ctocom.oracle.svm.guest.staging.cin GraalVM 25.1.The generated Feature checks the GraalVM version at native image build time and calls the correct API.
Tested with:
The disassembly of the generated feature looks like this:
Assisted-by: Claude Opus 4.6 noreply@anthropic.com
Follow up to #53552
Supersedes #53861 and graalvm/mandrel#962
cc @jerboaa