Repository navigation
Releases: 0xsan7/SCRAM
Release list
v0.2.0
⚠ BREAKING: schema_version is now 2.0.0, and repo_score means something different
If you consume SCRAM's JSON, read this before upgrading. Your code will not
fail — it will be quietly wrong.
summary.repo_score changed meaning and kept its name. It is now a
presented score out of 65. It used to be a raw total out of 100.
A consumer written against schema_version: 1.0.0 parses the new document
successfully, because the field names are unchanged. It then renders
25/100 for what is now 25/65 — wrong by 35%, with nothing in the
document to contradict it. That is why this is a major version bump rather
than a minor one: the failure mode is silence.
What to change
- fmt.Printf("score %d/100\n", summary.repo_score)
+ fmt.Printf("score %d/%d\n", summary.repo_score, summary.repo_score_max)Read summary.repo_score_max. Do not hardcode either 65 or 100. If your
consumer compares scores across versions of SCRAM, note that a score from
1.x and a score from 2.x are on different scales and are not comparable —
this is the one case where a trend line built from old history needs to be
discarded rather than continued.
What did not change
- The ordering is identical. A consumer that only sorts, ranks, or picks
the maximum is unaffected; the severity ordering underneath is the same. scram badgereads a scan document, so it picked the change up
automatically and now emits25/65.- SARIF is unaffected: it never carried a repository score, and its
securitySeverityis GitHub's own 0–10 CVSS field. - The formula is untouched. Severity (40), exploitability (25),
maintenance (20) and freshness (15) are computed exactly as before, in the
same units with the same weights.--explainprints all four plus the
0–100 subtotal they sum to, so the arithmetic stays checkable. Only the
total the score is reported against changed.
Bucket boundaries moved with the scale
| Bucket | 2.x (of 65) | was (of 100) |
|---|---|---|
| Critical | 58–65 | 90–100 |
| High | 45–57 | 70–89 |
| Medium | 26–44 | 40–69 |
| Low | 1–25 | 1–39 |
| Clean | 0 | 0 |
The rescale is monotonic but not bucket-preserving. Checked across all 101
possible inputs, exactly two change bucket, both upward: a raw total of 69
becomes high (it was medium), and 89 becomes critical (it was high).
No input is demoted. If you alert on bucket transitions, expect those two.
Why 65 and not 100
scripts/measure_score_terms.sh runs every ecosystem and prints which terms
carry data. Severity is the only term that scores without an opt-in flag.
Exploitability needs EPSS, which is a per-CVE fetch that returns nothing when
FIRST is unreachable, and freshness needs latest-version data this project
does not collect — so it is structurally zero everywhere.
Dividing by 100 advertised 35 points the tool usually cannot earn, and a
moderately-scored repository read as "39/100" when 39 was all the evidence
there was. See ROADMAP.md
for what a 100-point scale would require.
Changelog
Fixes
- 7a76788 fix: post the PR report when the policy gate fails
Other
- 83fbb01 release: prepare v0.2.0 install instructions and verification notes
Verifying this release
Every binary is checksummed and signed keyless. The signature is
bound to this repository's workflow identity and recorded in the
public Rekor transparency log, so it can be verified by anyone
without trusting anything GitHub says.
Download the binary for your platform, plus its .pem and .sig,
and the checksum file. Then, from that directory:
# 1. Checksums. Verifies every binary present in this directory
# against scram_0.2.0_checksums.txt. If you downloaded
# only one platform, the lines for the others report "No such
# file" -- that is expected, and is not a verification failure.
shasum -a 256 -c scram_0.2.0_checksums.txt
# (Linux: sha256sum -c scram_0.2.0_checksums.txt)
# 2. Signature. Replace the platform suffix with yours:
# darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, or
# windows-amd64.exe
cosign verify-blob \
--certificate scram-0.2.0-linux-amd64.pem \
--signature scram-0.2.0-linux-amd64.sig \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
scram-0.2.0-linux-amd64Success prints Verified OK. A signature from a different
repository is rejected with none of the expected identities matched what was in the certificate.
The certificate's identity is
https://github.com/0xsan7/SCRAM/.github/workflows/ci.yml@refs/tags/v0.2.0,
which is what ties the binary to this specific tag.
Built from commit 7a76788.
What is in this binary
The CycloneDX and SPDX SBOMs ship as release assets alongside these
binaries, generated by this project's own code from this
repository. They list every module in the released binary's own
dependency graph, so you can enumerate exactly what shipped without
rebuilding or re-running anything.
v0.2.0-rc1
⚠ BREAKING: schema_version is now 2.0.0, and repo_score means something different
Superseded by stable v0.2.0, which also posts the PR findings comment after a policy failure.
If you consume SCRAM's JSON, read this before upgrading. Your code will not
fail — it will be quietly wrong.
summary.repo_score changed meaning and kept its name. It is now a
presented score out of 65. It used to be a raw total out of 100.
A consumer written against schema_version: 1.0.0 parses the new document
successfully, because the field names are unchanged. It then renders
25/100 for what is now 25/65 — wrong by 35%, with nothing in the
document to contradict it. That is why this is a major version bump rather
than a minor one: the failure mode is silence.
What to change
- fmt.Printf("score %d/100\n", summary.repo_score)
+ fmt.Printf("score %d/%d\n", summary.repo_score, summary.repo_score_max)Read summary.repo_score_max. Do not hardcode either 65 or 100. If your
consumer compares scores across versions of SCRAM, note that a score from
1.x and a score from 2.x are on different scales and are not comparable —
this is the one case where a trend line built from old history needs to be
discarded rather than continued.
What did not change
- The ordering is identical. A consumer that only sorts, ranks, or picks
the maximum is unaffected; the severity ordering underneath is the same. scram badgereads a scan document, so it picked the change up
automatically and now emits25/65.- SARIF is unaffected: it never carried a repository score, and its
securitySeverityis GitHub's own 0–10 CVSS field. - The formula is untouched. Severity (40), exploitability (25),
maintenance (20) and freshness (15) are computed exactly as before, in the
same units with the same weights.--explainprints all four plus the
0–100 subtotal they sum to, so the arithmetic stays checkable. Only the
total the score is reported against changed.
Bucket boundaries moved with the scale
| Bucket | 2.x (of 65) | was (of 100) |
|---|---|---|
| Critical | 58–65 | 90–100 |
| High | 45–57 | 70–89 |
| Medium | 26–44 | 40–69 |
| Low | 1–25 | 1–39 |
| Clean | 0 | 0 |
The rescale is monotonic but not bucket-preserving. Checked across all 101
possible inputs, exactly two change bucket, both upward: a raw total of 69
becomes high (it was medium), and 89 becomes critical (it was high).
No input is demoted. If you alert on bucket transitions, expect those two.
Why 65 and not 100
scripts/measure_score_terms.sh runs every ecosystem and prints which terms
carry data. Severity is the only term that scores without an opt-in flag.
Exploitability needs EPSS, which is a per-CVE fetch that returns nothing when
FIRST is unreachable, and freshness needs latest-version data this project
does not collect — so it is structurally zero everywhere.
Dividing by 100 advertised 35 points the tool usually cannot earn, and a
moderately-scored repository read as "39/100" when 39 was all the evidence
there was. See ROADMAP.md
for what a 100-point scale would require.
Changelog
Security
- 4bf37c4 fix(diff): the vulnerability differential was comparing raw id strings
- af8e58f fix(resolve): every go.mod-only project reported zero vulnerabilities
Features
- fe2ff76 feat(resolve): yarn, pnpm and Cargo, and a go.mod fallback
- 343cb32 feat(score): the maintenance term reads a real OpenSSF Scorecard
- c93bc05 feat(score): the presented score is out of 65, because 65 is what it measures
Fixes
- 202752f fix(ci): pass the script path on stdin, not in the program text
- e452879 fix(ci): resolve the test interpreter per platform
- 32569c0 fix(report): the JSON said 25 and never said out of what
- 9f4ae85 fix(resolve): pnpm 6.0 lost 76% of its dependency tree
- aeefc1d fix: reject malformed Go module paths before v0.2.0 release
Other
- 0d53163 test(corpus): real yarn, pnpm and cargo lockfiles, 29 files, 13.8 MB
- f7232df test(resolve): the silent-zero invariant now follows the registry
Verifying this release
Every binary is checksummed and signed keyless. The signature is
bound to this repository's workflow identity and recorded in the
public Rekor transparency log, so it can be verified by anyone
without trusting anything GitHub says.
Download the binary for your platform, plus its .pem and .sig,
and the checksum file. Then, from that directory:
# 1. Checksums. Verifies every binary present in this directory
# against scram_0.2.0-rc1_checksums.txt. If you downloaded
# only one platform, the lines for the others report "No such
# file" -- that is expected, and is not a verification failure.
shasum -a 256 -c scram_0.2.0-rc1_checksums.txt
# (Linux: sha256sum -c scram_0.2.0-rc1_checksums.txt)
# 2. Signature. Replace the platform suffix with yours:
# darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, or
# windows-amd64.exe
cosign verify-blob \
--certificate scram-0.2.0-rc1-linux-amd64.pem \
--signature scram-0.2.0-rc1-linux-amd64.sig \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
scram-0.2.0-rc1-linux-amd64Success prints Verified OK. A signature from a different
repository is rejected with none of the expected identities matched what was in the certificate.
The certificate's identity is
https://github.com/0xsan7/SCRAM/.github/workflows/ci.yml@refs/tags/v0.2.0-rc1,
which is what ties the binary to this specific tag.
Built from commit aeefc1d.
What is in this binary
The CycloneDX and SPDX SBOMs ship as release assets alongside these
binaries, generated by this project's own code from this
repository. They list every module in the released binary's own
dependency graph, so you can enumerate exactly what shipped without
rebuilding or re-running anything.
v0.1.0
Changelog
Verifying this release
Every binary is checksummed and signed keyless. The signature is
bound to this repository's workflow identity and recorded in the
public Rekor transparency log, so it can be verified by anyone
without trusting anything GitHub says.
Download the binary for your platform, plus its .pem and .sig,
and the checksum file. Then, from that directory:
# 1. Checksums. Verifies every binary present in this directory
# against scram_0.1.0_checksums.txt. If you downloaded
# only one platform, the lines for the others report "No such
# file" -- that is expected, and is not a verification failure.
shasum -a 256 -c scram_0.1.0_checksums.txt
# (Linux: sha256sum -c scram_0.1.0_checksums.txt)
# 2. Signature. Replace the platform suffix with yours:
# darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, or
# windows-amd64.exe
cosign verify-blob \
--certificate scram_0.1.0-linux-amd64.pem \
--signature scram_0.1.0-linux-amd64.sig \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
scram_0.1.0-linux-amd64Success prints Verified OK. A signature from a different
repository is rejected with none of the expected identities matched what was in the certificate.
The certificate's identity is
https://github.com/0xsan7/SCRAM/.github/workflows/ci.yml@refs/tags/v0.1.0-rc1,
which is what ties the binary to this specific tag.
Built from commit de903ac.
What is in this binary
The CycloneDX and SPDX SBOMs ship as release assets alongside these
binaries, generated by this project's own code from this
repository. They list every module in the released binary's own
dependency graph, so you can enumerate exactly what shipped without
rebuilding or re-running anything.
v0.1.0-rc3
Superseded by v0.1.0, which is the same code with the release promoted. Use v0.1.0.
Changelog
Fixes
- 4d794f3 fix(action): a commit SHA starting with a digit was accepted as a version
- 03c5a1c fix(action): the action could not run on a pull request at all
- ec3db02 fix(action): the baseline could never suppress anything
Verifying this release
Every binary is checksummed and signed keyless. The signature is
bound to this repository's workflow identity and recorded in the
public Rekor transparency log, so it can be verified by anyone
without trusting anything GitHub says.
Download the binary for your platform, plus its .pem and .sig,
and the checksum file. Then, from that directory:
# 1. Checksums. Verifies every binary present in this directory
# against scram_0.1.0-rc3_checksums.txt. If you downloaded
# only one platform, the lines for the others report "No such
# file" -- that is expected, and is not a verification failure.
shasum -a 256 -c scram_0.1.0-rc3_checksums.txt
# (Linux: sha256sum -c scram_0.1.0-rc3_checksums.txt)
# 2. Signature. Replace the platform suffix with yours:
# darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, or
# windows-amd64.exe
cosign verify-blob \
--certificate scram_0.1.0-rc3-linux-amd64.pem \
--signature scram_0.1.0-rc3-linux-amd64.sig \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
scram_0.1.0-rc3-linux-amd64Success prints Verified OK. A signature from a different
repository is rejected with none of the expected identities matched what was in the certificate.
The certificate's identity is
https://github.com/0xsan7/SCRAM/.github/workflows/ci.yml@refs/tags/v0.1.0-rc1,
which is what ties the binary to this specific tag.
Built from commit ec3db02.
What is in this binary
The CycloneDX and SPDX SBOMs ship as release assets alongside these
binaries, generated by this project's own code from this
repository. They list every module in the released binary's own
dependency graph, so you can enumerate exactly what shipped without
rebuilding or re-running anything.
v0.1.0-rc2
Known broken — superseded by v0.1.0. Do not use.
Changelog
Fixes
- 5c17745 fix(action): the output directory was never created, and a crash was reported as a policy failure
- 6802f79 fix(action): the v0.1.0-rc1 action could not run at all
Other
- a0cb565 release: publish correctly, and fix instructions that verify nothing
Verifying this release
Every binary is checksummed and signed keyless. The signature is
bound to this repository's workflow identity and recorded in the
public Rekor transparency log, so it can be verified by anyone
without trusting anything GitHub says.
Download the binary for your platform, plus its .pem and .sig,
and the checksum file. Then, from that directory:
# 1. Checksums. Verifies every binary present in this directory
# against scram_0.1.0-rc2_checksums.txt. If you downloaded
# only one platform, the lines for the others report "No such
# file" -- that is expected, and is not a verification failure.
shasum -a 256 -c scram_0.1.0-rc2_checksums.txt
# (Linux: sha256sum -c scram_0.1.0-rc2_checksums.txt)
# 2. Signature. Replace the platform suffix with yours:
# darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, or
# windows-amd64.exe
cosign verify-blob \
--certificate scram_0.1.0-rc2-linux-amd64.pem \
--signature scram_0.1.0-rc2-linux-amd64.sig \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
scram_0.1.0-rc2-linux-amd64Success prints Verified OK. A signature from a different
repository is rejected with none of the expected identities matched what was in the certificate.
The certificate's identity is
https://github.com/0xsan7/SCRAM/.github/workflows/ci.yml@refs/tags/v0.1.0-rc1,
which is what ties the binary to this specific tag.
Built from commit 5c17745.
What is in this binary
The CycloneDX and SPDX SBOMs ship as release assets alongside these
binaries, generated by this project's own code from this
repository. They list every module in the released binary's own
dependency graph, so you can enumerate exactly what shipped without
rebuilding or re-running anything.
v0.1.0-rc1
Known broken — superseded by v0.1.0. Do not use.
Changelog
Security
- 7953625 fix(vuln): a merged advisory must not inherit a sibling's CVSS score
- a9560ca security: audit the public repository with real scanners, and make it standing
Features
- 842d9bc feat: SCRAM MVP — PR-native supply chain risk scanning
- 7023590 feat: dependency blame (scram blame )
- 23f99c5 feat: dependency blast radius (scram why)
- ef1d8d8 feat: pyproject.toml support (PEP 621 + Poetry), and two bugs it exposed
- 27d92cf feat: real npm v1 coverage, D25 fetcher regression tests, LIMITATIONS.md
- 84ff639 feat: risk-score trend sparkline
- 3dbea03 feat: self-score badge (scram badge)
Fixes
- 6f837aa fix(action): actually produce and upload SARIF, and flag the release ref as pending
- a33c1ba fix(blame): report a re-add after removal, and refuse to guess on a shallow clone
- 7e8d2d0 fix: a second D25 false negative in the pyproject fetch path
- 160f3e6 fix: detect and read the requirements filenames the resolver already claimed
- 7f6aaf2 fix: enforce a silent-zero invariant across resolver, scan, and CLI
- 4a9e582 fix: modern npm lockfiles with a top-level dependencies map resolved to zero
- fa78884 fix: two release ldflags named symbols that do not exist
Other
- bf96799 ci: cosign was installed after GoReleaser instead of before it
- eff793b ci: nightly fuzz, Go/OS matrix, golangci-lint — and the bug the linter found
- cd267de ci: replace the shell formatting check with a Go program, and add the C/F docs
- 8d0176b ci: the Windows failure was CRLF, and it took the log to find out
- b9e4d19 ci: the release job could never run, because the workflow had no tag trigger
- acd109b ci: the secret-scan workflow failed on its first run, on a URL I guessed
- e19c8f6 ci: windows-latest failed on a POSIX-only step, not on any code
- d459449 launch: Marketplace branding check, issue templates, and a changelog that cannot drift
- 3070c13 release: the first tag exposed three real bugs in the release path
- 3781f1e release: the footer template used artifact-only keys in a release scope
- 29ac2db release: verified GoReleaser, SECURITY.md, decision index, real coverage
Verifying this release
Every binary is checksummed and signed keyless, and the signature is
bound to this workflow's identity through the public Rekor log.
# 1. Checksums -- one file covers all five targets
sha256sum -c scram_0.1.0-rc1_checksums.txt
# 2. Signatures. The .pem and .sig files sit beside each binary, under
# scram_<os>_<arch>/. This loop checks every one of them.
for f in scram-*/scram scram-*/scram.exe; do
[ -f "$f" ] || continue
cosign verify-blob \
--certificate "$f.pem" \
--signature "$f.sig" \
--certificate-identity-regexp 'https://github.com/0xsan7/SCRAM/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
"$f"
doneBuilt from commit 3781f1e on HEAD.
The CycloneDX and SPDX SBOMs ship as release assets, generated by
this project's own code from this repository, so you can enumerate
exactly what the released binary was built from without re-running
anything.