{"id":1,"user_id":25,"name":"BadgeApp","description":"BadgeApp is the web application that allows developers to provide information about their project and (hopefully) get an Open Source Security Foundation (OpenSSF) Best Practices badge. This project was originally known as the Core Infrastructure Initiative (CII) best practices badge project.\r\n\r\nThe Open Source Security Foundation (OpenSSF) is managed by The Linux Foundation.  The OpenSSF Best Practices badge online application (aka the BadgeApp) enables developers to quickly determine whether they are following best practices and to receive a badge they can display on GitHub and other locations. The application and its criteria are an open source project to which developers can contribute.\r\n\r\nYou can see the program running, and use it to try to get a badge, by visiting: https://bestpractices.dev/\r\n\r\nThe BadgeApp is written in Ruby on Rails and Javascript.\r\n\r\nSee the development site on GitHub for more about how we secure this application.\r\n\r\nNote that the BadgeApp gets both \"metal\" series badges and \"baseline\" series badges; we want to earn the badges we manage!","homepage_url":"https://github.com/ossf/best-practices-badge","repo_url":"https://github.com/ossf/best-practices-badge","license":"MIT","homepage_url_status":"?","homepage_url_justification":"","sites_https_status":"Met","sites_https_justification":"The project website and repo use GitHub, which supports HTTPS using TLS.  There's no separate download URL (use git to download from the repo).","description_good_status":"Met","description_good_justification":"https://github.com/ossf/best-practices-badge","interact_status":"Met","interact_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md","contribution_status":"Met","contribution_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md","contribution_requirements_status":"Met","contribution_requirements_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md","license_location_status":"Met","license_location_justification":"It's in the LICENSE file in the top level directory.  See: https://github.com/ossf/best-practices-badge/blob/main/blob/main/LICENSE","floss_license_status":"Met","floss_license_justification":"The MIT license is widely acknowledged as being OSS.  The license is at https://github.com/ossf/best-practices-badge/blob/main/LICENSE The MIT license is approved by the Open Source Initiative (OSI).","floss_license_osi_status":"Met","floss_license_osi_justification":"The MIT license is approved by the Open Source Initiative (OSI).","documentation_basics_status":"Met","documentation_basics_justification":"The directory \"doc\" contains most documentation. Installation information is at https://github.com/ossf/best-practices-badge/blob/main/docs/INSTALL.md and other materials are at https://github.com/ossf/best-practices-badge/tree/main/docs/","documentation_interface_status":"Met","documentation_interface_justification":"Its interface is defined here: https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md#interface","repo_public_status":"Met","repo_public_justification":"It uses git, URL is https://github.com/ossf/best-practices-badge/","repo_track_status":"Met","repo_track_justification":"Uses git to track this. Repository on GitHub, which uses git. git can track the changes, who made them, and when they were made.","repo_interim_status":"Met","repo_interim_justification":"Interim versions are put on git, not just final versions.","repo_distributed_status":"Met","repo_distributed_justification":"Uses git. Repository on GitHub, which uses git. git is distributed.","version_unique_status":"Met","version_unique_justification":"The primary single user uses git commit records to identify releases.","version_semver_status":"Unmet","version_semver_justification":"BadgeApp undergoes continuous integration and is then deployed to a single site, \u003chttps://bestpractices.dev/\u003e.  We used Semantic Versioning for a while, but SemVer is a poor fit for this kind of situation, and we eventually gave up the practice.  Every version continues to have a unique version identifier: the git commit id.","version_tags_status":"Met","version_tags_justification":"Full releases are tagged using 'git tag'.","release_notes_status":"Met","release_notes_justification":"CHANGELOG file is in top directory, see: https://github.com/ossf/best-practices-badge/blob/main/CHANGELOG.md","release_notes_vulns_status":"Met","release_notes_vulns_justification":"We intend to do that, though we don't know of any for-certain publicly known vulnerabilities.\r\n\r\nOur release notes do document that commit fdb83380 on 2015-11-26 updated gem nokogiri from 1.6.6.2 to 1.6.6.4 due to CVE-2015-1819.  It's not clear if our application was actually vulnerable; it was easier to simply upgrade.  In any case, we upgraded immediately, and this is documented in our release notes.\r\n","report_url_status":"?","report_url_justification":"","report_tracker_status":"Met","report_tracker_justification":"Yes, GitHub issue tracker.","report_process_status":"Met","report_process_justification":"Yes, either GitHub issue tracker or mailing list.  See: https://github.com/ossf/best-practices-badge/blob/main/README.md","report_responses_status":"Met","report_responses_justification":"Yes.  Not many have been submitted so far, but we've responded.","enhancement_responses_status":"Met","enhancement_responses_justification":"The project has been responding to most enhancement requests.","report_archive_status":"Met","report_archive_justification":"Yes, via GitHub isue tracker: https://github.com/ossf/best-practices-badge/issues","vulnerability_report_process_status":"Met","vulnerability_report_process_justification":"https://github.com/ossf/best-practices-badge/issues","vulnerability_report_private_status":"Met","vulnerability_report_private_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md","vulnerability_report_response_status":"Met","vulnerability_report_response_justification":"No external reports so far, so this is vacuously true.","build_status":"N/A","build_justification":"The software is written using Ruby and Javascript, and their implementations run directly on the source code.","build_common_tools_status":"N/A","build_common_tools_justification":"Note that a Gemfile.lock file and Rake tasks are provided to enable others to quickly recreate a development environment.","build_floss_tools_status":"N/A","test_status":"Met","test_justification":"Yes, it includes a test suite based on minitest (the test framework that comes with Rails).","test_invocation_status":"Met","test_invocation_justification":"Yes. \"rake test\" invokes the automated test suite. The default \"rake\" command includes \"rake test\".  This is documented in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md).","test_most_status":"Met","test_most_justification":"Met.  Currently coverage of the ruby code is over 90%, and most of the code is in Ruby.","test_policy_status":"Met","test_policy_justification":"Yes.  The CONTRIBUTING file at \u003chttps://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md\u003e says,  \"When adding or changing functionality, please include new tests for them as part of your contribution\". Also, the project home page shows the test coverage, which encourages adding tests as new functionality is added.","tests_are_added_status":"Met","tests_are_added_justification":"Tests are added as new functionality is added.","tests_documented_added_status":"Met","tests_documented_added_justification":"Yes.  The CONTRIBUTING file at \u003chttps://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md\u003e says,  \"When adding or changing functionality, please include new tests for them as part of your contribution\".","warnings_status":"Met","warnings_justification":"The set of tools used for examining code quality are listed in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md).\r\n\r\nThe project uses rubocop and rails_best_practices to check for code quality errors in Ruby code; eslint is used to look for problems in Javascript.  The markdown documentation is scanned with markdownlink.","warnings_fixed_status":"Met","warnings_fixed_justification":"In general warnings are addressed.  In some cases warnings are disabled for specific cases.","warnings_strict_status":"Met","warnings_strict_justification":"The settings for the warning tools are generally fairly strict.","know_secure_design_status":"Met","know_secure_design_justification":"David A. Wheeler, lead developer, literally wrote the code on how to design secure software: http://www.dwheeler.com/secure-programs","know_common_errors_status":"Met","know_common_errors_justification":"For a discussion of security requirements, common types of security vulnerabilities, and how this application counters those common kinds of vulnerabilities, see: https://github.com/ossf/best-practices-badge/blob/main/docs/security.md","crypto_published_status":"Met","crypto_published_justification":"The software uses bcrypt to store salted hashed iterated passwords, and https+standard crypto protocols to communicate with users.","crypto_call_status":"Met","crypto_call_justification":"Uses 'bcrypt' gem for bcrypt, and https implementation built into its web server.","crypto_floss_status":"Met","crypto_floss_justification":"All required functionality is implemented using FLOSS, including cryptography.","crypto_keylength_status":"N/A","crypto_keylength_justification":"Note: This application uses bcrypt, which uses 128-bit salt and produces 184 bits as a salted encrypted iterated hash.  This is less than 224 bits, but that's not really what the 224 bits of hash are for. ","crypto_working_status":"Met","crypto_working_justification":"The only cryptographic algorithm directly used by the program is bcrypt, which is not broken.","crypto_pfs_status":"N/A","crypto_pfs_justification":"Nothing in the code inhibits or prevents the use of PFS; that is a property of the website's web server.","crypto_password_storage_status":"Met","crypto_password_storage_justification":"Bcrypt used for storing local passwords.","crypto_random_status":"Met","crypto_random_justification":"The nonce for the salt is created by the bcrypt gem; its engine.rb file shows that it uses OpenSSL to get cryptographically random data for the salt (on Java it would use SecureRandom, which is still fine, but that is not the default configuration). Other nonces are part of the https implementation, which are implemented by the web server (not this application).","delivery_mitm_status":"Met","delivery_mitm_justification":"Uses https.","delivery_unsigned_status":"Met","delivery_unsigned_justification":"Does not make this mistake.","vulnerabilities_fixed_60_days_status":"Met","vulnerabilities_fixed_60_days_justification":"No such vulnerabilities at this time.","vulnerabilities_critical_fixed_status":"Met","vulnerabilities_critical_fixed_justification":"No such vulnerabilities at this time.","static_analysis_status":"Met","static_analysis_justification":"As noted in \u003chttps://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md\u003e, Brakeman, Rubocop, and rails_best_practices are used to analyze the Ruby code.  Brakeman is specifically designed to analyze Ruby on Rails code.  The Javascript client-side code is analyzed with ESLint, using over 100 rules.\r\n\r\nThese analysis tools are used as part of the default 'rake' process used in local development, as well as the \"pronto\" process run on the continuous integration server running on CircleCI.","static_analysis_common_vulnerabilities_status":"Met","static_analysis_common_vulnerabilities_justification":"Brakeman specifically looks for common vulnerabilities in Ruby on Rails applications.","static_analysis_fixed_status":"Met","static_analysis_fixed_justification":"This is vacuously true, since we've had no reports of vulnerabilities that apply to a deployed system.","static_analysis_often_status":"Met","static_analysis_often_justification":"All commits to GitHub are run through CircleCI, which performs a number of static analysis checks (Brakeman, Rubocop, etc.).","dynamic_analysis_status":"Met","dynamic_analysis_justification":"Analyzed with OWASP ZAP by Emily Ratliff","dynamic_analysis_unsafe_status":"N/A","dynamic_analysis_unsafe_justification":"Application written using Ruby and Javascript, not C/C++","dynamic_analysis_enable_assertions_status":"Unmet","dynamic_analysis_enable_assertions_justification":"Instead of embedding run-time assertions, there are many external tests with assertions that are checked during automated testing.","dynamic_analysis_fixed_status":"Met","dynamic_analysis_fixed_justification":"A few minor issues were found by OWASP ZAP during development; these have already been fixed.","general_comments":"We hope to see many other projects get their badge. Please start!\r\n\r\nNote that this badge entry is released under at least the Creative Commons Attribution version 3.0 or later license (CC-BY-3.0+).","created_at":"2015-10-23T22:02:10.544Z","updated_at":"2026-07-18T04:02:54.845Z","crypto_weaknesses_status":"Met","crypto_weaknesses_justification":"The only cryptography used directly by this application is bcrypt  (used for storing passwords as salted iterated hashes).  At the time of this writing, no serious breaks are known in bcrypt.  The application also depends on the web server's https configuration, but that is out of scope for this code.","test_continuous_integration_status":"Met","test_continuous_integration_justification":"Code is frequently integrated back into GitHub; CircleCI and several other tools are then run on the result to determine if there's a problem.  If a problem is found, the tools provide feedback via GitHub.  For more information, see the [BadgeApp's status on CircleCI](https://circleci.com/gh/ossf/best-practices-badge).","cpe":"","discussion_status":"Met","discussion_justification":"GitHub issue tracker and pull requests support discussion","no_leaked_credentials_status":"Met","no_leaked_credentials_justification":"No valid private credentials are leaked.  There is a [.env](https://github.com/ossf/best-practices-badge/blob/main/.env) file, but it only includes stub data for testing, not the live credentials.","english_status":"Met","english_justification":"All documentation is in English, and the project accepts bug reports and comments in English.","hardening_status":"Met","hardening_justification":"We use various HTTP headers for hardening, including a rigorous Content Security Policy (CSP) setting.  For more information, see [security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/security.md) which discusses the hardening mechanisms.","crypto_used_network_status":"Met","crypto_used_network_justification":"https://github.com/ossf/best-practices-badge","crypto_tls12_status":"Met","crypto_tls12_justification":"Github uses TLS 1.2, see \u003chttps://github.com/ossf/best-practices-badge\u003e.","crypto_certificate_verification_status":"Met","crypto_certificate_verification_justification":"The software does not directly implement TLS, instead, it depends on the webserver and Ruby libraries to implement TLS - including certificate checking.  That said, there *is* a case where TLS certificate verification is necessary.\r\n\r\nThe only case where TLS certificate verification matters is that this application uses OAuth for access delegation (in this case, we contact GitHub to determine if someone is the claimed GitHub user).  In this case it *does* need to verify the TLS certificate, because if anyone could pretend to be the access delagatee (e.g., GitHub) then they could claim anything.  The application does not do this directly, instead this is done by the gems (Ruby libraries) we call for this purpose, which perform this checking.\r\n\r\nOther than that, this application does not use TLS certificate verification.  That's because it implements a server-side application, not a client-side application, and uses name/password or GitHub authentication for user authentication (not TLS certificates).","crypto_verification_private_status":"Met","crypto_verification_private_justification":"The software does not directly implement TLS, instead, it depends on the webserver and Ruby libraries to implement TLS - including certificate checking.  That said, there *is* a case where TLS certificate verification is necessary, and this is supported (indirectly) by the systems it depends on.\r\n\r\nThe only case where TLS certificate verification matters is that this application uses OAuth for access delegation (in this case, we contact GitHub to determine if someone is the claimed GitHub user).  In this case it *does* need to verify the TLS certificate, because if anyone could pretend to be the access delagatee (e.g., GitHub) then they could claim anything.  The application does not do this directly, instead this is done by the gems (Ruby libraries) we call for this purpose, which perform this checking.\r\n\r\nOther than that, this application does not use TLS certificate verification.  That's because it implements a server-side application, not a client-side application, and uses name/password or GitHub authentication for user authentication (not TLS certificates).","hardened_site_status":"Met","hardened_site_justification":"We use GitHub, and [securityheaders.io verifies that our sites meet this criterion](https://securityheaders.io/?q=https%3A%2F%2Fgithub.com%2Fcoreinfrastructure%2Fbest-practices-badge\u0026followRedirects=on).","installation_common_status":"Met","installation_common_justification":"We include an install script, `install_badge_dev_env` which allows devs to quickly install the software for development.  This script uses calls to various package managers to install all necessary dependencies quickly and easily.  The uninstall process is documented in [docs/INSTALL.md](https://github.com/ossf/best-practices-badge/blob/main/docs/INSTALL.md).","build_reproducible_status":"N/A","build_reproducible_justification":"The code is written in Ruby and Javascript, which are not delivered as compiled executables.","badge_percentage_0":100,"achieved_passing_at":"2023-09-19T06:10:30.864Z","lost_passing_at":"2023-09-19T06:10:11.390Z","implementation_languages":"Ruby, JavaScript","badge_percentage_1":100,"dco_status":"Met","dco_justification":"We require a DCO for contributions, as documented in https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/CONTRIBUTING.md which says:\r\n\r\n\u003e All contributions (including pull requests) must agree to the [Developer Certificate of Origin (DCO) version 1.1](docs/dco.txt).\r\nThis is exactly the same one created and used by the Linux kernel developers and posted on \u003chttp://developercertificate.org/\u003e. This is a developer's certification that he or she has the right to submit the patch for inclusion into the project.\r\n","governance_status":"Met","governance_justification":"The governance mode of the Badge app is outlined in on our GitHub repository within [docs/governance.md](https://github.com/ossf/best-practices-badge/blob/main/docs/governance.md)","code_of_conduct_status":"Met","code_of_conduct_justification":"See [CODE_OF_CONDUCT](https://github.com/ossf/best-practices-badge/blob/master/CODE_OF_CONDUCT.md).","roles_responsibilities_status":"Met","roles_responsibilities_justification":"The document [docs/governance.md](https://github.com/ossf/best-practices-badge/blob/main/docs/governance.md) describes the key roles, which are basically \"technical lead\" and \"others with commit rights\".  It also identifies who has those roles.","access_continuity_status":"Met","access_continuity_justification":"This project is run by the Linux Foundation, a 501(c)6.  Multiple people are authorized to do all these activities (create and close issues, accept proposed changes, and release versions of software), including David A. Wheeler, Jason Dossett, Marcus Streets, Nicko van Someren, and Dan Kohn.  See [CREDITS])(https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/CREDITS.md). The Linux Foundation could authorize others, if needed.  Thus, the project can continue even if any one person is incapacitated or killed.","bus_factor_status":"Met","bus_factor_justification":"David A. Wheeler, Jason Dossett, and Dan Kohn are all very familiar with the software and could easily continue its maintenance if necessary.  Many other people have contributed per [CREDITS](https://github.com/ossf/best-practices-badge/blob/main/CREDITS.md) and several of them could also probably maintain it if absolutely necessary. See [GitHub contributors statistics](https://github.com/ossf/best-practices-badge/graphs/contributors) for the latest statistics on contributors.","documentation_roadmap_status":"Met","documentation_roadmap_justification":"The [project roadmap](https://github.com/ossf/best-practices-badge/blob/main/docs/roadmap.md) explains these things.  Note that the project is in sustainment, so we're focusing more on continuous smaller improvements instead of massive changes.","documentation_architecture_status":"Met","documentation_architecture_justification":"The design is documented in [docs/implementation.md](https://github.com/ossf/best-practices-badge/blob/master/docs/implementation.md)","documentation_security_status":"Met","documentation_security_justification":"The security requirements and assurance case are documented in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md).","documentation_quick_start_status":"Met","documentation_quick_start_justification":"The [docs/INSTALL.md](https://github.com/ossf/best-practices-badge/blob/main/docs/INSTALL.md) installation manual also includes \"quick start\" information to help someone get started.  In particular, it describes how to start up the program, access it via a web browser, become an administrator, and access its internal state to perform a few tasks.","documentation_current_status":"Met","documentation_current_justification":"We routinely update the documentation when a new capability is added.\r\n\r\nFor example, when the software was modified on 2017-05-27 to support a separate runtime configuration environment variable to set the database pool size (originally commit 8eef5e77ec5b08bc6714e2aa5a6139e71e55ff2b), by the next day (2017-05-28) in commit 1a8bcb5c5b40751ca874bd0b550f25a6aa8d7ea5 the documentation was modified to record it.","documentation_achievements_status":"Met","documentation_achievements_justification":"We record on our [homepage](https://github.com/ossf/best-practices-badge) that we have a CII best practices badge, good code coverage, and that we use CircleCI as our continuous integration (CI) system.","accessibility_best_practices_status":"Met","accessibility_best_practices_justification":"We generally follow accessibility best practices, e.g., we provide ALT values for images where relevant.\r\n\r\nWe use this website to find accessibility problems:\r\nhttps://achecker.ca/checker/index.php\r\nWe've checked the following paths (these are key forms in the system): \"/\", \"/signup\", \"/login\", \"/projects\", and \"/projects/1\".  There are no known problems and no likely problems.","internationalization_status":"Met","internationalization_justification":"The software is internationalized using standard [Ruby on Rails mechanisms](http://guides.rubyonrails.org/i18n.html).  This data is then sent on to the JavaScript code where appropriate.  We use translation.io to manage the translations.\r\n","sites_password_security_status":"Met","sites_password_security_justification":"We use [GitHub, who meet this criterion](https://help.github.com/articles/github-security/).","maintenance_or_update_status":"Met","maintenance_or_update_justification":"Normally only a single version of the product is in production use.  That said, it's important to handle upgrades, especially so that various developers can upgrade.  How to upgrade is documented in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md).\r\n\r\nHere is a summary of common cases:\r\n* Upgrading often involves a database migration, which is handled by running \"rake db:migration\" (if the user forgets to do this, it is detected, running stops, and this information is presented).\r\n* Other upgrades generally involve installing updated gems (libraries), which are handled with \"bundle update\".\r\n* In rare cases an update to the Ruby language is needed; the steps to do this are also in [CONTRIBUTING.md](https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/CONTRIBUTING.md).","vulnerability_report_credit_status":"N/A","vulnerability_report_credit_justification":"We've never had an external bug reporter.\r\n\r\n[CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) notes that:\r\n\r\n\u003e We will gladly give credit to anyone who reports a vulnerability so that we can fix it. If you want to remain anonymous or pseudonymous instead,  please let us know that; we will gladly respect your wishes.\r\n\r\nThis is emphasized in the vulnerability report handling process [docs/security.md](https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/docs/implementation.md), where the last step is giving credit.","vulnerability_response_process_status":"Met","vulnerability_response_process_justification":"The vulnerability report handling process is documented in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md).","coding_standards_status":"Met","coding_standards_justification":"[CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) documents our coding style guides.\r\n\r\nAs documented there:\r\n* For Ruby on Rails, we generally follow the [community Ruby style guide](https://github.com/bbatsov/ruby-style-guide) and the complementary [community Rails style guide](https://github.com/bbatsov/rails-style-guide).\r\n* For JavaScript, our coding style is based on the [Node.js style guide](https://github.com/felixge/node-style-guide).","coding_standards_enforced_status":"Met","coding_standards_enforced_justification":"[CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) documents our coding style enforcement mechanisms.\r\n\r\nAs documented there:\r\n* For Ruby on Rails, we use rubocop and rails_best_practices for style enforcement (as well as Brakeman to find vulnerabilities)\r\n* For JavaScript, we ESLint.","build_standard_variables_status":"N/A","build_standard_variables_justification":"The application does not create native binaries.  (Some of the libraries it depends on do, but those are external.)","build_preserve_debug_status":"N/A","build_preserve_debug_justification":"The application does not create native binaries.  (Some of the libraries it depends on do, but those are external.)","build_non_recursive_status":"N/A","build_non_recursive_justification":"The application does not create native binaries.  (Some of the libraries it depends on do, but those are external.)","build_repeatable_status":"N/A","build_repeatable_justification":"The application does not create native binaries.  (Some of the libraries it depends on do, but those are external.)  It is written in scripting languages where the source code is used directly.","installation_standard_variables_status":"N/A","installation_standard_variables_justification":"There is no installation system for build artifacts, as it's written using scripts.\r\n\r\nIt could be said that Rails builds web application assets (e.g., minified and concatenated JavaScript, and combined CSS); under that interpretation, they are written by the Rails framework as part of the execution of the Rails asset pipeline, and this is controlled in the usual way by controlling the framework.","installation_development_quick_status":"Met","installation_development_quick_justification":"The software is installed using standard conventions for this kind of software.  The underlying Ruby libraries are installed using bundler (the usual Ruby package manager).  Lower-level system components are normally installed using the system package manager.\r\n\r\nIt's possible to install these quickly, using a provided installation shell script that determines which system package manager to use \u0026 tries to automatically install whatever is needed, including the tests and test environment.  The instructions for quickly installing everything is in [INSTALL.md](https://github.com/ossf/best-practices-badge/blob/main/docs/INSTALL.md).","external_dependencies_status":"Met","external_dependencies_justification":"External dependencies are stored in a [Gemfile](https://github.com/ossf/best-practices-badge/blob/main/Gemfile).","dependency_monitoring_status":"Met","dependency_monitoring_justification":"External dependency checking is performed in two ways:\r\n\r\n* bundle_audit.  This checks all gems for known vulnerabilities.  This is run on every execution of the \"rake\" local check task and on every run of the continuous integration task on CircleCI.\r\n* GitHub (built-in dependency scanner).  This also checks gems for known vulnerabilities, and puts the current status on a badge that is displayed on the front page of the project home page.\r\n\r\nFor the few external dependencies that aren't managed as gems (e.g., PostgreSQL) the system package managers and/or the deployment system's managers are used to maintain them \u0026 periodically check them.","updateable_reused_components_status":"Met","updateable_reused_components_justification":"The project uses bundler, the standard package management solution for Ruby, for most externally-maintained components.  For the rest (e.g., PostgreSQL) it uses the system package manager.","interfaces_current_status":"Met","interfaces_current_justification":"We avoid depending on deprecated/obsolete functions.","automated_integration_testing_status":"Met","automated_integration_testing_justification":"We use [CircleCI](https://circleci.com/gh/ossf/best-practices-badge) to automatically test every check in to any branch in our repository.  I some circumstances experimental branches which do not yet run even in a development environment may be ignored via a custom entry in our circle.yml file.  The master, staging, and production  branches are always tested.","regression_tests_added50_status":"Met","regression_tests_added50_justification":"When regressions occur, we add tests for them.","test_statement_coverage80_status":"Met","test_statement_coverage80_justification":"As of this writing, we have 100% statement coverage, see [Codecov.io](https://codecov.io/gh/ossf/best-practices-badge).","test_policy_mandated_status":"Met","test_policy_mandated_justification":"Yes, this is a documented policy in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) which says:\r\n\r\n\u003e When adding or changing functionality, please include new tests for them as part of your contribution.","implement_secure_design_status":"Met","implement_secure_design_justification":"They are implemented, as described in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/security.md).\r\n","input_validation_status":"Met","input_validation_justification":"All inputs from potentially untrusted sources are checked \u0026 rejected if they are invalid.  Some, such as justifications, only have a few limitations (must be UTF-8 and have a limited length). For more information, see [security.md](https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/docs/security.md).","crypto_algorithm_agility_status":"N/A","crypto_algorithm_agility_justification":"This implements a web application, and the (external) web server determines what cryptographic algorithms are in use by the user.  If the web server supports multiple cryptographic algorithms (and it usually would), then the application does.  The functionality that calls out to other systems (e.g., OAUTH for GitHub, and data access for the detectives) are also external (and they support multiple algorithms anyway).","crypto_credential_agility_status":"Met","crypto_credential_agility_justification":"All authentication credentials can be provided via environment variables when run in production, so no useful key is stored in the source code.","signed_releases_status":"N/A","signed_releases_justification":"Releases are not intended for widespread use in many different sites, so this is N/A.\r\n","version_tags_signed_status":"Unmet","version_tags_signed_justification":"In production the software is run in a single site, so the need for signed versions is less.","badge_percentage_2":100,"contributors_unassociated_status":"Met","contributors_unassociated_justification":"There are [at least 22 contributors](https://github.com/ossf/best-practices-badge/graphs/contributors), and at least three significant contributors today: David A. Wheeler (IDA), Jason Dossett (IDA), and Dan Kohn (Linux Foundation).  For this work, IDA works for the Core Infrastructure Initiative (CII), which is a project of the Linux Foundation (LF). However, the LF is itself a [nonprofit mutual benefit corporation (specifically a Section 501(c)(6))](https://www.linuxfoundation.org/bylaws/).  As a nonprofit mutual benefit corporation, the LF is directed by other organizations which actually provide funding to do this work, and thus the LF and CII can be viewed as \"pass through\" organizations as described in this criterion.\r\n","copyright_per_file_status":"Met","copyright_per_file_justification":"Each source file has a copyright statement in its header.  See [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) for the instructions for Ruby (nearly all source files are in Ruby).","license_per_file_status":"Met","license_per_file_justification":"Each source file has a copyright statement in its header (MIT).  See [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) for the instructions for Ruby source files (nearly all source files are in Ruby).","small_tasks_status":"Met","small_tasks_justification":"We use the \"up-for-grabs\" tag.  This is noted on the [front page of the repo](https://github.com/coreinfrastructure/best-practices-badge).","require_2FA_status":"Met","require_2FA_justification":"The Core Infrastructure Initiative (CII) requires two-factor authentication for all organization members and outside collaborators as described in [Requiring two-factor authentication in your organization](https://help.github.com/articles/requiring-two-factor-authentication-in-your-organization/).","secure_2FA_status":"Met","secure_2FA_justification":"Project governance specifically documents that SMS is not acceptable; see [governance.md](https://github.com/ossf/best-practices-badge/blob/main/docs/governance.md).","code_review_standards_status":"Met","code_review_standards_justification":"The file [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) describes the code review requirements.  E.G., changes to the code built on Rails must follow the [Rails community style guide](https://github.com/bbatsov/rails-style-guide).  The continuous integration tasks run a large number of checks, e.g., all Ruby code must go through Rubocop, and all JavaScript code must go through ESLint (with the given conditions).  We absolutely require that the Ruby code have at least 90% statement coverage, but we typically don't accept statement coverage less than 100%.","two_person_review_status":"Met","two_person_review_justification":"We have a policy in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) that modifications other than low-risk modifications be reviewed by someone else, and a stated goal of having at least 50% of all proposed modifications to be reviewed.","test_statement_coverage90_status":"Met","test_statement_coverage90_justification":"As of this writing, we have 100% statement coverage, see [Codecov.io](https://codecov.io/gh/ossf/best-practices-badge).","test_branch_coverage80_status":"N/A","test_branch_coverage80_justification":"There are no top-to-bottom FLOSS tools available in Ruby which can measure branch coverage.   Ruby version 2.5 was the first version that enabled capturing branch coverage, and it was only released on 2017-12-25.  Other tools on top of Ruby need to be modified so that they can use this information, e.g., [simplecov issue 412](https://github.com/colszowka/simplecov/issues/412) proposed adding branch coverage support to simplecov.","security_review_status":"Met","security_review_justification":"We have performed a self-assessment of our security, and it is documented in [security.md](https://github.com/ossf/best-practices-badge/blob/main/doc/security.md).  This considered the security requirements and security boundary, and examined the high-level architecture.  We used static \u0026 dynamic tools, as well as human review (especially of the major design components).  This was *not* an independent evaluation, but the criterion doesn't require that.","assurance_case_status":"Met","assurance_case_justification":"The security requirements and assurance case are documented in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md).","achieve_passing_status":"Met","achieve_silver_status":"Met","tiered_percentage":300,"repo_url_updated_at":"2026-07-18T03:38:32.274Z","achieved_silver_at":"2023-09-19T06:10:30.864Z","lost_silver_at":"2023-09-19T06:10:11.390Z","achieved_gold_at":"2023-09-19T06:10:30.864Z","lost_gold_at":"2023-09-19T06:10:11.390Z","first_achieved_passing_at":"2016-01-12T22:55:00.000Z","first_achieved_silver_at":"2023-09-07T18:29:54.722Z","first_achieved_gold_at":"2023-09-07T18:29:54.722Z","maintained_status":"Met","OSPS-AC-01.01_status":"Met","OSPS-AC-01.01_justification":"The authoritative repository is hosted on GitHub, which requires multi-factor authentication to modify sensitive resources or to read sensitive resources like keys. GitHub allows anyone to read publicly available resources (such as the source code), and that's fine.","OSPS-AC-02.01_status":"Met","OSPS-AC-02.01_justification":"New collaborators are only given lowest available privileges. We generally don't add many collaborators who can directly edit the software, but instead ask people to fork the repository and create pull requests from them, which gives them *no* privileges by default.","OSPS-AC-03.01_status":"Met","OSPS-AC-03.01_justification":"Our main branch is protected (it's named `main`).","OSPS-AC-03.02_status":"Met","OSPS-AC-03.02_justification":"GitHub requires this.","OSPS-BR-01.01_status":"Met","OSPS-BR-01.01_justification":"Other the branch name we don't use input parameters. See below in OSPS-BR-01.02 for branch names.","OSPS-BR-01.02_status":3,"OSPS-BR-01.02_justification":"Branch names are checked before they are used *if* they are used. Note that the scorecard workflow doesn't use the branch name, so it doesn't check it easier (we can't add that check because the scorecard workflow is only allowed to do certain things).","OSPS-BR-03.01_status":"Met","OSPS-BR-03.01_justification":"https: is always used.","OSPS-BR-03.02_status":"Met","OSPS-BR-03.02_justification":"https: is always used.","OSPS-BR-07.01_status":"Met","OSPS-BR-07.01_justification":"We enable secret scanning to prevent this.","OSPS-DO-01.01_status":"N/A","OSPS-DO-01.01_justification":"The project doesn't create \"releases\" for many to download and install. Its primary purpose is to be a specific website's implementation. Therefore, it must be completely usable without any \"user guides\" for end users (who spend relatively little time on the site). We do have guides for setting up and running the site, primarily to enable others to install it so they can add features to it as proposals.","OSPS-DO-02.01_status":"Met","OSPS-DO-02.01_justification":"See SECURITY.md for how to report defects.","OSPS-GV-02.01_status":"Met","OSPS-GV-02.01_justification":"GitHub provides issues and pull requests. We also use a mailing list.","OSPS-GV-03.01_status":"Met","OSPS-GV-03.01_justification":"See CONTRIBUTING.md.","OSPS-LE-02.01_status":"Met","OSPS-LE-02.01_justification":"We use the MIT license, which meets the OSI Open Source Definition and the Free Software Definition.","OSPS-LE-02.02_status":"Met","OSPS-LE-02.02_justification":"We use the MIT license, which meets the OSI Open Source Definition and the Free Software Definition.","OSPS-LE-03.01_status":"Met","OSPS-LE-03.01_justification":"See file LICENSE for the source code.","OSPS-LE-03.02_status":"Met","OSPS-LE-03.02_justification":"See file LICENSE for the source code.","OSPS-QA-01.01_status":"Met","OSPS-QA-01.02_status":"Met","OSPS-QA-02.01_status":"Met","OSPS-QA-04.01_status":"Met","OSPS-QA-05.01_status":"Met","OSPS-QA-05.02_status":"Met","OSPS-VM-02.01_status":"Met","OSPS-AC-04.01_status":"Met","OSPS-AC-04.01_justification":"All CI/CD except 1 have no special privileges, and thus can't do anything special.\r\n\r\nThe CircleCI \"deploy\" task *does* have a special permission: the secret key for deployment. This is only run after all verification steps pass, and only on the \"staging\" and \"production\" branches, which are protected branches that *cannot* be pushed to normally (changing their contents requires extra privileges).","OSPS-BR-02.01_status":"Met","OSPS-BR-02.01_justification":"The primary single user uses git commit records to identify releases. [version_unique]","OSPS-BR-04.01_status":"Met","OSPS-BR-04.01_justification":"CHANGELOG file is in top directory, see: https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/CHANGELOG.md [release_notes]","OSPS-BR-05.01_status":"Met","OSPS-BR-05.01_justification":"External dependencies are stored in a [Gemfile](https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/Gemfile). [external_dependencies]","OSPS-BR-06.01_status":"N/A","OSPS-BR-06.01_justification":"Releases are not intended for widespread use in many different sites, so this is N/A. [signed_releases]","OSPS-DO-06.01_status":"Met","OSPS-DO-06.01_justification":"Our key documentation is in CONTRIBUTING.md. Selection is discussed in the [reuse (supply chain)[https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md#reuse-supply-chain) section. As documented there, we use package managers to obtain and track dependencies. We also use bundle-audit and dependabot to alert us to vulnerabilities in dependencies.","OSPS-GV-01.01_status":"Met","OSPS-GV-01.01_justification":"See docs/TSC.md","OSPS-GV-01.02_status":"Met","OSPS-GV-01.02_justification":"The document [docs/governance.md](https://github.com/ossf/best-practices-badge/blob/main/docs/governance.md) describes the key roles, which are basically \"technical lead\" and \"others with commit rights\".  It also identifies who has those roles. [roles_responsibilities]","OSPS-GV-03.02_status":"Met","OSPS-GV-03.02_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md [contribution_requirements]","OSPS-LE-01.01_status":"Met","OSPS-LE-01.01_justification":"We require a DCO for contributions, as documented in https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md which says:\r\n\r\n\u003e All contributions (including pull requests) must agree to the [Developer Certificate of Origin (DCO) version 1.1](docs/dco.txt).\r\nThis is exactly the same one created and used by the Linux kernel developers and posted on \u003chttp://developercertificate.org/\u003e. This is a developer's certification that he or she has the right to submit the patch for inclusion into the project. [dco]","OSPS-QA-03.01_status":"Met","OSPS-QA-03.01_justification":"We use [CircleCI](https://circleci.com/gh/ossf/best-practices-badge) to automatically test every check in to any branch in our repository.  I some circumstances experimental branches which do not yet run even in a development environment may be ignored via a custom entry in our circle.yml file.  The master, staging, and production  branches are always tested. [automated_integration_testing]","OSPS-QA-06.01_status":"Met","OSPS-QA-06.01_justification":"We use [CircleCI](https://circleci.com/gh/ossf/best-practices-badge) to automatically test every check in to any branch in our repository.  I some circumstances experimental branches which do not yet run even in a development environment may be ignored via a custom entry in our circle.yml file.  The master, staging, and production  branches are always tested. [automated_integration_testing]","OSPS-SA-01.01_status":"Met","OSPS-SA-01.01_justification":"The design is documented in [docs/implementation.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md) [documentation_architecture]","OSPS-SA-02.01_status":"Met","OSPS-SA-02.01_justification":"Its interface is defined here: https://github.com/ossf/best-practices-badge/blob/main/doc/implementation.md#interface [documentation_interface]","OSPS-SA-03.01_status":"Met","OSPS-SA-03.01_justification":"The security requirements and assurance case are documented in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md). [assurance_case]","OSPS-VM-01.01_status":"Met","OSPS-VM-01.01_justification":"https://github.com/ossf/best-practices-badge/issues [vulnerability_report_process]","OSPS-VM-03.01_status":"Met","OSPS-VM-03.01_justification":"https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md [vulnerability_report_private]","OSPS-VM-04.01_status":"Met","OSPS-VM-04.01_justification":"We intend to do that, though we don't know of any for-certain publicly known vulnerabilities.\r\n\r\nOur release notes do document that commit fdb83380 on 2015-11-26 updated gem nokogiri from 1.6.6.2 to 1.6.6.4 due to CVE-2015-1819.  It's not clear if our application was actually vulnerable; it was easier to simply upgrade.  In any case, we upgraded immediately, and this is documented in our release notes. [release_notes_vulns]","OSPS-AC-04.02_status":"Met","OSPS-AC-04.02_justification":"The only job assigned special permissions is the special deployment task. All others only have the privileges necessary to download the code, install tools locally in that container, and run the tools to determine and report analysis results.","OSPS-BR-02.02_status":"Met","OSPS-BR-02.02_justification":"The primary single user uses git commit records to identify releases. [version_unique]","OSPS-BR-07.02_status":"Met","OSPS-BR-07.02_justification":"See docs/secrets-policy.md for the policy and processes for managing secret/credentials, including rotating them.","OSPS-DO-03.01_status":"N/A","OSPS-DO-03.01_justification":"Releases are not intended for widespread use in many different sites, so this is N/A. [signed_releases]","OSPS-DO-03.02_status":"N/A","OSPS-DO-03.02_justification":"Releases are not intended for widespread use in many different sites, so this is N/A. [signed_releases]","OSPS-DO-04.01_status":"N/A","OSPS-DO-04.01_justification":"Our releases are intended for use in a single website that we maintain, and the support ends when we update the production branch.","OSPS-DO-05.01_status":"N/A","OSPS-DO-05.01_justification":"As the intended use is a single website, we simply stop updating all previous versions, and only support the current version.","OSPS-GV-04.01_status":"Met","OSPS-GV-04.01_justification":"See docs/governance.md especially our \"Escalated permissions policy\". This updated policy was approved by the Best Practices Badge TSC in 2026.","OSPS-QA-02.02_status":"Met","OSPS-QA-02.02_justification":"See `docs/sbom.md`. Every time we push to the `staging` or `production` branch, as part of the build process we generate an SPDX SBOM and record it. We provide a script `scripts/get-sbom` to make it easy to acquire the SBOM information given a commit ID. Commits to `production` are the closest thing we have to a \"release\". We also document the REST API for retrieving a SPDX SBOM of the *current* main branch, though that isn't really a release.","OSPS-QA-04.02_status":"N/A","OSPS-QA-04.02_justification":"We don't use multiple source code repositories for the project.","OSPS-QA-06.02_status":"Met","OSPS-QA-06.02_justification":"Yes, it includes a test suite based on minitest (the test framework that comes with Rails). [test]","OSPS-QA-06.03_status":"Met","OSPS-QA-06.03_justification":"Yes, this is a documented policy in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) which says:\r\n\r\n\u003e When adding or changing functionality, please include new tests for them as part of your contribution. [test_policy_mandated]","OSPS-QA-07.01_status":"Met","OSPS-QA-07.01_justification":"We have a policy in [CONTRIBUTING.md](https://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md) that modifications other than low-risk modifications be reviewed by someone else, and a stated goal of having at least 50% of all proposed modifications to be reviewed. [two_person_review]","OSPS-SA-03.02_status":"Met","OSPS-SA-03.02_justification":"The security requirements and assurance case are documented in [docs/security.md](https://github.com/ossf/best-practices-badge/blob/main/docs/implementation.md). [assurance_case]","OSPS-VM-04.02_status":"N/A","OSPS-VM-04.02_justification":"We don't have any known vulnerabilities in components we use. When a dependency has a vulnerability, we generally simply update it to a not-vulnerable version, even if we believe it won't affect us, because that's a stronger defense than a possibly-flawed analysis.","OSPS-VM-05.01_status":"Met","OSPS-VM-05.01_justification":"External dependency checking is performed in two ways:\r\n\r\n* bundle_audit.  This checks all gems for known vulnerabilities.  This is run on every execution of the \"rake\" local check task and on every run of the continuous integration task on CircleCI.\r\n* [Gemnasium](https://gemnasium.com/linuxfoundation/cii-best-practices-badge).  This also checks gems for known vulnerabilities, and puts the current status on a badge that is displayed on the front page of the project home page.\r\n\r\nFor the few external dependencies that aren't managed as gems (e.g., PostgreSQL) the system package managers and/or the deployment system's managers are used to maintain them \u0026 periodically check them. [dependency_monitoring]","OSPS-VM-05.02_status":"Met","OSPS-VM-05.02_justification":"External dependency checking is performed in two ways:\r\n\r\n* bundle_audit.  This checks all gems for known vulnerabilities.  This is run on every execution of the \"rake\" local check task and on every run of the continuous integration task on CircleCI.\r\n* [Gemnasium](https://gemnasium.com/linuxfoundation/cii-best-practices-badge).  This also checks gems for known vulnerabilities, and puts the current status on a badge that is displayed on the front page of the project home page.\r\n\r\nFor the few external dependencies that aren't managed as gems (e.g., PostgreSQL) the system package managers and/or the deployment system's managers are used to maintain them \u0026 periodically check them. [dependency_monitoring]","OSPS-VM-05.03_status":"Met","OSPS-VM-05.03_justification":"External dependency checking is performed in two ways:\r\n\r\n* bundle_audit.  This checks all gems for known vulnerabilities.  This is run on every execution of the \"rake\" local check task and on every run of the continuous integration task on CircleCI.\r\n* [Gemnasium](https://gemnasium.com/linuxfoundation/cii-best-practices-badge).  This also checks gems for known vulnerabilities, and puts the current status on a badge that is displayed on the front page of the project home page.\r\n\r\nFor the few external dependencies that aren't managed as gems (e.g., PostgreSQL) the system package managers and/or the deployment system's managers are used to maintain them \u0026 periodically check them. [dependency_monitoring]","OSPS-VM-06.01_status":"Met","OSPS-VM-06.01_justification":"This is vacuously true, since we've had no reports of vulnerabilities that apply to a deployed system. [static_analysis_fixed]","OSPS-VM-06.02_status":"Met","OSPS-VM-06.02_justification":"As noted in \u003chttps://github.com/ossf/best-practices-badge/blob/main/CONTRIBUTING.md\u003e, Brakeman, Rubocop, and rails_best_practices are used to analyze the Ruby code.  Brakeman is specifically designed to analyze Ruby on Rails code.  The Javascript client-side code is analyzed with ESLint, using over 100 rules.\r\n\r\nThese analysis tools are used as part of the default 'rake' process used in local development, as well as the \"pronto\" process run on the continuous integration server running on CircleCI. [static_analysis]","badge_percentage_baseline_1":100,"badge_percentage_baseline_2":100,"badge_percentage_baseline_3":100,"achieved_baseline_1_at":"2025-12-27T00:39:14.103Z","achieved_baseline_2_at":"2026-04-01T21:28:30.835Z","achieved_baseline_3_at":"2026-04-03T22:31:58.389Z","lost_baseline_1_at":null,"lost_baseline_2_at":null,"lost_baseline_3_at":null,"first_achieved_baseline_1_at":"2025-12-27T00:39:14.103Z","first_achieved_baseline_2_at":"2026-04-01T21:28:30.835Z","first_achieved_baseline_3_at":"2026-04-03T22:31:58.389Z","baseline_tiered_percentage":300,"entry_locale":"en","OSPS-BR-01.03_status":"Met","OSPS-BR-01.03_justification":"Unreviewed code (PRs) runs in the low-privilege pull_request context with no secrets and read-only tokens; the workflows that hold write credentials at *all* only run on code that has already been reviewed and merged:\r\n\r\n1. pull_request (not pull_request_target) is used for untrusted code. The two workflows that trigger on pull requests (main.yml and codespell.yml) both\r\n  use the pull_request event trigger. GitHub Actions automatically denies access\r\n   to repository secrets and grants only a read-only, ephemeral GITHUB_TOKEN to\r\n  workflows triggered this way from forks. No secrets can leak to an external\r\n  contributor's PR. Neither workflow uses pull_request_target, which is the\r\n  primary vector by which CI/CD systems accidentally expose privileged\r\n  credentials to unreviewed code.\r\n2. Minimal declared permissions on PR-triggered workflows. Both main.yml and\r\n  codespell.yml declare permissions: contents: read at the top level, so even   \r\n  the ephemeral GITHUB_TOKEN is scoped to the minimum needed. Because GitHub's\r\n  permissions: key defaults anything not listed to none, there are no implicit  \r\n  write permissions available.\r\n3. Privileged workflows never trigger on pull requests. The only workflow with\r\n   elevated permissions (sbom.yml, which requires contents: write to create     \r\n  GitHub Releases) is gated exclusively on push to the staging or production\r\n   branches that only receive reviewed, merged code. It never runs on \r\n  a PR. Similarly, scorecard.yml only triggers on push to main, a scheduled\r\n  cron, and branch_protection_rule events.\r\n4. persist-credentials: false on privileged checkouts. The sbom.yml workflow\r\n  additionally sets persist-credentials: false on actions/checkout, ensuring git\r\n   credentials are not stored in the workspace even after checkout, limiting\r\n  lateral movement if a downstream step were compromised.","OSPS-DO-07.01_status":"Met","OSPS-DO-07.01_justification":"The software is installed using standard conventions for this kind of software.  The underlying Ruby libraries are installed using bundler (the usual Ruby package manager).  Lower-level system components are normally installed using the system package manager.\r\n\r\nIt's possible to install these quickly, using a provided installation shell script that determines which system package manager to use \u0026 tries to automatically install whatever is needed, including the tests and test environment.  The instructions for quickly installing everything is in [INSTALL.md](https://github.com/linuxfoundation/cii-best-practices-badge/blob/master/docs/INSTALL.md). [installation_development_quick]","OSPS-BR-01.04_status":"Met","OSPS-BR-01.04_justification":"None of the three CI/CD workflows (.github/workflows/main.yml, codespell.yml, scorecard.yml) define any workflow_dispatch inputs or other explicit collaborator-triggered input parameters. All workflows trigger only on automated events (push, pull_request, schedule, branch_protection_rule).\r\n\r\nSince there are no manual workflow inputs to sanitize, the criterion is vacuously satisfied — there is no attack surface of this type to protect.\r\n\r\nSupporting evidence:\r\n\r\n - grep for workflow_dispatch across all workflow files returns zero  matches.\r\n - The existing input validation (OSPS-BR-01.02's  script/validate_branch_name) handles environment-provided values like GITHUB_REF_NAME, which is a different concern (automated trigger context, not collaborator-supplied input).\r\n\r\nConclusion: The project meets OSPS-BR-01.04 because it has no pipelines that\r\naccept trusted-collaborator input (no workflow_dispatch with inputs, no\r\nmanual triggers with parameters). If such inputs are added in the future,\r\nthey would need to be validated before use.","badge_level":"gold","additional_rights":[],"project_entry_attribution":"Please credit David A. Wheeler and the CII Best Practices badge contributors.","project_entry_license":"CC-BY-3.0+"}