OpenSSF Best Practices badge: every answer, ready to paste
This page exists because the badge cannot be filled in from a script. The
BadgeApp accepts POST and PUT only from a logged-in browser session; there
is no API key. So the answers are written here, and a human pastes them.
Why bother. The badge is worth 5 points out of 10 on the Scorecard
CII-Best-Practices check, which is 2.5 % of the aggregate score. That alone
would be a poor reason. The better one is that the questionnaire asks 67
questions a maintainer should be able to answer, and answering them honestly is
how you find out which ones you cannot.
Read the answers before pasting them. Several are Unmet on purpose. An
answer that claims a practice nobody follows is exactly the fault this
repository spends its time hunting, and the badge is not worth acquiring that
way.
Before you start
Sign in at https://www.bestpractices.dev/ with the GitHub account that owns the repository.
Add the project with the repository URL:
https://github.com/stephrobert/collection-scalewayThe form autofills a dozen answers from GitHub. Check them anyway: the autofill guesses from file names, and a guess that lands on the right answer is still a guess.
Work down the page in the order below. It follows the page exactly.
The badge is awarded when every MUST is met and every SHOULD is met or
justified. SUGGESTED criteria may be left Unmet without justification.
Three answers are possible: Met, Unmet, N/A. Some criteria require a
URL alongside Met; they are marked (URL required) below.
Basics
Basic project website content
description_good · MUST · Met
The project produces an Ansible collection for the Scaleway APIs, and the generator that writes it. The README says what it is in its first two sentences, and states the boundary that decides the rest: Terraform provisions resources, Ansible operates existing ones.
interact · MUST · Met
Contribution and bug reporting are described in CONTRIBUTING.md, linked from the README, with issue templates that ask the question that settles a report before the conversation starts.
contribution · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/CONTRIBUTING.md
CONTRIBUTING.md describes what to run before pushing, what gets refused on sight, and how a decision is recorded as an override carrying its reason.
contribution_requirements · SHOULD · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/CONTRIBUTING.md
The same file states the requirements: no hand-edited generated file, a falsification mutation for every new guard, and the language boundary between what is published and what is not.
FLOSS license
floss_license · MUST · Met
GPL-3.0-or-later, declared in
LICENSEand ingalaxy.yml.
floss_license_osi · SUGGESTED · Met
GPL-3.0-or-later is OSI-approved.
license_location · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/LICENSE
Documentation
documentation_basics · MUST · Met
The collection README covers installation, authentication, a sixty-second first run, and the module tables. Every published module carries its own reference page, generated from the same model as its
argument_specso the two cannot describe different things.
documentation_interface · MUST · Met
Each module publishes
DOCUMENTATION,EXAMPLESandRETURN, rendered byansible-docand on Galaxy. As of 0.3.0, 297 options, 62 returned keys and 669 returned fields carry a description, and the release gate refuses to publish a version where one does not.
Other
sites_https · MUST · Met
The repository, the released archives and the Galaxy pages are served over HTTPS only.
discussion · MUST · Met
GitHub Issues and pull requests. Searchable, addressable by URL, open to new participants, and requiring no proprietary client.
english · SHOULD · Met
Everything published is in English: both READMEs,
docs/,galaxy.yml, the changelog, and the documentation of every module. The code, its comments and the test names are in French, which is the maintainer’s language and does not reach a user of the collection. The boundary is written down in the repository’s own instructions.
maintained · MUST · Met
Change Control
Public version-controlled source repository
repo_public · MUST · Met
https://github.com/stephrobert/collection-scaleway
repo_track · MUST · Met (git)
repo_interim · MUST · Met
Every change lands on
mainthrough a pull request; interim versions are public as soon as they are pushed.
repo_distributed · SUGGESTED · Met (git)
Unique version numbering
version_unique · MUST · Met
Each release carries a unique version in
galaxy.yml, and the release gate refuses to publish when the tag and that file disagree.
version_semver · SUGGESTED · Met
Semantic versioning, which Ansible requires of collections. The next number is derived from the changelog fragments rather than chosen.
version_tags · SUGGESTED · Met
Every release is a signed tag, and the workflow publishes on a tag and nothing else.
Release notes
release_notes · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/ansible_collections/stephrobert/scaleway/CHANGELOG.rst
Composed by
antsibull-changelogfrom fragments written with the change they describe. The release gate refuses to publish while a fragment is still pending, so a change cannot ship undescribed.
release_notes_vulns · MUST · Met
No publicly known vulnerability has been fixed to date. The changelog mechanism carries a
security_fixessection for the day one is, and the release notes are composed from those fragments rather than written by hand.
Reporting
Bug-reporting process
report_process · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/CONTRIBUTING.md#issues
report_tracker · SHOULD · Met
https://github.com/stephrobert/collection-scaleway/issues
report_responses · MUST · Met
The repository has a single maintainer, and reports are answered. The issue templates ask for what settles most reports in one exchange: for a module that fails, what Ansible printed; for a module that is missing, what
mise run reportsays about the operation, since every operation is either generated, excluded with its reason, or unclassified and failing CI.
enhancement_responses · SHOULD · Met
Enhancement requests are answered, including when the answer is no. The project has a written boundary that refuses a whole class of them: Terraform provisions resources, Ansible operates existing ones, so an operation that creates or deletes resources is out of scope even when the generator could produce it.
report_archive · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/issues?q=is%3Aissue
Vulnerability report process
vulnerability_report_process · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/blob/0.7.0/SECURITY.md
vulnerability_report_private · MUST · Met (URL required)
https://github.com/stephrobert/collection-scaleway/security/advisories/new
vulnerability_report_response · MUST · Met
SECURITY.md commits to an acknowledgement within 3 working days, a first assessment with its severity and reasoning within 10, and a fix or a reasoned decision not to fix within 90. Those deadlines are written for what one person can hold rather than copied from a template.
Quality
Working build system
build · MUST · Met
mise run packagebuilds the collection archive, checks its contents, installs it into a throwaway directory and asksansible-docfor its documentation. A file present in an archive is not a module Ansible can load, which is why the last two steps exist.
build_common_tools · SUGGESTED · Met (mise, uv, pip, ansible-galaxy)
build_floss_tools · SHOULD · Met
Every tool in the build is FLOSS.
Automated test suite
test · MUST · Met
1154 unit tests, plus
ansible-test sanityon fouransible-coreversions and an integration run of the shipped playbooks against a local emulator.
test_invocation · SHOULD · Met
mise run testfor the unit suite,mise run checkfor everything a pull request must pass.
test_most · SUGGESTED · Unmet
No line-coverage figure is measured or published, so claiming “most” would be a claim nobody checked. What the repository measures instead is whether each guard actually bites:
/falsifyneutralises every declared guard one at a time in a copy outside the repository and requires the named test to fail. That is a different property from coverage, and it is not a substitute for it.
test_continuous_integration · SUGGESTED · Met
Every pull request runs
mise run check,ansible-test sanityon fouransible-coreversions, the archive build, the integration run and the example platform.
New functionality testing
test_policy · MUST · Met
CONTRIBUTING.md requires a test with new functionality, and requires a falsification mutation with any new guard, because a guard whose removal leaves the tests green is a comment.
tests_are_added · MUST · Met
tests_documented_added · SUGGESTED · Met
The requirement is in CONTRIBUTING.md and repeated as a checklist item in the pull request template, with the two ways of writing a mutation that proves nothing, both of which happened here.
Warning flags
warnings · MUST · Met
ruff check,ruff format --check, andmypyin strict mode.
warnings_fixed · MUST · Met
All three are gates: a warning fails the build rather than being reported.
warnings_strict · SUGGESTED · Met
mypyruns in strict mode, and the generator refuses an untranslatable type rather than defaulting it tostr.
Security
Secure development knowledge
know_secure_design · MUST · Met
The maintainer understands the principles. Where they apply here, they are applied and written down: least privilege on every CI job, no secret reachable from a
pull_requestrun, a publication token confined to an environment that only version tags may deploy to, and a runtime that centralises error handling so that no code path copies a secret into a log.
know_common_errors · MUST · Met
The class that matters for this project is secret leakage through generated code. The generator marks a sensitive parameter
no_logfrom a deliberately wide name heuristic, on the stated reasoning that a false positive is fixed by an override while a false negative writes a secret into Ansible’s log. A falsification mutation proves that guard bites.
Use basic good cryptographic practices
crypto_published · MUST · Met
The collection talks to the Scaleway API over TLS through the official SDK. It implements no cryptography of its own.
crypto_call · SHOULD · Met
No cryptography is implemented in this project.
crypto_floss · MUST · Met
Python’s standard library and OpenSSL, through the SDK.
crypto_keylength · MUST · N/A
The project generates no keys and specifies no key lengths. Release signing is keyless: the signature binds the archive to the identity of the workflow that produced it, and the key material is Sigstore’s.
crypto_working · MUST · Met
No broken or obsolete algorithm is used or depended upon.
crypto_weaknesses · SHOULD · Met
crypto_pfs · SHOULD · N/A
The project operates no server and terminates no TLS connection.
crypto_password_storage · MUST · N/A
The project stores no password and authenticates no user. Credentials are read from the environment or the Scaleway configuration file and passed to the SDK.
crypto_random · MUST · N/A
No random value is generated for a security purpose. The generator is deliberately deterministic: the same contract produces the same files, byte for byte, and a golden test measures it.
Secured delivery against man-in-the-middle attacks
delivery_mitm · MUST · Met
The repository is cloned over HTTPS or SSH, the archive is downloaded from Galaxy over HTTPS, and each release carries a signed tag, a keyless signature over the archive and a build provenance attestation. SECURITY.md publishes the two commands that verify them, and the release workflow runs the first one on the archive before publishing it.
delivery_unsigned · MUST · Met
Publicly known vulnerabilities fixed
vulnerabilities_fixed_60_days · MUST · Met
None is known. OSV-Scanner runs on every pull request and weekly, Dependabot watches pip and GitHub Actions, and the dependency lock carries hashes.
vulnerabilities_critical_fixed · SHOULD · Met
Other security issues
no_leaked_credentials · MUST · Met
TruffleHog runs on every pull request. The publication token lives in a GitHub environment reachable only from version tags, and is passed through the environment rather than on a command line, because a command line ends up in a log and a log gets shared.
Analysis
Static code analysis
static_analysis · MUST · Met
CodeQL on Python,
ruffandmypy --strictas gates, and four workflow scanners: actionlint, zizmor, poutine and plumber.
static_analysis_common_vulnerabilities · SUGGESTED · Met
CodeQL’s security query suite.
static_analysis_fixed · MUST · Met
All of them are gates rather than reports.
static_analysis_often · SUGGESTED · Met
On every pull request, and weekly for the ones that need a trusted context.
Dynamic code analysis
dynamic_analysis · SUGGESTED · Met
The test suite runs on every change; the shipped playbooks are played against a local emulator on every pull request; and the example platform is played against the real Scaleway account before a release, with a differential check that the account returns to the resources it held before.
dynamic_analysis_unsafe · SUGGESTED · N/A
Python is memory-safe. There is no C or C++ in this project.
dynamic_analysis_enable_assertions · SUGGESTED · Met
Assertions are enabled: the code is never run with
-O.
dynamic_analysis_fixed · MUST · Met
After you submit
The badge percentage appears immediately; Scorecard picks it up on its next
weekly run, so CII-Best-Practices will still read 0 for a few days. That delay
is the tool’s, not the project’s.
Add the badge to the root README when the percentage reaches 100 %, next to the others:
[](https://www.bestpractices.dev/projects/<ID>)
<ID> is the number in the project URL after registration. Tell the maintainer
of this file what it is, and it will be added to the derived block rather than
pasted by hand.