APIAPI v1SARIF per Repo

SARIF per Repository

GET /api/v1/repositories/{repositoryUrl}/sarif

This endpoint gets parameterized with the full repository URL. The repository URL is the URL of the repository that should be scanned. The URL must be URL encoded (https://gitlab.opencode.de/zendis-repo-scanner → https%3A%2F%2Fgitlab.opencode.de%2Fzendis-repo-scanner).

Using this format opens the possibility to scan repositories from other platforms like GitHub, Bitbucket, etc. Besides that, caching is simplified because the URL is unique (instead of using the project ID and a platform URL as query string for example) and the URL is human-readable, at least after URL decoding. This might improve debugging in the future.

The result is returned in SARIF format. SARIF simplifies possible later integration with other tools. It is an open standard and widely supported.

Example Request

main.go
package main
 
import (
    "fmt"
    "io"
    "net/http"
)
 
func main() {
    url := "https://scanner.zend.is/api/v1/repositories/https%3A%2F%2Fgitlab.opencode.de%2Fzendis-repo-scanner/sarif"
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    defer resp.Body.Close()
 
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))
}

Example JSON Response

{
  "$schema": "https://www.schemastore.org/schemas/json/sarif-2.1.0.json",
  "runs": [
    {
      "properties": {
        "badges": [
          {
            "badgeId": "MAINTAINED",
            "badgeLevel": "BRONZE",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/badge-api/-/raw/main/assets/MAINTAINED-1.svg",
            "badgeGranted": true,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": false,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "The number of commits in the last 6 months. (The current value is 39)",
                  "value": "39",
                  "status": "pass",
                  "ruleId": "COMMITS",
                  "threshold": {
                    "min": 5,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "BRONZE",
                  "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4"
                }
              ]
            }
          },
          {
            "badgeId": "MAINTAINED",
            "badgeLevel": "SILVER",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/badge-api/-/raw/main/assets/MAINTAINED-2.svg",
            "badgeGranted": true,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": false,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "The number of commits in the last 6 months. (The current value is 39)",
                  "value": "39",
                  "status": "pass",
                  "ruleId": "COMMITS",
                  "threshold": {
                    "min": 5,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "BRONZE",
                  "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4"
                },
                {
                  "description": "The minimum time it takes for a project member to react to an issue in the last 3 months. (The current value is <nil>)",
                  "value": "<nil>",
                  "status": "open",
                  "ruleId": "ISSUE_REACTION_TIME",
                  "threshold": {
                    "max": 7,
                    "timeRangeInMonths": 3
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "SILVER"
                }
              ]
            }
          },
          {
            "badgeId": "MAINTAINED",
            "badgeLevel": "GOLD",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/badge-api/-/raw/main/assets/MAINTAINED-3.svg",
            "badgeGranted": true,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": true,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "The number of commits in the last 6 months. (The current value is 39)",
                  "value": "39",
                  "status": "pass",
                  "ruleId": "COMMITS",
                  "threshold": {
                    "min": 5,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "BRONZE",
                  "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4"
                },
                {
                  "description": "The minimum time it takes for a project member to react to an issue in the last 3 months. (The current value is <nil>)",
                  "value": "<nil>",
                  "status": "open",
                  "ruleId": "ISSUE_REACTION_TIME",
                  "threshold": {
                    "max": 7,
                    "timeRangeInMonths": 3
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "SILVER"
                },
                {
                  "description": "The number of tags/releases in the last 6 months. (The current value is 1)",
                  "value": "1",
                  "status": "pass",
                  "ruleId": "RELEASES",
                  "threshold": {
                    "min": 1,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "MAINTAINED",
                  "badgeLevel": "GOLD",
                  "evidence": "The number of tags/releases in the last 6 months is 1 (1 tag(s) of which 0 are releases). The following tags/releases were found: tag:v1.1.0"
                }
              ]
            }
          },
          {
            "badgeId": "REUSED",
            "badgeLevel": "BRONZE",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/badge-api/-/raw/main/assets/REUSED-1.svg",
            "badgeGranted": false,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": false,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "The project has a packaging system in place and used it during the last 6 months. It checks the container registry, the package registry and the releases. It expects either a release to have assets or packages inside those two registries (The current value is 0)",
                  "value": "0",
                  "status": "fail",
                  "ruleId": "PACKAGES",
                  "threshold": {
                    "min": 1,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "REUSED",
                  "badgeLevel": "BRONZE",
                  "evidence": "No container tags, packages or releases with assets found."
                },
                {
                  "description": "The number of CI pipeline runs in the last 6 months. (The current value is 56)",
                  "value": "56",
                  "status": "pass",
                  "ruleId": "CI_PIPELINE",
                  "threshold": {
                    "min": 1,
                    "timeRangeInMonths": 6
                  },
                  "badgeId": "REUSED",
                  "badgeLevel": "BRONZE",
                  "evidence": "The number of CI pipeline runs in the last 6 months is 56 (43 of 56 were successful)."
                }
              ]
            }
          },
          {
            "badgeId": "DIN-SPEC-XXXX",
            "badgeLevel": "BRONZE",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/manual-badges/-/raw/main/badges/din-spec-xxxx.svg",
            "badgeGranted": false,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": false,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "Provides a badge for projects that are compliant with DIN SPEC XXXX. This badge is granted manually trough the DIN SPEC XXXX working group. (The current value is 0)",
                  "value": "0",
                  "status": "fail",
                  "ruleId": "MANUAL/DIN SPEC XXXX compliant",
                  "threshold": {
                    "min": 1
                  },
                  "badgeId": "DIN-SPEC-XXXX",
                  "badgeLevel": "BRONZE",
                  "evidence": "Check was not manually granted"
                }
              ]
            }
          },
          {
            "badgeId": "OPEN-SOURCE",
            "badgeLevel": "GOLD",
            "badgeUrl": "https://gitlab.opencode.de/open-code/badgebackend/manual-badges/-/raw/main/badges/open-source.svg",
            "badgeGranted": true,
            "badgeInformationUri": "",
            "isHighestGrantedBadge": true,
            "badgeExplanation": {
              "criteria": [
                {
                  "description": "Provides a badge for projects that are open-source. This badge is granted manually by the openCode team. (The current value is 1)",
                  "value": "1",
                  "status": "pass",
                  "ruleId": "MANUAL/Project is open source",
                  "threshold": {
                    "min": 1
                  },
                  "badgeId": "OPEN-SOURCE",
                  "badgeLevel": "GOLD",
                  "evidence": "Check was manually granted"
                }
              ]
            }
          }
        ],
        "testedRepository": "https://gitlab.opencode.de/bmi/ozg-rahmenarchitektur/ozgsec/ozgsec-best-practice-scanner"
      },
      "results": [
        {
          "kind": "pass",
          "message": "The number of commits in the last 6 months. (The current value is 39)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "BRONZE",
            "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4",
            "threshold": {
              "min": 5,
              "timeRangeInMonths": 6
            },
            "value": "39"
          },
          "ruleId": "COMMITS",
          "ruleIndex": 0
        },
        {
          "kind": "pass",
          "message": "The number of commits in the last 6 months. (The current value is 39)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "BRONZE",
            "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4",
            "threshold": {
              "min": 5,
              "timeRangeInMonths": 6
            },
            "value": "39"
          },
          "ruleId": "COMMITS",
          "ruleIndex": 0
        },
        {
          "kind": "open",
          "message": "The minimum time it takes for a project member to react to an issue in the last 3 months. (The current value is <nil>)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "SILVER",
            "evidence": "",
            "threshold": {
              "max": 7,
              "timeRangeInMonths": 3
            },
            "value": "<nil>"
          },
          "ruleId": "ISSUE_REACTION_TIME",
          "ruleIndex": 1
        },
        {
          "kind": "pass",
          "message": "The number of commits in the last 6 months. (The current value is 39)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "BRONZE",
            "evidence": "The number of commits in the last 6 months is 39. First commit dd519848, last commit e5eaf6c4",
            "threshold": {
              "min": 5,
              "timeRangeInMonths": 6
            },
            "value": "39"
          },
          "ruleId": "COMMITS",
          "ruleIndex": 0
        },
        {
          "kind": "open",
          "message": "The minimum time it takes for a project member to react to an issue in the last 3 months. (The current value is <nil>)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "SILVER",
            "evidence": "",
            "threshold": {
              "max": 7,
              "timeRangeInMonths": 3
            },
            "value": "<nil>"
          },
          "ruleId": "ISSUE_REACTION_TIME",
          "ruleIndex": 1
        },
        {
          "kind": "pass",
          "message": "The number of tags/releases in the last 6 months. (The current value is 1)",
          "properties": {
            "badgeId": "MAINTAINED",
            "badgeLevel": "GOLD",
            "evidence": "The number of tags/releases in the last 6 months is 1 (1 tag(s) of which 0 are releases). The following tags/releases were found: tag:v1.1.0",
            "threshold": {
              "min": 1,
              "timeRangeInMonths": 6
            },
            "value": "1"
          },
          "ruleId": "RELEASES",
          "ruleIndex": 2
        },
        {
          "kind": "fail",
          "message": "The project has a packaging system in place and used it during the last 6 months. It checks the container registry, the package registry and the releases. It expects either a release to have assets or packages inside those two registries (The current value is 0)",
          "properties": {
            "badgeId": "REUSED",
            "badgeLevel": "BRONZE",
            "evidence": "No container tags, packages or releases with assets found.",
            "threshold": {
              "min": 1,
              "timeRangeInMonths": 6
            },
            "value": "0"
          },
          "ruleId": "PACKAGES",
          "ruleIndex": 3
        },
        {
          "kind": "pass",
          "message": "The number of CI pipeline runs in the last 6 months. (The current value is 56)",
          "properties": {
            "badgeId": "REUSED",
            "badgeLevel": "BRONZE",
            "evidence": "The number of CI pipeline runs in the last 6 months is 56 (43 of 56 were successful).",
            "threshold": {
              "min": 1,
              "timeRangeInMonths": 6
            },
            "value": "56"
          },
          "ruleId": "CI_PIPELINE",
          "ruleIndex": 4
        },
        {
          "kind": "fail",
          "message": "Provides a badge for projects that are compliant with DIN SPEC XXXX. This badge is granted manually trough the DIN SPEC XXXX working group. (The current value is 0)",
          "properties": {
            "badgeId": "DIN-SPEC-XXXX",
            "badgeLevel": "BRONZE",
            "evidence": "Check was not manually granted",
            "threshold": {
              "min": 1
            },
            "value": "0"
          },
          "ruleId": "MANUAL/DIN SPEC XXXX compliant",
          "ruleIndex": 5
        },
        {
          "kind": "pass",
          "message": "Provides a badge for projects that are open-source. This badge is granted manually by the openCode team. (The current value is 1)",
          "properties": {
            "badgeId": "OPEN-SOURCE",
            "badgeLevel": "GOLD",
            "evidence": "Check was manually granted",
            "threshold": {
              "min": 1
            },
            "value": "1"
          },
          "ruleId": "MANUAL/Project is open source",
          "ruleIndex": 6
        }
      ],
      "tool": {
        "driver": {
          "informationUri": "https://gitlab.opencode.de/open-code/badgebackend/badge-api",
          "name": "badge-api",
          "rules": [
            {
              "id": "COMMITS",
              "name": "Commits",
              "fullDescription": {
                "text": "The number of commits in the last 6 months."
              },
              "help": {
                "text": "The number of commits in the last 6 months."
              },
              "properties": {
                "unit": "commits",
                "threshold": {
                  "min": 5,
                  "timeRangeInMonths": 6
                }
              }
            },
            {
              "id": "ISSUE_REACTION_TIME",
              "name": "Issue Reaction Time",
              "fullDescription": {
                "text": "The minimum time it takes for a project member to react to an issue in the last 3 months."
              },
              "help": {
                "text": "The minimum time it takes for a project member to react to an issue in the last 3 months."
              },
              "properties": {
                "unit": "days",
                "threshold": {
                  "max": 7,
                  "timeRangeInMonths": 3
                }
              }
            },
            {
              "id": "RELEASES",
              "name": "Releases",
              "fullDescription": {
                "text": "The number of tags/releases in the last 6 months."
              },
              "help": {
                "text": "The number of tags/releases in the last 6 months."
              },
              "properties": {
                "unit": "releases",
                "threshold": {
                  "min": 1,
                  "timeRangeInMonths": 6
                }
              }
            },
            {
              "id": "PACKAGES",
              "name": "Packaging",
              "fullDescription": {
                "text": "The project has a packaging system in place and used it during the last 6 months. It checks the container registry, the package registry and the releases. It expects either a release to have assets or packages inside those two registries"
              },
              "help": {
                "text": "Packaging is a way to distribute software. It is important to have a packaging system in place to make it easier for users to install and use the software. Packaging systems can help automate the process of installing software, manage dependencies, and ensure that the software is installed correctly. This check looks for a packaging system in the project and checks if it has been used in the last 6 months."
              },
              "properties": {
                "unit": "packages",
                "threshold": {
                  "min": 1,
                  "timeRangeInMonths": 6
                }
              }
            },
            {
              "id": "CI_PIPELINE",
              "name": "CI Pipeline Runs",
              "fullDescription": {
                "text": "The number of CI pipeline runs in the last 6 months."
              },
              "help": {
                "text": "The number of CI pipeline runs the last 6 months."
              },
              "properties": {
                "unit": "runs",
                "threshold": {
                  "min": 1,
                  "timeRangeInMonths": 6
                }
              }
            },
            {
              "id": "MANUAL/DIN SPEC XXXX compliant",
              "name": "DIN SPEC XXXX compliant",
              "fullDescription": {
                "text": "Provides a badge for projects that are compliant with DIN SPEC XXXX. This badge is granted manually trough the DIN SPEC XXXX working group."
              },
              "help": {
                "text": "This is a manual check"
              },
              "properties": {
                "unit": "",
                "threshold": {
                  "min": 1
                }
              }
            },
            {
              "id": "MANUAL/Project is open source",
              "name": "Project is open source",
              "fullDescription": {
                "text": "Provides a badge for projects that are open-source. This badge is granted manually by the openCode team."
              },
              "help": {
                "text": "This is a manual check"
              },
              "properties": {
                "unit": "",
                "threshold": {
                  "min": 1
                }
              }
            }
          ]
        }
      }
    }
  ],
  "version": "2.1.0"
}