> ## Documentation Index
> Fetch the complete documentation index at: https://backstage.spotify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub

> Collect GitHub-specific facts including branch protections, repository details, Dependabot alerts, code scanning alerts, and security advisories.

Similar to the [Source Control Management (SCM)](./scm) integration plugin, the GitHub integration plugin for [Soundcheck](https://backstage.spotify.com/plugins/soundcheck/) provides out-of-box integration with GitHub by leveraging Backstage's GitHub integration to implement collection of facts from GitHub repositories.

The purpose of the GitHub integration plugin is to provide GitHub-specific fact collection (like branch protections), while the SCM integration plugin provides the collection of facts based on repository content.

The GitHub integration allows collecting details about repositories and branches, as well as
security alerts and advisories that come as part of the GitHub Advanced Security products.
The collection of the following facts is supported:

* [BranchProtections](#collecting-branchprotections-fact)
* [BranchRules](#collecting-branchrules-fact)
* [CodeScanningAlerts](#collecting-codescanningalerts-fact)
* [DependabotAlerts](#collecting-dependabotalerts-fact)
* [RepositoryDetails](#collecting-repositorydetails-fact)
* [RepositoryLanguages](#collecting-repositorylanguages-fact)
* [SecretScanningAlerts](#collecting-secretscanningalerts-fact)
* [SecurityAdvisories](#collecting-securityadvisories-fact)

## Prerequisites

### Configure GitHub integration in Backstage

Integrations are configured at the root level of `app-config.yaml`. Here's an example configuration for GitHub:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}
```

Consult the [Backstage GitHub integration instructions](https://backstage.io/docs/integrations/github/locations) for full configuration details.

<Warning>
  If no GitHub integration is configured for a repository, the GitHub Fact
  Collector will **not** make unauthenticated requests and will instead return a
  fact collection error. This avoids hitting low unauthenticated rate limits
  that could block the entire GitHub Fact Collector queue.
</Warning>

### Add the GitHubFactCollector to Soundcheck

GitHub integration for Soundcheck is not installed by default. It must be manually installed and configured for the **GitHub Fact Collector** to work.

First, add the `@spotify/backstage-plugin-soundcheck-backend-module-github` package:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
yarn workspace backend add @spotify/backstage-plugin-soundcheck-backend-module-github
```

Then add the following to your `packages/backend/src/index.ts` file:

```ts packages/backend/src/index.ts highlight={4} theme={"theme":{"light":"github-light","dark":"dracula"}}
const backend = createBackend();

backend.add(import('@spotify/backstage-plugin-soundcheck-backend'));
backend.add(
  import('@spotify/backstage-plugin-soundcheck-backend-module-github'),
);
// ...

backend.start();
```

Consult the [Soundcheck Backend documentation](../../../setup-and-installation#backend-setup) for additional details on setting up the Soundcheck backend.

### Entity configuration

To be able to determine the repository to use the GitHub integration will use the value from the [`backstage.io/source-location`](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) annotation. In many cases this will be set for you but if it is not you will need to add it to your `catalog-info.yaml` file, here's a simple example:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
metadata:
  annotations:
    backstage.io/source-location: url:https://github.com/my-org/my-service/tree/main
```

## Plugin Configuration

The collection of facts is driven by configuration. To learn more about the configuration, jump to the [Defining GitHub Fact Collectors](#defining-github-fact-collectors) section.

GitHub Fact Collector can be configured via YAML or No-Code UI. If you configure it via both YAML and No-Code UI, the configurations will be merged.
It's preferable to choose a single source for the Fact Collectors configuration (either No-Code UI or YAML) to avoid confusing merge results.

### No-Code UI Configuration Option

1. Make sure the prerequisite [Configure GitHub integration in Backstage](#configure-github-integration-in-backstage) is completed and GitHub instance details are configured.

2. To enable the GitHub Integration, go to `Soundcheck > Integrations > GitHub` and click the `Configure` button. To learn more about the No-Code UI config, see the [Configuring a fact collector (integration) via the no-code UI](../index#configuring-a-fact-collector-integration-via-the-no-code-ui).

<Frame>
  <img
    src="https://mintcdn.com/spotify-89f50c35/ulmNVnZzSFL3BsWR/plugins/soundcheck/images/collectors/github-collector-ncui.png?fit=max&auto=format&n=ulmNVnZzSFL3BsWR&q=85&s=53544cacba55ce4a76be07c84723e9b9"
    alt="GitHub
Integration"
    width="3456"
    height="1916"
    data-path="plugins/soundcheck/images/collectors/github-collector-ncui.png"
  />
</Frame>

### YAML Configuration Option

1. Create a `github-facts-collectors.yaml` file in the root of your Backstage repository and fill in all your **GitHub Fact Collectors**.
   A simple example **GitHub Fact Collector** is listed below.

   ```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
   ---
   frequency:
     cron: '0 * * * *'
   collects:
     - factName: branch_protections
       type: BranchProtections
     - factName: branch_rules
       type: BranchRules
     - factName: code_scanning_alerts
       type: CodeScanningAlerts
       state: open
     - factName: dependabot_alerts
       type: DependabotAlerts
       states:
         - open
     - factName: repository_details
       type: RepositoryDetails
     - factName: repository_languages
       type: RepositoryLanguages
     - factName: secret_scanning_alerts
       type: SecretScanningAlerts
       state: open
     - factName: security_advisories
       type: SecurityAdvisories
       state: published
   ```

   **Note:** this file will be loaded at runtime along with the rest of your Backstage configuration files. Therefore, make sure that it's available in deployed environments in the same way as your `app-config.yaml` files are.

2. Add a soundcheck collectors field to `app-config.yaml` and reference the newly created `github-facts-collectors.yaml`

   ```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
   # app-config.yaml
   soundcheck:
     collectors:
       github:
         $include: ./github-facts-collectors.yaml
   ```

### Rate Limiting (Optional)

This fact collector can be rate limited in Soundcheck using the following configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  job:
    workers:
      github:
        limiter:
          max: 4900
          duration: 3600000
```

GitHub API has a limit of [5000 requests per hour (15000 for Enterprise)](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28). We recommend setting your rate limit to something below this, i.e. in the example above, we set the rate limit to 4900 executions every hour.

This fact collector handles rate limit errors per the [recommendation from GitHub](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#exceeding-the-rate-limit). Soundcheck will automatically wait and retry requests that are rate limited.

## Defining GitHub Fact Collectors

This section describes the data shape and semantics of **GitHub Fact Collectors**.

### Overall Shape Of A GitHub Fact Collector

The following is an example of a descriptor file for a **GitHub Fact Collector**:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
---
frequency:
  cron: '0 * * * *'
initialDelay:
  seconds: 30
filter:
  kind: 'Component'
cache:
  duration:
    hours: 2
collects:
  - factName: branch_protections
    type: BranchProtections
    filter:
      - spec.lifecycle: 'production'
        spec.type: 'website'
    cache: false
  - factName: branch_rules
    type: BranchRules
  - factName: code_scanning_alerts
    type: CodeScanningAlerts
    state: open
  - factName: dependabot_alerts
    type: DependabotAlerts
    states:
      - open
  - factName: repository_details
    type: RepositoryDetails
    cache: true
    exclude:
      - spec.type: 'documentation'
  - factName: repository_languages
    type: RepositoryLanguages
  - factName: secret_scanning_alerts
    type: SecretScanningAlerts
    state: open
  - factName: security_advisories
    type: SecurityAdvisories
    state: published
```

Below are the details for each field.

#### `frequency` \[optional]

The frequency at which the collector should be executed. Possible values are either a cron expression `{ cron: ... }` or [HumanDuration](https://backstage.io/docs/reference/types.humanduration).
This is the default frequency for each collector.

#### `initialDelay` \[optional]

The amount of time that should pass before the first invocation happens. Possible values are either a cron expression `{ cron: ... }` or [HumanDuration](https://backstage.io/docs/reference/types.humanduration).

#### `batchSize` \[optional]

The number of entities to collect facts for at once. Optional, the default value is 1.

**Note**: Fact collection for a batch of entities is still considered as one hit towards the rate limits
by the Soundcheck [Rate Limiting](#rate-limiting-optional) engine, while the actual number of hits
will be equal to the `batchSize`.

Example:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
batchSize: 100
```

#### `filter` \[optional]

A filter specifying which entities to collect the specified facts for. Matches the [filter format](https://backstage.io/docs/reference/catalog-client.entityfilterquery) used by the Catalog API.
This is the default filter for each collector.

See [filters](/plugins/soundcheck/core-concepts/filters) for more details.

#### `exclude` \[optional]

Entities matching this filter will be skipped during the fact collection process. Can be used in combination with filter. Matches the [filter format](https://backstage.io/docs/reference/catalog-client.entityfilterquery) used by the Catalog API.

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
filter:
  - kind: component
exclude:
  - spec.type: documentation
```

#### `cache` \[optional]

If the collected facts should be cached, and if so for how long. Possible values are either `true` or `false` or a nested `{ duration:` [HumanDuration](https://backstage.io/docs/reference/types.humanduration) `}` field.
This is the default cache config for each collector.

#### `collects` \[required]

An array describing which facts to collect and how to collect them. See below for details about the overall shape of a fact collector.

### Overall Shape Of A Fact Collector

Each collector supports the fields described below.

#### `factName` \[required]

The name of the fact to be collected.

* Minimum length of 1
* Maximum length of 100
* Alphanumeric with single separator instances of periods, dashes, underscores, or forward slashes

#### `type` \[required]

The type of the collector (e.g. BranchProtections, RepositoryDetails).

#### `frequency` \[optional]

The frequency at which the fact collection should be executed. Possible values are either a cron expression `{ cron: ... }` or [HumanDuration](https://backstage.io/docs/reference/types.humanduration).
If provided, it overrides the default frequency provided at the top level. If not provided, it defaults to the frequency provided at the top level. If neither collector's frequency, nor default frequency is provided, the fact will only be collected on demand.

Example:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
frequency:
  minutes: 10
```

#### `batchSize` \[optional]

The number of entities to collect facts for at once. Optional, the default value is 1.
If provided it overrides the default batchSize provided at the top level. If not provided it defaults to the batchSize provided at the top level. If neither collector's batchSize nor default batchSize is provided the fact will be collected for one entity at a time.

**Note**: Fact collection for a batch of entities is still considered as one hit towards the rate limits
by the Soundcheck [Rate Limiting](#rate-limiting-optional) engine, while the actual number of hits
will be equal to the `batchSize`.

Example:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
batchSize: 100
```

#### `filter` \[optional]

A filter specifying which entities to collect the specified facts for. Matches the [filter format](https://backstage.io/docs/reference/catalog-client.entityfilterquery) used by the Catalog API.
If provided, it overrides the default filter provided at the top level. If not provided, it defaults to the filter provided at the top level. If neither collector's filter, nor default filter is provided, the fact will be collected for all entities.

#### `exclude` \[optional]

Entities matching this filter will be skipped during the fact collection process. Can be used in combination with filter. Matches the [filter format](https://backstage.io/docs/reference/catalog-client.entityfilterquery) used by the Catalog API.

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
filter:
  - kind: component
exclude:
  - spec.type: documentation
```

#### `cache` \[optional]

If the collected facts should be cached, and if so for how long. Possible values are either `true` or `false` or a nested `{ duration:` [HumanDuration](https://backstage.io/docs/reference/types.humanduration) `}` field.
If provided, it overrides the default cache config provided at the top level. If not provided, it defaults to the cache config provided at the top level. If neither collector's cache nor default cache config is provided, the fact will not be cached.
Example:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
cache:
  duration:
    hours: 24
```

## Collecting BranchProtections Fact

The `BranchProtections` fact contains information about configured branch protections for a default branch in a GitHub repository.

Prerequisites:

* Grant your GitHub app or access token with necessary permissions listed in the [Get branch protection](https://docs.github.com/en/rest/branches/branch-protection#get-branch-protection) GitHub API documentation.

### Shape of A BranchProtections Fact Collector

The shape of a BranchProtections Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: BranchProtections`).

The following is an example of the `BranchProtections` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: branch_protections
    type: BranchProtections
    frequency:
      cron: '0 * * * *'
    filter:
      - spec.lifecycle: 'production'
        spec.type: 'website'
    cache: false
```

### Shape of A BranchProtections Fact

The shape of a `BranchProtections` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding branch protection, refer to the [GitHub API documentation](https://docs.github.com/en/rest/branches/branch-protection#get-branch-protection).

The following is an example of the collected `BranchProtections` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/branch_protections
entityRef: component:default/queue-proxy
timestamp: 2023-02-24T15:50+00Z
data:
  url: 'https://api.github.com/repos/backstage/backstage/branches/main/protection'
  required_pull_request_reviews:
    url: 'https://api.github.com/repos/backstage/backstage/branches/main/protection/required_pull_request_reviews',
    dismiss_stale_reviews: false
    require_code_owner_reviews: true
    required_approving_review_count: 2
    require_last_push_approval: false
  required_signatures:
    url: 'https://api.github.com/repos/backstage/backstage/branches/main/protection/required_signatures'
    enabled: false
  enforce_admins:
    url: 'https://api.github.com/repos/backstage/backstage/branches/main/protection/enforce_admins'
    enabled: false
  required_linear_history:
    enabled: false
  allow_force_pushes:
    enabled: true
  allow_deletions:
    enabled: true
  block_creations:
    enabled: true
  required_conversation_resolution:
    enabled: false
  lock_branch:
    enabled: false
  allow_fork_syncing:
    enabled: true
```

### Shape of A BranchProtections Fact Check

The shape of a `BranchProtections` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `BranchProtections` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: requires_code_owner_reviews
      rule:
        factRef: github:default/branch_protections
        path: $.required_pull_request_reviews.require_code_owner_reviews
        operator: equal
        value: true
    - id: requires_at_least_two_approving_reviews
      rule:
        factRef: github:default/branch_protections
        path: $.required_pull_request_reviews.required_approving_review_count
        operator: greaterThanInclusive
        value: 2
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck BranchProtections Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub BranchProtections Fact Collector
      checks:
        - id: requires_code_owner_reviews
          name: Requires code owner reviews
          description: PR requires code owner reviews
        - id: requires_at_least_two_approving_reviews
          name: Requires at least two approving reviews
          description: PR requires at least two approving reviews
```

## Collecting BranchRules Fact

The `BranchRules` fact contains information about configured branch rules for a default branch in a GitHub repository.

Prerequisites:

* Grant your GitHub app or access token with necessary permissions listed in the [Get rules for a branch](https://docs.github.com/en/rest/repos/rules#get-rules-for-a-branch) GitHub API documentation.

### Shape of A BranchRules Fact Collector

The shape of a BranchRules Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: BranchRules`).

The following is an example of the `BranchRules` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: branch_rules
    type: BranchRules
    frequency:
      cron: '0 * * * *'
    filter:
      - spec.lifecycle: 'production'
        spec.type: 'website'
    cache: false
```

### Shape of A BranchRules Fact

The shape of a `BranchRules` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding branch rules, refer to the [GitHub API documentation](https://docs.github.com/en/rest/repos/rules#get-rules-for-a-branch).

The following is an example of the collected `BranchRules` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/branch_rules
entityRef: component:default/queue-proxy
timestamp: 2024-12-10T15:50+00Z
data:
  rules:
    - type: commit_message_pattern
      ruleset_source_type: Repository
      ruleset_source: monalisa/my-repo
      ruleset_id: 42
      parameters:
        operator: starts_with
        pattern: issue
    - type: commit_author_email_pattern
      ruleset_source_type: Organization
      ruleset_source: my-org
      ruleset_id: 73
      parameters:
        operator: contains
        pattern: github
```

### Shape of A BranchRules Fact Check

The shape of a `BranchRules` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `BranchRules` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: commit_message_pattern_is_set
      rule:
        factRef: github:default/branch_rules
        path: $.rules[*].type
        operator: contains
        value: commit_message_pattern
    - id: commit_message_pattern_matches_issues
      rule:
        factRef: github:default/branch_rules
        path: $.rules[?(@.type === 'commit_message_pattern')].parameters.pattern
        operator: matches
        value: .*issues.*
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck BranchRules Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub BranchRules Fact Collector
      checks:
        - id: commit_message_pattern_is_set
          name: Commit message patters is set
          description: Commit message patters is set
        - id: commit_message_pattern_matches_issues
          name: Commit message pattern matches .*issues.*
          description: Commit message pattern matches .*issues.*
```

## Collecting CodeScanningAlerts Fact

The `CodeScanningAlerts` fact contains information about code scanning alerts for a default branch in a GitHub repository.

Prerequisites:

1. In order to be able to collect code scanning alerts you must enable them in GitHub, refer to the [GitHub Code Scanning documentation](https://docs.github.com/en/code-security/code-scanning/enabling-code-scanning).
2. Grant your GitHub app or access token with necessary permissions listed in the [List code scanning alerts for a repository](https://docs.github.com/en/rest/code-scanning/code-scanning#list-code-scanning-alerts-for-a-repository) GitHub API documentation.

<Note>
  This is a sensitive fact. See [docs](../index#sensitive-facts) for more
  details.
</Note>

### Shape of A CodeScanningAlerts Fact Collector

The shape of a CodeScanningAlerts Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: CodeScanningAlerts`)
and supports additional configuration options:

#### `toolName` \[optional]

The name of a code scanning tool. If specified, only results by this tool will be collected.
Example: 'CodeQL'.

#### `state` \[optional]

If specified, only code scanning alerts with this state will be returned.
Can be one of: 'open', 'closed', 'dismissed', 'fixed'.

#### `severity` \[optional]

If specified, only code scanning alerts with this severity will be returned.
Can be one of: 'critical', 'high', 'medium', 'low', 'warning', 'note', 'error'.

The following is an example of the `CodeScanningAlerts` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: code_scanning_alerts
    type: CodeScanningAlerts
    state: open
  - factName: codeql_dismissed_critical_alerts
    type: CodeScanningAlerts
    toolName: CodeQL
    state: dismissed
    severity: critical
```

### Shape of A CodeScanningAlerts Fact

The shape of a `CodeScanningAlerts` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding code scanning alerts, refer to the [GitHub API documentation](https://docs.github.com/en/rest/code-scanning/code-scanning#list-code-scanning-alerts-for-a-repository).

The following is an example of the collected `CodeScanningAlerts` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/code_scanning_alerts
entityRef: component:default/queue-proxy
timestamp: 2025-03-14T15:50+00Z
data:
  alerts:
    - number: 4
      created_at: 2020-02-13T12:29:18Z
      url: https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/4
      html_url: https://github.com/octocat/hello-world/code-scanning/4
      state: open
      fixed_at: null
      dismissed_by: null
      dismissed_at: null
      dismissed_reason: null
      dismissed_comment: null
      rule:
        id: js/zipslip
        severity: error
        tags:
          - security
          - external/cwe/cwe-022
        description: Arbitrary file write during zip extraction
        name: js/zipslip
      tool:
        name: CodeQL
        guid: null
        version: 2.4.0
      most_recent_instance:
        ref: refs/heads/main
        analysis_key: .github/workflows/codeql-analysis.yml:CodeQL-Build
        category: .github/workflows/codeql-analysis.yml:CodeQL-Build
        environment:
        state: open
        commit_sha: 39406e42cb832f683daa691dd652a8dc36ee8930
        message:
          text: This path depends on a user-provided value.
        location:
          path: spec-main/api-session-spec.ts
          start_line: 917
          end_line: 917
          start_column: 7
          end_column: 18
        classifications:
          - test
      instances_url: https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/4/instances
```

### Shape of A CodeScanningAlerts Fact Check

The shape of a `CodeScanningAlerts` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `CodeScanningAlerts` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: no_open_code_scanning_alerts
      rule:
        factRef: github:default/code_scanning_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
    - id: no_dismissed_critical_code_scanning_alerts
      rule:
        factRef: github:default/codeql_dismissed_critical_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck CodeScanningAlerts Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub CodeScanningAlerts Fact Collector
      checks:
        - id: no_open_code_scanning_alerts
          name: No open code scanning alerts
          description: No open code scanning alerts
        - id: no_dismissed_critical_code_scanning_alerts
          name: No dismissed critical code scanning alerts
          description: No dismissed critical code scanning alerts
```

## Collecting DependabotAlerts Fact

The `DependabotAlerts` fact contains information about dependabot alerts for a GitHub repository.

Prerequisites:

1. In order to be able to collect dependabot alerts you must enable them in GitHub, refer to the [GitHub Dependabot documentation](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/configuring-dependabot-alerts#enabling-or-disabling-dependabot-alerts-for-a-repository).
2. Grant your GitHub app or access token with necessary permissions listed in the [List Dependabot alerts for a repository](https://docs.github.com/en/rest/dependabot/alerts#list-dependabot-alerts-for-a-repository) GitHub API documentation.

<Note>
  This is a sensitive fact. See [docs](../index#sensitive-facts)for more
  details.
</Note>

### Shape of A DependabotAlerts Fact Collector

The shape of a DependabotAlerts Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: DependabotAlerts`)
and supports additional configuration options:

#### `states` \[optional]

If specified, only dependabot alerts with these states will be returned.
Possible values: 'auto\_dismissed', 'dismissed', 'fixed', 'open'.

#### `severities` \[optional]

If specified, only dependabot alerts with these severities will be returned.
Possible values: 'low', 'medium', 'high', 'critical'.

The following is an example of the `DependabotAlerts` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: dependabot_alerts
    type: DependabotAlerts
    states:
      - open
  - factName: dependabot_dismissed_critical_alerts
    type: DependabotAlerts
    states:
      - dismissed
    severities:
      - critical
```

### Shape of A DependabotAlerts Fact

The shape of a `DependabotAlerts` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding dependabot alerts, refer to the [GitHub API documentation](https://docs.github.com/en/rest/dependabot/alerts#list-dependabot-alerts-for-a-repository).

The following is an example of the collected `DependabotAlerts` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/dependabot_alerts
entityRef: component:default/queue-proxy
timestamp: 2025-03-14T15:50+00Z
data:
  alerts:
    - number: 1
      state: open
      dependency:
        package:
          ecosystem: pip
          name: ansible
        manifest_path: path/to/requirements.txt
        scope: runtime
      security_advisory:
        ghsa_id: GHSA-8f4m-hccc-8qph
        cve_id: CVE-2021-20191
        summary: Insertion of Sensitive Information into Log File in ansible
        description: A flaw was found in ansible. Credentials, such as secrets, are being disclosed in console log by default and not protected by no_log feature when using those modules. An attacker can take advantage of this information to steal those credentials. The highest threat from this vulnerability is to data confidentiality.
        vulnerabilities:
          - package:
              ecosystem: pip
              name: ansible
            severity: medium
            vulnerable_version_range: '>= 2.9.0, < 2.9.18'
            first_patched_version:
              identifier: 2.9.18
          - package:
              ecosystem: pip
              name: ansible
            severity: medium
            vulnerable_version_range: '< 2.8.19'
            first_patched_version:
              identifier: 2.8.19
          - package:
              ecosystem: pip
              name: ansible
            severity: medium
            vulnerable_version_range: '>= 2.10.0, < 2.10.7'
            first_patched_version:
              identifier: 2.10.7
        severity: medium
        cvss:
          vector_string: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
          score: 5.5
        cvss_severities:
          cvss_v3:
            vector_string: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
            score: 5.5
          cvss_v4:
            vector_string: CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
            score: 8.5
        cwes:
          - cwe_id: CWE-532
            name: Insertion of Sensitive Information into Log File
        identifiers:
          - type: GHSA
            value: GHSA-8f4m-hccc-8qph
          - type: CVE
            value: CVE-2021-20191
        references:
          - url: https://nvd.nist.gov/vuln/detail/CVE-2021-20191
          - url: https://access.redhat.com/security/cve/cve-2021-20191
          - url: https://bugzilla.redhat.com/show_bug.cgi?id=1916813
        published_at: 2021-06-01T17:38:00Z
        updated_at: 2021-08-12T23:06:00Z
        withdrawn_at: null
      security_vulnerability:
        package:
          ecosystem: pip
          name: ansible
        severity: medium
        vulnerable_version_range: '< 2.8.19'
        first_patched_version:
          identifier: 2.8.19
      url: https://api.github.com/repos/octocat/hello-world/dependabot/alerts/1
      html_url: https://github.com/octocat/hello-world/security/dependabot/1
      created_at: 2022-06-14T15:21:52Z
      updated_at: 2022-06-14T15:21:52Z
      dismissed_at: null
      dismissed_by: null
      dismissed_reason: null
      dismissed_comment: null
      fixed_at: null
```

### Shape of A DependabotAlerts Fact Check

The shape of a `DependabotAlerts` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `DependabotAlerts` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: no_open_dependabot_alerts
      rule:
        factRef: github:default/dependabot_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
    - id: no_dismissed_critical_dependabot_alerts
      rule:
        factRef: github:default/dependabot_dismissed_critical_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck DependabotAlerts Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub DependabotAlerts Fact Collector
      checks:
        - id: no_open_dependabot_alerts
          name: No open dependabot alerts
          description: No open dependabot alerts
        - id: no_dismissed_critical_dependabot_alerts
          name: No dismissed critical dependabot alerts
          description: No dismissed critical dependabot alerts
```

## Collecting RepositoryDetails Fact

The `RepositoryDetails` fact contains information about a GitHub repository.

Prerequisites:

* Grant your GitHub app or access token with necessary permissions listed in the [Get a repository](https://docs.github.com/en/rest/repos/repos#get-a-repository) GitHub API documentation.

### Shape of A RepositoryDetails Fact Collector

The shape of a `RepositoryDetails` Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: RepositoryDetails`).

The following is an example of the `RepositoryDetails` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: repository_details
    type: RepositoryDetails
    frequency:
      cron: '0 * * * *'
    filter:
      - spec.lifecycle: 'production'
    cache: true
```

### Shape of A RepositoryDetails Fact

The shape of a `RepositoryDetails` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected about repository, refer to the [GitHub API documentation](https://docs.github.com/en/rest/repos/repos#get-a-repository).

The following is an example of the collected `RepositoryDetails` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/repository_details
entityRef: component:default/queue-proxy
timestamp: 2023-02-24T15:50+00Z
data:
  name: backstage
  full_name: backstage/backstage
  private: true
  html_url: 'https://github.com/backstage/backstage'
  description: null
  fork: false
  url: 'https://api.github.com/repos/backstage/backstage'
  homepage: null
  size: 3
  stargazers_count: 0
  watchers_count: 0
  language: null
  has_issues: true
  has_projects: true
  has_downloads: true
  has_wiki: true
  has_pages: false
  has_discussions: false
  forks_count: 0
  mirror_url: null
  archived: false
  disabled: false
  open_issues_count: 0
  license: null
  allow_forking: true
  is_template: false
  web_commit_signoff_required: false
  visibility: 'private'
  forks: 0
  open_issues: 0
  watchers: 0
  default_branch: main
  permissions:
    admin: true
    maintain: true
    push: true
    triage: true
    pull: true
  allow_squash_merge: true
  allow_merge_commit: true
  allow_rebase_merge: true
  allow_auto_merge: false
  delete_branch_on_merge: false
  allow_update_branch: false
  use_squash_pr_title_as_default: false
  squash_merge_commit_message: 'COMMIT_MESSAGES'
  squash_merge_commit_title: 'COMMIT_OR_PR_TITLE'
  merge_commit_message: 'PR_TITLE'
  merge_commit_title: 'MERGE_MESSAGE'
  security_and_analysis:
    secret_scanning:
      status: 'disabled'
    secret_scanning_push_protection:
      status: 'disabled'
  network_count: 0
  subscribers_count: 1
```

### Shape of A RepositoryDetails Fact Check

The shape of a `RepositoryDetails` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `RepositoryDetails` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: allows_rebase_merge
      rule:
        factRef: github:default/repository_details
        path: $.allow_rebase_merge
        operator: equal
        value: true
    - id: has_less_than_ten_open_issues
      rule:
        factRef: github:default/repository_details
        path: $.open_issues
        operator: lessThan
        value: 10
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck RepositoryDetails Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub RepositoryDetails Fact Collector
      checks:
        - id: allows_rebase_merge
          name: Allows Rebase Merge
          description: Repository allows rebase merge
        - id: has_less_than_ten_open_issues
          name: Has Less Than 10 Open Issues
          description: GitHub Repository Has Less Than 10 Open Issues
```

## Collecting RepositoryLanguages Fact

The `RepositoryLanguages` fact contains information about languages used in a GitHub repository.

Prerequisites:

* Grant your GitHub app or access token with necessary permissions listed in the [List repository languages](https://docs.github.com/en/rest/repos/repos#list-repository-languages) GitHub API documentation.

### Shape of A RepositoryLanguages Fact Collector

The shape of a `RepositoryLanguages` Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: RepositoryLanguages`).

The following is an example of the `RepositoryLanguages` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: repository_languages
    type: RepositoryLanguages
    frequency:
      cron: '0 * * * *'
    filter:
      - spec.lifecycle: 'production'
    cache: true
```

### Shape of A RepositoryLanguages Fact

The shape of a `RepositoryLanguages` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected about repository languages, refer to the [GitHub API documentation](https://docs.github.com/en/rest/repos/repos#list-repository-languages).

The following is an example of the collected `RepositoryLanguages` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/repository_languages
entityRef: component:default/queue-proxy
timestamp: 2023-02-24T15:50+00Z
data:
  C: 78769
  Python: 7769
```

### Shape of A RepositoryLanguages Fact Check

The shape of a `RepositoryLanguages` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `RepositoryLanguages` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: uses_python
      rule:
        factRef: github:default/repository_languages
        path: $.Python
        operator: greaterThan
        value: 0
    - id: uses_java
      rule:
        factRef: github:default/repository_languages
        path: $.Java
        operator: greaterThan
        value: 0
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck RepositoryLanguages Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub RepositoryLanguages Fact Collector
      checks:
        - id: uses_python
          name: Uses Python
          description: Uses Python
        - id: uses_java
          name: Uses Java
          description: Uses Java
```

## Collecting SecretScanningAlerts Fact

The `SecretScanningAlerts` fact contains information about secret scanning alerts for a GitHub repository.

Prerequisites:

1. In order to be able to collect secret scanning alerts you must enable them in GitHub, refer to the [GitHub Secret Scanning documentation](https://docs.github.com/en/code-security/secret-scanning/enabling-secret-scanning-features/enabling-secret-scanning-for-your-repository).
2. Grant your GitHub app or access token with necessary permissions listed in the [List secret scanning alerts for a repository](https://docs.github.com/en/rest/secret-scanning/secret-scanning#list-secret-scanning-alerts-for-a-repository) GitHub API documentation.

<Note>
  This is a sensitive fact. See [docs](../index#sensitive-facts)for more
  details.
</Note>

### Shape of A SecretScanningAlerts Fact Collector

The shape of a CodeScanningAlerts Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: SecretScanningAlerts`)
and supports additional configuration options:

#### `state` \[optional]

If specified, only secret scanning alerts with this state will be returned.
Can be one of: 'open', 'resolved'.

#### `validities` \[optional]

If specified, only code scanning alerts with these validities will be returned.
Possible values: 'active', 'inactive', 'unknown'.

The following is an example of the `SecretScanningAlerts` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: secret_scanning_alerts
    type: SecretScanningAlerts
    state: open
  - factName: secret_scanning_active_alerts
    type: SecretScanningAlerts
    validities:
      - active
      - unknown
```

### Shape of A SecretScanningAlerts Fact

The shape of a `SecretScanningAlerts` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding secret scanning alerts, refer to the [GitHub API documentation](https://docs.github.com/en/rest/secret-scanning/secret-scanning#list-secret-scanning-alerts-for-a-repository).

The following is an example of the collected `SecretScanningAlerts` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/code_scanning_alerts
entityRef: component:default/queue-proxy
timestamp: 2025-03-14T15:50+00Z
data:
  alerts:
    - number: 1
      created_at: 2020-11-06T18:18:30Z
      url: https://api.github.com/repos/owner/repo/secret-scanning/alerts/1
      html_url: https://github.com/owner/repo/security/secret-scanning/1
      locations_url: https://api.github.com/repos/owner/private-repo/secret-scanning/alerts/1/locations
      state: open
      resolution: null
      resolved_at: null
      resolved_by: null
      secret_type: mailchimp_api_key
      secret_type_display_name: Mailchimp API Key
      secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us2
      push_protection_bypassed_by: null
      push_protection_bypassed: false
      push_protection_bypassed_at: null
      push_protection_bypass_request_reviewer: null
      push_protection_bypass_request_reviewer_comment: null
      push_protection_bypass_request_comment: null
      push_protection_bypass_request_html_url: null
      resolution_comment: null
      validity: unknown
      publicly_leaked: false
      multi_repo: false
```

### Shape of A SecretScanningAlerts Fact Check

The shape of a `SecretScanningAlerts` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `SecretScanningAlerts` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: no_open_secret_scanning_alerts
      rule:
        factRef: github:default/secret_scanning_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
    - id: no_active_secret_scanning_alerts
      rule:
        factRef: github:default/secret_scanning_active_alerts
        path: $.alerts
        operator: hasLengthOf
        value: 0
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck SecretScanningAlerts Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub SecretScanningAlerts Fact Collector
      checks:
        - id: no_open_secret_scanning_alerts
          name: No open secret scanning alerts
          description: No open secret scanning alerts
        - id: no_active_secret_scanning_alerts
          name: No active secret scanning alerts
          description: No active secret scanning alerts
```

## Collecting SecurityAdvisories Fact

The `SecurityAdvisories` fact contains information about security advisories in a GitHub repository.

Prerequisites:

* Grant your GitHub app or access token with necessary permissions listed in the [List repository security advisories](https://docs.github.com/en/rest/security-advisories/repository-advisories#list-repository-security-advisories) GitHub API documentation.

### Shape of A SecurityAdvisories Fact Collector

The shape of a SecurityAdvisories Fact Collector matches the [Overall Shape Of A Fact Collector](#overall-shape-of-a-fact-collector) (restriction: `type: SecurityAdvisories`)
and supports additional configuration options:

#### `state` \[optional]

If specified, only security advisories with this state will be returned.
Can be one of: 'triage', 'draft', 'published', 'closed'.

The following is an example of the `SecurityAdvisories` Fact Collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
collects:
  - factName: security_advisories
    type: SecurityAdvisories
    state: published
  - factName: all_security_advisories
    type: SecurityAdvisories
```

### Shape of A SecurityAdvisories Fact

The shape of a `SecurityAdvisories` Fact is based on the [Fact Schema](#overall-shape-of-a-github-fact-collector).

For a description of the data collected regarding security advisories, refer to the [GitHub API documentation](https://docs.github.com/en/rest/security-advisories/repository-advisories#list-repository-security-advisories).

The following is an example of the collected `SecurityAdvisories` fact:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
factRef: github:default/security_advisories
entityRef: component:default/queue-proxy
timestamp: 2025-03-14T15:50+00Z
data:
  advisories:
    - ghsa_id: GHSA-abcd-1234-efgh
      cve_id: CVE-2050-00000
      url: https://api.github.com/repos/repo/a-package/security-advisories/GHSA-abcd-1234-efgh
      html_url: https://github.com/repo/a-package/security/advisories/GHSA-abcd-1234-efgh
      summary: A short summary of the advisory.
      description: A detailed description of what the advisory entails.
      severity: critical
      author:
        login: octocat
        id: 1
        node_id: MDQ6VXNlcjE=
        avatar_url: https://github.com/images/error/octocat_happy.gif
        gravatar_id:
        url: https://api.github.com/users/octocat
        html_url: https://github.com/octocat
        followers_url: https://api.github.com/users/octocat/followers
        following_url: https://api.github.com/users/octocat/following{/other_user}
        gists_url: https://api.github.com/users/octocat/gists{/gist_id}
        starred_url: https://api.github.com/users/octocat/starred{/owner}{/repo}
        subscriptions_url: https://api.github.com/users/octocat/subscriptions
        organizations_url: https://api.github.com/users/octocat/orgs
        repos_url: https://api.github.com/users/octocat/repos
        events_url: https://api.github.com/users/octocat/events{/privacy}
        received_events_url: https://api.github.com/users/octocat/received_events
        type: User
        site_admin: false
      publisher:
        login: octocat
        id: 1
        node_id: MDQ6VXNlcjE=
        avatar_url: https://github.com/images/error/octocat_happy.gif
        gravatar_id:
        url: https://api.github.com/users/octocat
        html_url: https://github.com/octocat
        followers_url: https://api.github.com/users/octocat/followers
        following_url: https://api.github.com/users/octocat/following{/other_user}
        gists_url: https://api.github.com/users/octocat/gists{/gist_id}
        starred_url: https://api.github.com/users/octocat/starred{/owner}{/repo}
        subscriptions_url: https://api.github.com/users/octocat/subscriptions
        organizations_url: https://api.github.com/users/octocat/orgs
        repos_url: https://api.github.com/users/octocat/repos
        events_url: https://api.github.com/users/octocat/events{/privacy}
        received_events_url: https://api.github.com/users/octocat/received_events
        type: User
        site_admin: false
      identifiers:
        - type: GHSA
          value: GHSA-abcd-1234-efgh
        - type: CVE
          value: CVE-2050-00000
      state: published
      created_at: 2020-01-01T00:00:00Z
      updated_at: 2020-01-02T00:00:00Z
      published_at: 2020-01-03T00:00:00Z
      closed_at: null
      withdrawn_at: null
      submission: null
      vulnerabilities:
        - package:
            ecosystem: pip
            name: a-package
          vulnerable_version_range: '>= 1.0.0, < 1.0.1'
          patched_versions: 1.0.1
          vulnerable_functions:
            - function1
        - package:
            ecosystem: pip
            name: another-package
          vulnerable_version_range: '>= 1.0.0, < 1.0.2'
          patched_versions: 1.0.2
          vulnerable_functions:
            - function2
      cvss:
        vector_string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
        score: 9.8
      cvss_severities:
        cvss_v3:
          vector_string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
          score: 9.8
        cvss_v4:
          vector_string: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
          score: 9.3
      cwes:
        - cwe_id: CWE-123
          name: A CWE
      cwe_ids:
        - CWE-123
      credits:
        - login: octocat
          type: analyst
      credits_detailed:
        - user:
            login: octocat
            id: 1
            node_id: MDQ6VXNlcjE=
            avatar_url: https://github.com/images/error/octocat_happy.gif
            gravatar_id:
            url: https://api.github.com/users/octocat
            html_url: https://github.com/octocat
            followers_url: https://api.github.com/users/octocat/followers
            following_url: https://api.github.com/users/octocat/following{/other_user}
            gists_url: https://api.github.com/users/octocat/gists{/gist_id}
            starred_url: https://api.github.com/users/octocat/starred{/owner}{/repo}
            subscriptions_url: https://api.github.com/users/octocat/subscriptions
            organizations_url: https://api.github.com/users/octocat/orgs
            repos_url: https://api.github.com/users/octocat/repos
            events_url: https://api.github.com/users/octocat/events{/privacy}
            received_events_url: https://api.github.com/users/octocat/received_events
            type: User
            site_admin: false
          type: analyst
          state: accepted
      collaborating_users:
        - login: octokitten
          id: 1
          node_id: MDQ6VXNlcjE=
          avatar_url: https://github.com/images/error/octokitten_happy.gif
          gravatar_id:
          url: https://api.github.com/users/octokitten
          html_url: https://github.com/octokitten
          followers_url: https://api.github.com/users/octokitten/followers
          following_url: https://api.github.com/users/octokitten/following{/other_user}
          gists_url: https://api.github.com/users/octokitten/gists{/gist_id}
          starred_url: https://api.github.com/users/octokitten/starred{/owner}{/repo}
          subscriptions_url: https://api.github.com/users/octokitten/subscriptions
          organizations_url: https://api.github.com/users/octokitten/orgs
          repos_url: https://api.github.com/users/octokitten/repos
          events_url: https://api.github.com/users/octokitten/events{/privacy}
          received_events_url: https://api.github.com/users/octokitten/received_events
          type: User
          site_admin: false
      collaborating_teams:
        - name: Justice League
          id: 1
          node_id: MDQ6VGVhbTE=
          slug: justice-league
          description: A great team.
          privacy: closed
          notification_setting: notifications_enabled
          url: https://api.github.com/teams/1
          html_url: https://github.com/orgs/github/teams/justice-league
          members_url: https://api.github.com/teams/1/members{/member}
          repositories_url: https://api.github.com/teams/1/repos
          permission: admin
          parent: null
      private_fork: null
```

### Shape of A SecurityAdvisories Fact Check

The shape of a `SecurityAdvisories` Fact Check matches the [Shape of a Fact Check](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/checks#overall-shape-of-a-check).

The following is an example of the `SecurityAdvisories` fact checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  checks:
    - id: no_critical_security_advisories_published
      rule:
        factRef: github:default/security_advisories
        path: $.advisories[?(@.severity === 'critical')]
        operator: hasLengthOf
        value: 0
```

The following is an example of the Soundcheck track that utilizes these checks:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
- id: demo
  name: Demo
  ownerEntityRef: group:default/owning_group
  description: Demonstration of Soundcheck SecurityAdvisories Fact Collector
  levels:
    - ordinal: 1
      name: First level
      description: Checks leveraging Soundcheck's GitHub SecurityAdvisories Fact Collector
      checks:
        - id: no_critical_security_advisories_published
          name: No critical security advisories published
          description: No critical security advisories published
```

## Appendix

### Recommended GitHub Settings Fact Collector

Pre-built `Recommended GitHub Settings` checks are based on the following collector configuration:

```yaml theme={"theme":{"light":"github-light","dark":"dracula"}}
soundcheck:
  collectors:
    github:
      collects:
        - factName: branch_protections
          type: BranchProtections
          filter:
            - kind:
                - component
          cache:
            duration:
              hours: 24
          frequency:
            cron: '0 1 * * *'

        - factName: repository_details
          type: RepositoryDetails
          filter:
            - kind:
                - component
          cache:
            duration:
              hours: 24
          frequency:
            cron: '0 5 * * *'
```
