Skip to content

Instantly share code, notes, and snippets.

@Amsamms
Created September 8, 2026 05:06
Show Gist options
  • Select an option

  • Save Amsamms/ce775a92668002119c336dc704d84639 to your computer and use it in GitHub Desktop.

Select an option

Save Amsamms/ce775a92668002119c336dc704d84639 to your computer and use it in GitHub Desktop.
Verification testbed (Dockerfile) for the OSV-SCALIBR erlang/rebarlock inventory extractor - google/osv-scalibr#1952

Verification testbed for the OSV-SCALIBR erlang/rebarlock extractor

This Dockerfile builds a container holding a real rebar.lock, for verifying the software inventory extraction plugin proposed in:

Distribution method: rebar3 / rebar.lock, the lockfile of the standard Erlang/OTP build tool. Packages come from the Hex package manager. OSV ecosystems: Hex, plus GIT for git-pinned dependencies.

Why the lockfile is generated, not copied in

The image does not ship a hand-written fixture. It runs rebar3 lock during the build, so the rebar.lock inside the image is genuinely produced by the build tool. The dependency set is chosen to exercise all three cases the extractor handles:

Case Dependency Expected result
Plain Hex package jsx, cf, quickrand reported against ecosystem Hex
hex.pm name differs from OTP app name app uuid, hex package uuid_erl reported as uuid_erl, not uuid
Git-pinned dependency erlware_commons @ tag v1.5.0 reported against ecosystem GIT with repo + commit, not as a Hex package

The build has a self-check step that fails loudly if any of those three entries is missing, so the image cannot be published in a state that is not useful for verification.

Usage

docker build -t rebarlock-testbed .
docker run --rm rebarlock-testbed          # prints the lockfile the image contains

To scan it with OSV-SCALIBR:

docker run --rm rebarlock-testbed cat /app/rebar.lock > rebar.lock
scalibr --extractors=erlang/rebarlock --root=. --result=-

Verified output

Built and run successfully (podman 3.4.4, base erlang:27.3.4-alpine = Erlang/OTP 27.3.4.17 with rebar3 3.27.0; resulting image 115 MB). docker run --rm rebarlock-testbed prints:

{"1.2.0",
[{<<"cf">>,{pkg,<<"cf">>,<<"0.3.1">>},1},
 {<<"erlware_commons">>,
  {git,"https://github.com/erlware/erlware_commons.git",
       {ref,"6f7a32487a27efe3e2824923b5bf5643c20c21e6"}},
  0},
 {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},0},
 {<<"quickrand">>,{pkg,<<"quickrand">>,<<"2.0.7">>},1},
 {<<"uuid">>,{pkg,<<"uuid_erl">>,<<"2.0.6">>},0}]}.

Note {<<"uuid">>,{pkg,<<"uuid_erl">>,...}}: the OTP application is uuid while the hex.pm package is uuid_erl. An extractor that reports the application name here would produce a package name that does not exist on hex.pm and would never match an OSV record.

# Verification image for the OSV-SCALIBR "erlang/rebarlock" software inventory extractor.
#
# Approved PRP issue : https://github.com/google/osv-scalibr/issues/1952
# Pull request : https://github.com/google/osv-scalibr/pull/2404
# Distribution method: rebar3 / rebar.lock (Hex package manager for Erlang/OTP)
# OSV ecosystems : Hex, plus GIT for git-pinned dependencies
#
# This image does NOT copy in a test fixture. It runs rebar3 itself so that the
# rebar.lock inside the image is genuinely produced by the build tool, and it is
# chosen to cover all three cases the extractor handles:
#
# 1. plain Hex packages ....................... jsx, cf, quickrand -> ecosystem Hex
# 2. hex.pm name differing from the OTP app name app "uuid",
# which on hex.pm is the package "uuid_erl" ................... -> ecosystem Hex
# 3. git-pinned dependency, locked to a commit erlware_commons ... -> ecosystem GIT
#
# Build:
# docker build -t rebarlock-testbed .
# Inspect the lockfile the image contains:
# docker run --rm rebarlock-testbed
# Scan it with OSV-SCALIBR:
# docker run --rm rebarlock-testbed cat /app/rebar.lock > rebar.lock
# scalibr --extractors=erlang/rebarlock --root=. --result=-
FROM erlang:27.3.4-alpine
# This base image already provides Erlang/OTP 27.3.4.17 and rebar3 3.27.0 at
# /usr/local/bin/rebar3. git is required for rebar3 to resolve the git-pinned dep.
RUN apk add --no-cache git
WORKDIR /app
RUN mkdir -p src \
&& printf '%s\n' \
'{erl_opts, [debug_info]}.' \
'{deps, [' \
' {jsx, "3.1.0"},' \
' {uuid, "2.0.6", {pkg, uuid_erl}},' \
' {erlware_commons, {git, "https://github.com/erlware/erlware_commons.git", {tag, "v1.5.0"}}}' \
']}.' \
> rebar.config \
&& printf '%s\n' \
'{application, rebarlock_demo,' \
' [{description, "Demo app producing a real rebar.lock for OSV-SCALIBR plugin verification"},' \
' {vsn, "0.1.0"},' \
' {registered, []},' \
' {applications, [kernel, stdlib]},' \
' {env, []},' \
' {modules, []}]}.' \
> src/rebarlock_demo.app.src
# Resolve dependencies and write /app/rebar.lock.
RUN rebar3 lock
# Fail the build loudly if the lockfile did not come out as expected, so the image
# is only ever published in a state that is actually useful for verifying the plugin.
RUN test -s rebar.lock \
&& grep -q '{pkg,<<"uuid_erl">>' rebar.lock \
&& grep -q 'erlware_commons' rebar.lock \
&& grep -q '{pkg,<<"jsx">>' rebar.lock \
&& echo "OK: rebar.lock contains Hex, differing-app-name and git-pinned entries"
CMD ["cat", "/app/rebar.lock"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment