I'd like to propose to evaluate and (selectively) adopt secure software development best practices recommended by the Open Source Security Foundation (OpenSSF) [1]. The OpenSSF Scorecard project checks various development best practices of open source projects hosted on GitHub and provides guidance on how to improve those practices [2]. The overall goal of this issue is to strengthen the (supply chain) security posture of the ered project.
Below are the results as of today. I would recommend looking into
the branch protection settings
pinning the versions of GitHub actions
enabling dependabot (at least for the GitHub actions)
{
"date": "2024-03-20T23:07:30+01:00",
"repo": {
"name": "github.com/Ericsson/ered",
"commit": "fd716d22cf10912ff140e46f7a2aca413c80066f"
},
"scorecard": {
"version": "(devel)",
"commit": "unknown"
},
"score": 4.2,
"checks": [
{
"details": null,
"score": 10,
"reason": "no binaries found in the repo",
"name": "Binary-Artifacts",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#binary-artifacts",
"short": "Determines if the project has generated executable (binary) artifacts in the source repository."
}
},
{
"details": [
"Warn: 'force pushes' enabled on branch 'main'",
"Info: 'allow deletion' disabled on branch 'main'",
"Warn: status checks do not require up-to-date branches for 'main'",
"Warn: 'last push approval' disabled on branch 'main'",
"Info: PRs are required in order to make changes on branch 'main'",
"Warn: no status checks found to merge onto branch 'main'",
"Warn: number of required reviewers is 0 on branch 'main', while the ideal suggested is 2",
"Warn: stale review dismissal disabled on branch 'main'",
"Warn: settings do not apply to administrators on branch 'main'",
"Warn: codeowner review is not required on branch 'main'"
],
"score": 1,
"reason": "branch protection is not maximal on development and all release branches",
"name": "Branch-Protection",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection",
"short": "Determines if the default and release branches are protected with GitHub's branch protection settings."
}
},
{
"details": null,
"score": 9,
"reason": "21 out of 23 merged PRs checked by a CI test -- score normalized to 9",
"name": "CI-Tests",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#ci-tests",
"short": "Determines if the project runs tests before pull requests are merged."
}
},
{
"details": null,
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"name": "CII-Best-Practices",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#cii-best-practices",
"short": "Determines if the project has an OpenSSF (formerly CII) Best Practices Badge."
}
},
{
"details": null,
"score": 7,
"reason": "found 7 unreviewed changesets out of 26 -- score normalized to 7",
"name": "Code-Review",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#code-review",
"short": "Determines if the project requires human code review before pull requests (aka merge requests) are merged."
}
},
{
"details": [
"Info: mysql-otp contributor org/company found, ericsson software technology contributor org/company found, ericsson contributor org/company found, "
],
"score": 10,
"reason": "project has 3 contributing companies or organizations -- score normalized to 10",
"name": "Contributors",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#contributors",
"short": "Determines if the project has a set of contributors from multiple organizations (e.g., companies)."
}
},
{
"details": null,
"score": 10,
"reason": "no dangerous workflow patterns detected",
"name": "Dangerous-Workflow",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#dangerous-workflow",
"short": "Determines if the project's GitHub Action workflows avoid dangerous patterns."
}
},
{
"details": [
"Warn: tool 'RenovateBot' is not used",
"Warn: tool 'Dependabot' is not used",
"Warn: tool 'PyUp' is not used"
],
"score": 0,
"reason": "no update tool detected",
"name": "Dependency-Update-Tool",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool",
"short": "Determines if the project uses a dependency update tool."
}
},
{
"details": [
"Warn: no OSSFuzz integration found",
"Warn: no GoBuiltInFuzzer integration found",
"Warn: no PythonAtherisFuzzer integration found",
"Warn: no CLibFuzzer integration found",
"Warn: no CppLibFuzzer integration found",
"Warn: no SwiftLibFuzzer integration found",
"Warn: no RustCargoFuzzer integration found",
"Warn: no JavaJazzerFuzzer integration found",
"Warn: no ClusterFuzzLite integration found",
"Warn: no HaskellPropertyBasedTesting integration found",
"Warn: no TypeScriptPropertyBasedTesting integration found",
"Warn: no JavaScriptPropertyBasedTesting integration found"
],
"score": 0,
"reason": "project is not fuzzed",
"name": "Fuzzing",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#fuzzing",
"short": "Determines if the project uses fuzzing."
}
},
{
"details": [
"Info: FSF or OSI recognized license: LICENSE:1",
"Info: License file found in expected location: LICENSE:1"
],
"score": 10,
"reason": "license file detected",
"name": "License",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#license",
"short": "Determines if the project has defined a license."
}
},
{
"details": null,
"score": 1,
"reason": "2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1",
"name": "Maintained",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained",
"short": "Determines if the project is \"actively maintained\"."
}
},
{
"details": [
"Warn: no GitHub/GitLab publishing workflow detected."
],
"score": -1,
"reason": "packaging workflow not detected",
"name": "Packaging",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#packaging",
"short": "Determines if the project is published as a package that others can easily download, install, easily update, and uninstall."
}
},
{
"details": [
"Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:13",
"Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:38",
"Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/redis-compatibility.yml:16",
"Warn: third-party GitHubAction not pinned by hash: .github/workflows/redis-compatibility.yml:18",
"Info: 0 out of 3 GitHub-owned GitHubAction dependencies pinned",
"Info: 0 out of 1 third-party GitHubAction dependencies pinned"
],
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"name": "Pinned-Dependencies",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies",
"short": "Determines if the project has declared and pinned the dependencies of its build process."
}
},
{
"details": [
"Warn: 0 commits out of 27 are checked with a SAST tool"
],
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"name": "SAST",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#sast",
"short": "Determines if the project uses static code analysis."
}
},
{
"details": [
"Warn: no security policy file detected",
"Warn: no security file to analyze",
"Warn: no security file to analyze",
"Warn: no security file to analyze"
],
"score": 0,
"reason": "security policy file not detected",
"name": "Security-Policy",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#security-policy",
"short": "Determines if the project has published a security policy."
}
},
{
"details": null,
"score": -1,
"reason": "no releases found",
"name": "Signed-Releases",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#signed-releases",
"short": "Determines if the project cryptographically signs release artifacts."
}
},
{
"details": [
"Warn: no topLevel permission defined: .github/workflows/ci.yml:1",
"Warn: no topLevel permission defined: .github/workflows/redis-compatibility.yml:1",
"Info: no jobLevel write permissions found"
],
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"name": "Token-Permissions",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions",
"short": "Determines if the project's workflows follow the principle of least privilege."
}
},
{
"details": null,
"score": 10,
"reason": "0 existing vulnerabilities detected",
"name": "Vulnerabilities",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#vulnerabilities",
"short": "Determines if the project has open, known unfixed vulnerabilities."
}
}
],
"metadata": null
}
I'd like to propose to evaluate and (selectively) adopt secure software development best practices recommended by the Open Source Security Foundation (OpenSSF) [1]. The OpenSSF Scorecard project checks various development best practices of open source projects hosted on GitHub and provides guidance on how to improve those practices [2]. The overall goal of this issue is to strengthen the (supply chain) security posture of the ered project.
[1] https://openssf.org/ [2] https://github.com/ossf/scorecard/tree/main#scorecard-checks
Below are the results as of today. I would recommend looking into
enabling dependabot (at least for the GitHub actions)
{ "date": "2024-03-20T23:07:30+01:00", "repo": { "name": "github.com/Ericsson/ered", "commit": "fd716d22cf10912ff140e46f7a2aca413c80066f" }, "scorecard": { "version": "(devel)", "commit": "unknown" }, "score": 4.2, "checks": [ { "details": null, "score": 10, "reason": "no binaries found in the repo", "name": "Binary-Artifacts", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#binary-artifacts", "short": "Determines if the project has generated executable (binary) artifacts in the source repository." } }, { "details": [ "Warn: 'force pushes' enabled on branch 'main'", "Info: 'allow deletion' disabled on branch 'main'", "Warn: status checks do not require up-to-date branches for 'main'", "Warn: 'last push approval' disabled on branch 'main'", "Info: PRs are required in order to make changes on branch 'main'", "Warn: no status checks found to merge onto branch 'main'", "Warn: number of required reviewers is 0 on branch 'main', while the ideal suggested is 2", "Warn: stale review dismissal disabled on branch 'main'", "Warn: settings do not apply to administrators on branch 'main'", "Warn: codeowner review is not required on branch 'main'" ], "score": 1, "reason": "branch protection is not maximal on development and all release branches", "name": "Branch-Protection", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection", "short": "Determines if the default and release branches are protected with GitHub's branch protection settings." } }, { "details": null, "score": 9, "reason": "21 out of 23 merged PRs checked by a CI test -- score normalized to 9", "name": "CI-Tests", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#ci-tests", "short": "Determines if the project runs tests before pull requests are merged." } }, { "details": null, "score": 0, "reason": "no effort to earn an OpenSSF best practices badge detected", "name": "CII-Best-Practices", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#cii-best-practices", "short": "Determines if the project has an OpenSSF (formerly CII) Best Practices Badge." } }, { "details": null, "score": 7, "reason": "found 7 unreviewed changesets out of 26 -- score normalized to 7", "name": "Code-Review", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#code-review", "short": "Determines if the project requires human code review before pull requests (aka merge requests) are merged." } }, { "details": [ "Info: mysql-otp contributor org/company found, ericsson software technology contributor org/company found, ericsson contributor org/company found, " ], "score": 10, "reason": "project has 3 contributing companies or organizations -- score normalized to 10", "name": "Contributors", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#contributors", "short": "Determines if the project has a set of contributors from multiple organizations (e.g., companies)." } }, { "details": null, "score": 10, "reason": "no dangerous workflow patterns detected", "name": "Dangerous-Workflow", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#dangerous-workflow", "short": "Determines if the project's GitHub Action workflows avoid dangerous patterns." } }, { "details": [ "Warn: tool 'RenovateBot' is not used", "Warn: tool 'Dependabot' is not used", "Warn: tool 'PyUp' is not used" ], "score": 0, "reason": "no update tool detected", "name": "Dependency-Update-Tool", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool", "short": "Determines if the project uses a dependency update tool." } }, { "details": [ "Warn: no OSSFuzz integration found", "Warn: no GoBuiltInFuzzer integration found", "Warn: no PythonAtherisFuzzer integration found", "Warn: no CLibFuzzer integration found", "Warn: no CppLibFuzzer integration found", "Warn: no SwiftLibFuzzer integration found", "Warn: no RustCargoFuzzer integration found", "Warn: no JavaJazzerFuzzer integration found", "Warn: no ClusterFuzzLite integration found", "Warn: no HaskellPropertyBasedTesting integration found", "Warn: no TypeScriptPropertyBasedTesting integration found", "Warn: no JavaScriptPropertyBasedTesting integration found" ], "score": 0, "reason": "project is not fuzzed", "name": "Fuzzing", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#fuzzing", "short": "Determines if the project uses fuzzing." } }, { "details": [ "Info: FSF or OSI recognized license: LICENSE:1", "Info: License file found in expected location: LICENSE:1" ], "score": 10, "reason": "license file detected", "name": "License", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#license", "short": "Determines if the project has defined a license." } }, { "details": null, "score": 1, "reason": "2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1", "name": "Maintained", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained", "short": "Determines if the project is \"actively maintained\"." } }, { "details": [ "Warn: no GitHub/GitLab publishing workflow detected." ], "score": -1, "reason": "packaging workflow not detected", "name": "Packaging", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#packaging", "short": "Determines if the project is published as a package that others can easily download, install, easily update, and uninstall." } }, { "details": [ "Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:13", "Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:38", "Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/redis-compatibility.yml:16", "Warn: third-party GitHubAction not pinned by hash: .github/workflows/redis-compatibility.yml:18", "Info: 0 out of 3 GitHub-owned GitHubAction dependencies pinned", "Info: 0 out of 1 third-party GitHubAction dependencies pinned" ], "score": 0, "reason": "dependency not pinned by hash detected -- score normalized to 0", "name": "Pinned-Dependencies", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies", "short": "Determines if the project has declared and pinned the dependencies of its build process." } }, { "details": [ "Warn: 0 commits out of 27 are checked with a SAST tool" ], "score": 0, "reason": "SAST tool is not run on all commits -- score normalized to 0", "name": "SAST", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#sast", "short": "Determines if the project uses static code analysis." } }, { "details": [ "Warn: no security policy file detected", "Warn: no security file to analyze", "Warn: no security file to analyze", "Warn: no security file to analyze" ], "score": 0, "reason": "security policy file not detected", "name": "Security-Policy", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#security-policy", "short": "Determines if the project has published a security policy." } }, { "details": null, "score": -1, "reason": "no releases found", "name": "Signed-Releases", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#signed-releases", "short": "Determines if the project cryptographically signs release artifacts." } }, { "details": [ "Warn: no topLevel permission defined: .github/workflows/ci.yml:1", "Warn: no topLevel permission defined: .github/workflows/redis-compatibility.yml:1", "Info: no jobLevel write permissions found" ], "score": 0, "reason": "detected GitHub workflow tokens with excessive permissions", "name": "Token-Permissions", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions", "short": "Determines if the project's workflows follow the principle of least privilege." } }, { "details": null, "score": 10, "reason": "0 existing vulnerabilities detected", "name": "Vulnerabilities", "documentation": { "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#vulnerabilities", "short": "Determines if the project has open, known unfixed vulnerabilities." } } ], "metadata": null }