diff --git a/data-sources/ghapi.yaml b/data-sources/ghapi.yaml index f9c8fcc..c821367 100644 --- a/data-sources/ghapi.yaml +++ b/data-sources/ghapi.yaml @@ -14,3 +14,13 @@ rest: type: string repo: type: string + repo: + endpoint: https://api.github.com/repos/{owner}/{repo} + parse: json + input_schema: + type: object + properties: + owner: + type: string + repo: + type: string diff --git a/rule-types/github/osps-do-03.yaml b/rule-types/github/osps-do-03.yaml new file mode 100644 index 0000000..565e93e --- /dev/null +++ b/rule-types/github/osps-do-03.yaml @@ -0,0 +1,103 @@ +--- +version: v1 +release_phase: alpha +type: rule-type +name: osps-do-03 +display_name: OSPS-DO-03 The project documentation MUST provide user guides for all basic functionality +short_failure_message: No user guides or project documentation found +severity: + value: low +context: + provider: github +description: | + Verifies that the project documentation provides a user guide. + + This rule attempts to locate user guides from several project documentation sources. + + Currently, this rule checks the following: + + * The GitHub repository's public link + * A `docs` directory in the default branch of the repository with .md, .rst, .html or .txt files + * A `README.md` file containing preformatted text (triple-backtick) or the headings + "usage" or "getting started" + + For more information, see [OpenSSF Security Baseline](https://baseline.openssf.org/#osps-do-03). +guidance: | + Publish documentation in one of the following well-known locations: + + * Set the repository homepage to a documentation URL. + * Create a `docs` directory in the default branch of the repository + * Add a "usage" or "getting started" section to `README.md` +def: + in_entity: repository + rule_schema: {} + ingest: + type: git + eval: + type: rego + data_sources: + - name: ghapi + rego: + type: deny-by-default + def: | + package minder + + import rego.v1 + + default allow := false + + repo := sprintf("%s/%s", []) + + allow if { + # Check the SECURITY-INSIGHTS.yaml file + file.exists("SECURITY-INSIGHTS.yaml") + si_data := yaml.unmarshal(file.read("SECURITY-INSIGHTS.yaml")) + count(si_data.documentation) > 0 + } + + # TODO: these should trigger a remediation to put them in + # SECURITY-INSIGHTS.yaml, but also still pass the check(?) + + allow if { + # Check the GitHub homepage link + out = minder.datasource.ghapi.repo({ + "owner": input.properties["github/repo_owner"], + "repo": input.properties["github/repo_name"] + }) + out.body.homepage != "" + } + + allow if { + # Check the docs directory + mdDocs := file.ls_glob("docs/*.md") + rstDocs := file.ls_glob("docs/*.rst") + htmlDocs := file.ls_glob("docs/*.html") + txtDocs := file.ls_glob("docs/*.txt") + count(mdDocs) + count(rstDocs) + count(htmlDocs) + count(txtDocs) > 0 + } + + readme := file.read("README.md") + allow if { + # Check the README.md file for preformatted text after the first line + regex.match("\n *```", readme) + } + allow if { + regex.match("\n#+ (?i:Usage|Getting Started)", readme) + } + remediate: + type: pull_request + pull_request: + title: "Add documentation to security-insights.yaml" + body: | + This is a Minder automated pull request. + + This pull request links the discovered documentation in the security-insights.yaml file. + method: minder.yq.evaluate + params: + # TODO: need to be able to feed output from eval into remediate + expression: | + .documentation = [ "./README.md" ] + patterns: + # TODO: need to be able to create files as well as match existing files + - pattern: "SECURITY-INSIGHTS.yaml" + type: glob \ No newline at end of file