feat(action): add sbom input so SPDX output is reachable from the GitHub Action - #1099
feat(action): add sbom input so SPDX output is reachable from the GitHub Action#1099Ayush7614 wants to merge 1 commit into
Conversation
…Hub Action Closes OWASP#1078. The CLI supports --sbom cyclonedx|spdx but the Action only exposed the legacy cdx boolean, so SPDX SBOMs were unreachable in CI. This adds a first-class sbom input (cyclonedx|spdx, case-insensitive, with cdx/spdx2.3 aliases) plus sbom-inventory-only, keeps cdx as a deprecated fallback (sbom wins when both are set), and fails fast on unknown formats instead of silently scanning without an SBOM.
sonukapoor
left a comment
There was a problem hiding this comment.
The design here is the right one and I want to lead with that, because the security-sensitive part is done better than the surrounding code.
The user's value never reaches argv. You normalise it in a case and only ever append hardcoded literals, so there is nothing to escape. I threw spdx; rm -rf /, $(touch ...), backticks, embedded newlines and a bare * at the composed block and every one hit the *) branch and exited 1. Compare --ca-cert and --fail-on, which pass raw values through. Yours is the better pattern and I would like new enum inputs to follow it.
Backward compatibility checks out too. I ran the matrix and cdx: "true" on its own composes exactly what it does on main, so pinned workflows are unaffected. Including sbom-inventory-only when the issue only listed it as a "consider" was a good call, and allowing it alongside cdx is correct.
Four things before it goes in.
1. echo swallows -n, which defeats the fail-fast guard. action.yml:309. Bash's echo builtin treats -n, -e and -E as options:
in=<-n> echo -> <> printf -> <-n>
in=<-e> echo -> <> printf -> <-e>
So sbom: "-n" normalises to empty, the -n "$sbom_input" test at line 310 is false, the invalid-value guard never runs, and it falls through to the cdx branch. The job then scans with no SBOM and no error, which is the exact outcome your PR description says it prevents. printf '%s' "${INPUT_SBOM:-}" fixes it. Not ${INPUT_SBOM,,} please, that needs bash 4 and GitHub's macOS runners are still on 3.2.
2. The Action accepts four formats the CLI rejects. The CLI's alias table is exactly cyclonedx, spdx, spdx2.3. Verified:
--sbom cdx -> Unknown --sbom format "cdx"
--sbom cyclone-dx -> Unknown --sbom format "cyclone-dx"
--sbom spdx-2.3 -> Unknown --sbom format "spdx-2.3"
--sbom spdx2.3 -> works
So sbom: cdx succeeds in CI and the same thing fails on someone's laptop. I would narrow the case to cyclonedx|spdx|spdx2.3. Also the error message lists only cyclonedx, spdx and drops spdx2.3, which we document as first-class.
3. website/docs/spdx.md:93-105 still says this feature does not exist. It currently tells people the action has no SPDX input and gives an npx workaround. That is the page the issue named specifically. It wants to become an sbom: spdx example.
4. "Deprecated" on the cdx input contradicts the rest of the codebase. action.yml:63 and github-action.md:43. args.ts calls it a permanent alias, the SPDX docs call it "still supported", and the issue says it must keep working unchanged. Calling it deprecated in the Marketplace description signals removal to exactly the pinned-workflow users we are protecting. "Alias for sbom: cyclonedx" would be truer.
Smaller things, take or leave: there are em dashes in action.yml:63 and :329, and line 329 prints into CI logs. The sbom-inventory-only description says it requires sbom, but the code accepts cdx too. And a value like " spdx " hard-fails on whitespace.
One thought on the tests rather than a request. They pin exact strings like sbom_input=$(echo "${INPUT_SBOM:-}", so fixing item 1 will break them with no behaviour change. None of them parse the YAML or run the shell, and we have no actionlint step, so action.yml has no real guard today. Executing the block with the env vars set and asserting the composed args array is how I found item 1, and it would be worth more than more indexOf assertions.
Closes #1078.
Summary
The CLI supports
--sbom cyclonedx|spdxbut the GitHub Action only exposed the legacycdxboolean, so SPDX 2.3 SBOMs were unreachable in CI.Changes
sbominput (cyclonedx|spdx, case-insensitive,cdx/spdx2.3aliases). Takes precedence overcdx.sbom-inventory-onlyinput wired to--sbom-inventory-only(warns when no SBOM output is enabled).cdxkept as deprecated fallback (elif), so existing workflows keep working and setting both does not emit two SBOM flags.sbomvalues fail fast with::error::instead of silently scanning without an SBOM.website/docs/github-action.md.Verification
tests/github-action.test.ts: 7 tests pass (new: sbom wiring, cdx fallback precedence, invalid-format rejection, inventory-only, alias normalization).npm run buildpasses;action.ymlparses as valid YAML.