OpenSSF Best Practices badge¶
Editions: OSS, Cloud, Enterprise. Unless stated otherwise, everything on this page ships in OSS.
This page is a maintainer checklist for the OpenSSF Best Practices badge
and for the Scorecard check that reports
no effort to earn an OpenSSF best practices badge detected.
It is not a completed questionnaire and it does not claim the badge.
The authority for answers is the passing criteria. A dated evidence review from 2026-09-10 is in OpenSSF Best Practices Badge: Readiness Guide. Where the two disagree, prefer this page and the live repository.
How Scorecard detects the badge¶
Scorecard does not read README.md, SECURITY.md, or any other file in this
repository for this check. A badge image, a placeholder URL, or a made-up
project id in the README does not change the result.
The check is named CII-Best-Practices in
Scorecard's check list
and check documentation.
Dashboards often label the same check OpenSSF Best Practices. The documented
remediation is to sign up at bestpractices.dev.
Detection, from current main of
ossf/scorecard:
checks/raw/cii_best_practices.gocallsCIIClient.GetBadgeLevelwith the repository URI.- The default client in
clients/cii_http_client.gosendsGET https://www.bestpractices.dev/projects.json?url=https://github.com/preloop/preloop(the repo URI is prefixed withhttps://). - An empty JSON array is
NotFound. The probeprobes/hasOpenSSFBadgethen returns a negative finding. checks/evaluation/cii_best_practices.goturns that finding into score 0 and the textno effort to earn an OpenSSF best practices badge detected.
badge_level on the first JSON object sets the score:
badge_level contains |
Score | Result text |
|---|---|---|
| (no project; empty array) | 0 | no effort to earn an OpenSSF best practices badge detected |
in_progress |
2 | badge detected: InProgress |
passing |
5 | badge detected: Passing |
silver |
7 | badge detected: Silver |
gold |
10 | badge detected: Gold |
in_progress is matched before passing (strings.Contains on
badge_level). Registering the project is enough to leave "no effort".
Passing, silver, and gold require the site to record those levels.
Checked on 2026-10-04:
https://www.bestpractices.dev/projects.json?url=https://github.com/preloop/preloop
returned []. There is no project id to put in the README.
A separate blob client reads a precomputed result.json from a bucket. The
public Scorecard cron and the
check docs
use the bestpractices.dev API keyed by repository URL. Neither path searches
this git tree.
Register the project¶
A maintainer account on bestpractices.dev is required. This repository cannot enroll itself, and an agent must not invent a project id.
- Sign in at bestpractices.dev with a maintainer account.
- Search for an existing Preloop entry. If none exists, open the new-project form with this repository URL filled in.
- Submit the project. The site assigns a numeric id and starts the entry at
in_progress. Saving partial answers is enough for that level. Do not mark a criterion Met to raise a percentage. - After the entry exists, confirm the API returns a non-empty array for
https://www.bestpractices.dev/projects.json?url=https://github.com/preloop/preloopand thatbadge_levelcontainsin_progress. The next Scorecard run can then report InProgress (score 2). - Fill the passing questionnaire using the map below. When the site records
passing, the same API field becomes
passingand Scorecard's score becomes 5.
README badge, after a real id exists¶
Add this to README.md only after the site shows a numeric project id.
Replace PROJECT_ID with that id. Do not commit the placeholder, and do not
guess an id.
[](https://www.bestpractices.dev/projects/PROJECT_ID)
That markdown is for readers. Scorecard ignores it. Linking the badge from the
repository front page is a silver criterion (documentation_achievements),
which applies after the project has a real achievement to link.
Passing criteria¶
Identifiers match the passing questionnaire. "Evidence" means a public URL a maintainer can paste. It does not mean the criterion has been marked Met. Suggested criteria are included when the repository already answers them; they are not required to pass.
Evidence already in the repository¶
| Criteria | Evidence |
|---|---|
description_good, interact |
README.md, docs/index.md, docs.preloop.ai |
contribution, contribution_requirements |
CONTRIBUTING.md: fork, branch, pull request, review before merge, Ruff and frontend format checks |
floss_license, floss_license_osi, license_location |
Root LICENSE, Apache-2.0, OSI-approved. Answer for the public OSS tree. Do not extend the claim to proprietary clients. |
documentation_basics, documentation_interface |
Docs site, CLI guide, openapi.yaml |
sites_https |
https://github.com/preloop/preloop, https://docs.preloop.ai, https://preloop.ai, GitHub Releases |
discussion, english |
GitHub issues and pull requests; documentation and issue text are in English |
repo_public, repo_track, repo_interim, repo_distributed |
Public git history on GitHub, including pre-release commits |
version_unique, version_semver, version_tags |
Git tags and GitHub Releases. RELEASING.md describes the version flow. |
release_notes |
CHANGELOG.md and the GitHub release notes. Confirm the notes are a human summary, not git log. |
report_process, report_tracker, report_archive |
GitHub issues |
vulnerability_report_process, vulnerability_report_private |
SECURITY.md (security@preloop.ai) and private vulnerability reporting |
build, build_common_tools, build_floss_tools |
pyproject.toml, cli Makefile, frontend/package.json, .github/workflows/ci.yml |
test, test_invocation, test_continuous_integration |
TESTING.md (pytest, npm run test) and the CI workflow |
test_policy, tests_documented_added |
CONTRIBUTING.md: new features and bug fixes should include tests when practical |
warnings |
CI runs ruff check and go vet ./... |
crypto_password_storage |
backend/preloop/api/auth/jwt.py hashes passwords with bcrypt and gensalt() |
delivery_mitm, delivery_unsigned |
HTTPS GitHub Releases. Release verification covers Sigstore provenance. Passing allows HTTPS. It does not require a separate signature. |
static_analysis, static_analysis_common_vulnerabilities, static_analysis_often |
.github/workflows/codeql.yml runs on pull requests, pushes to main, and weekly. Pull-request language jobs are path-filtered. main and the weekly run cover Go, Python, JavaScript/TypeScript, and Actions. The workflow uploads SARIF (upload: true). Ruff and go vet also run in CI. |
dynamic_analysis (suggested) |
.github/workflows/fuzz.yml and docs/fuzzing.md: native Go fuzzers for two parsers, on relevant pull requests and nightly. This is not a whole-product dynamic scan. |
dynamic_analysis_unsafe (suggested; N/A may apply) |
No cgo or C/C++ sources were found in this tree. If the software produced by the project stays in Go, Python, and JavaScript, the memory-unsafe clause allows N/A. Confirm that before selecting it. |
no_leaked_credentials |
.github/workflows/secret-scan.yml and historical dispositions. The maintainer still confirms that any previously valid credential was revoked. Do not paste secrets into the form. |
maintained is a MUST. Activity on main, releases, and issue responses is
the evidence, and a maintainer has to affirm it.
Gaps before marking Passing¶
These are the items that still need a human answer or a fresh check. Do not mark them Met from this page alone.
| Criteria | Remaining work |
|---|---|
know_secure_design, know_common_errors |
A primary developer attests, on the form, to the secure-design principles and vulnerability classes named in the criterion details, including at least one mitigation for each. An architecture document does not answer this. |
vulnerability_report_response |
MUST: every vulnerability report in the last 6 months had an initial response within 14 days. SECURITY.md says acknowledgement is "as soon as possible", which is not a 14-day record. If no reports arrived in that window, the criterion allows N/A. |
report_responses, enhancement_responses |
MUST / SHOULD: a majority of bug reports, and of enhancement requests, from the last 2–12 months were acknowledged. Count the tracker. A handful of answered issues is not a rate. |
tests_are_added |
MUST: show that tests were added with the most recent major changes, matching the policy in CONTRIBUTING.md. |
test_most (suggested) |
TESTING.md records a coverage target (CI fails under 60%, goal 75% overall). A percentage does not by itself prove most branches and functionality are tested. |
warnings_fixed, warnings_strict (strict is suggested) |
Show that enabled Ruff and go vet findings are addressed, not only that the jobs exist. |
release_notes_vulns |
For each release, identify every publicly known runtime vulnerability in the project itself that already had a CVE or similar identifier, and point at the release note. Dependency advisories do not count. N/A is allowed when there were no such vulnerabilities. The maintainer confirms that history. |
vulnerabilities_fixed_60_days, vulnerabilities_critical_fixed |
Confirm no unpatched medium-or-higher vulnerability has been publicly known for more than 60 days, on the release being assessed. A local upgrade or a clean scan of one module is not that confirmation. |
static_analysis_fixed, dynamic_analysis_fixed |
MUST: confirmed exploitable medium-or-higher findings from static or dynamic analysis were fixed in a timely way. A green CodeQL or fuzz job does not answer this. N/A applies only when no such finding was confirmed. |
crypto_published, crypto_call, crypto_floss, crypto_keylength, crypto_working, crypto_weaknesses, crypto_pfs, crypto_random |
Review default protocols, key lengths, and call sites against the criterion text. Password hashing above covers crypto_password_storage only. Standard-library imports are not a complete answer. |
dynamic_analysis_enable_assertions (suggested) |
State which fuzz or test configuration enables assertions, and that those assertions are not required in production builds. |
Silver and gold are separate questionnaires. They are not required to clear
"no effort" or to reach the passing score of 5. For later silver work, the
tree already has CODE_OF_CONDUCT.md
and docs/architecture/governance.md. A
Developer Certificate of Origin or other contributor assertion (dco) was
not found.
What this page does not do¶
It does not register the project, submit answers, or add a badge URL to the README. The support period in SECURITY.md is a signed commitment (release manager, 2026-09-27) for users of Preloop. It is a separate statement from the badge criteria.