{"id":46069410,"url":"https://github.com/divd-nl/cna-bot","last_synced_at":"2026-03-01T13:01:40.648Z","repository":{"id":62878515,"uuid":"560973121","full_name":"DIVD-NL/cna-bot","owner":"DIVD-NL","description":"GitHub action to validate and submit CVE entries using cvelib, cvelint and cve service.","archived":false,"fork":false,"pushed_at":"2025-11-11T08:51:19.000Z","size":262,"stargazers_count":5,"open_issues_count":4,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-02-12T15:42:58.913Z","etag":null,"topics":["cve","security"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/cve-cna-bot","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DIVD-NL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-02T16:58:21.000Z","updated_at":"2025-11-11T08:48:27.000Z","dependencies_parsed_at":"2023-12-11T11:48:58.313Z","dependency_job_id":"9509f865-464a-4a2b-a67f-a47f537055ac","html_url":"https://github.com/DIVD-NL/cna-bot","commit_stats":{"total_commits":94,"total_committers":4,"mean_commits":23.5,"dds":0.4148936170212766,"last_synced_commit":"1899a33aeb8fca2db55c1c4641d55d26bba703cb"},"previous_names":["divd-nl/cve-rsus-validate-submit"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/DIVD-NL/cna-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DIVD-NL%2Fcna-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DIVD-NL%2Fcna-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DIVD-NL%2Fcna-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DIVD-NL%2Fcna-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DIVD-NL","download_url":"https://codeload.github.com/DIVD-NL/cna-bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DIVD-NL%2Fcna-bot/sbom","scorecard":{"id":35371,"data":{"date":"2025-08-11","repo":{"name":"github.com/DIVD-NL/cna-bot","commit":"b853b831c2f457af466056a5a83f070e21ba8c2b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/8 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/DIVD-NL/cna-bot/main.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:2: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: pipCommand not pinned by hash: Dockerfile:5","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","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"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T20:10:53.346Z","repository_id":62878515,"created_at":"2025-08-14T20:10:53.352Z","updated_at":"2025-08-14T20:10:53.352Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29969700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T12:56:10.327Z","status":"ssl_error","status_checked_at":"2026-03-01T12:55:24.744Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cve","security"],"created_at":"2026-03-01T13:01:40.011Z","updated_at":"2026-03-01T13:01:40.637Z","avatar_url":"https://github.com/DIVD-NL.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CNA Bot\n\nThis GitHub action validates CVE JSON 5.0 format records and (optionally) submits them to the CVE RSUS service.\n\n## Inputs\n\n### `cve-user`\n\n**Required** CVE services user name (usually the email address)\n\n### `cve-org`\n\n**Required** CVE services organisation\n\n### `cve-api-key`\n\n**Required** CVE services api key (Please store this in a GitHub secret)\n\n### `cve-environment`\n\n**Required** CVE services environment (defaults to test)\n\n### `publish`\n\nSet to `true` to publish the records to the CVE services (defaults to false)\n\n### `path`\n\nPath to find CVE records in. Any \\*.json file in this directory is considered a CVE record (defaults to `.`)\n\n## `reservations-path`\n\nPath to find CVE ID reservations in. Any \\*.json file in this directory is considered a CVE ID reservation (defaults to `\u003cpath\u003e/reservations`)\n\n### `ignore`\n\nComma separted list of checks to ignore.\n\n### `pr`\n\nCreate a pull request to bring local records in line with remote records (defaults to `false`)\n\n### `github-token`\n\nA github token to be used by this action. Default ` `. Recommended value: ${{ secrets.GITHUB_TOKEN }}\n\nIf you want github actions to run on pull requests created by this action you will have to use a personal Github Access token with at least the `repo` and `org:read` scopes and grant the bot write access to the repo.\n\n### `reserve`\n\nMinimum number of records to reserve in one go (0=do not make reservations). This parameter defaults to 0 because maintaining a \"stockpile\" of CVE IDs is discouraged.\n\n### `min-reserved`\n\nMinimum number of reserved records for the current year.\n\nAction will fail if the number of records in RESERVED state drops below this amount. If `reserve` is set to a number above 0 this action will reserve this many new records.\n\n### `expire-after`\n\nCreate pull request (if `pr` is set to `true`) to expire reservations this much time after the end of the year.\nExample values are:\n* `4d` for 4 days, reservations will expire on or after 5 Jan\n* `3w` for 4 weeks, reservations will expire on or after 15 Jan\n* `2m` for 2 months, reservations will expire on or after 1 Mar\n* `1y` for 1 year, reserveration will expire on or after 1 Jan for reservations before the previous year\n\n### `skip-cve-lint`\n\nSet to `true` to skip running cvelint validation checks. (Defaults to `false`)\nThis is useful when you want to bypass the cvelint validation step, for example during testing or when using custom validation workflows.\n\n### `verbose`\n\nSet to true to increase the output levels. (Defaults to `false`)\n\n### `quiet`\n\nSet to true to output only the minimul output. (Defaults to `false`)\nIf both `verbose` and `quiet` are set, `quiet` wins\n\n## Versions\n\nFor the stable version use `DIVD-NL/cna-bot@v1` (recommended)\n\nFor the current beta version use `DIVD-NL/cna-bot@v1.4`\n\n## Example usage\n\nSee: https://github.com/DIVD-NL/cna-admin-test\n\nIn this repo the CVE records are in `./records` and it has this workflow configuration\n\n```yml\n# test_and_update_cve_records.yml\non:\n  push:\n    branches:\n      - 'main'\n  pull_request:\n    branches:\n      - 'main'\n  schedule:\n    - cron: \"5 4 * * *\" #  This should be changed to another cron value.\n\n\njobs:\n  test_and_update_cve_records:\n    runs-on: ubuntu-latest\n    steps:\n      # Get the repository's code\n      - name: Checkout\n        uses: actions/checkout@v3\n      # Check CVE records and publish them    \n      - name: CVE RSUS check and upload\n        uses: DIVD-NL/cna-bot@v1\n        with: \n          cve-user          : ${{ secrets.CVE_USER }}\n          cve-org           : ${{ secrets.CVE_ORG }}\n          cve-api-key       : ${{ secrets.CVE_API_KEY }}\n          cve-environment   : test                                        # Change to prod for actual use\n          publish           : ${{ github.ref == 'refs/heads/main' }}      # Only publish when we merge into the main branch\n          path              : records                                     # This is where the CVE records live\n          reservations-path : records/reservations                        # This is where reservation CVE IDs live\n          ignore            : \"\"                                          # Don't ignore any checks\n          min-reserved      : 0                                           # Don't pre-reserve records\n          reserve           : 0                                           # Don't pre-reserve records \n          pr                : ${{ github.event_name != 'pull_request' }}  # Create a PR when we push or run on schedule\n          github-token      : ${{ secrets.GITHUB_TOKEN }}          \n          expire-after      : \"1y\"\n\n```\n\n### Usage with a GitHub App\n\nInstead of using a Personal Access Token, a GitHub App can be used. This is\nadvantagus since all the pull requests are created in the name of the App and\nnot a personal account.\n\n**Steps:**\n\n1. [Register new GitHub App](https://docs.github.com/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app)\n2. [Store the App's ID in your repository environment variables](https://docs.github.com/actions/learn-github-actions/variables#defining-configuration-variables-for-multiple-workflows) (example: `APP_ID`)\n3. [Store the App's private key in your repository secrets](https://docs.github.com/actions/security-guides/encrypted-secrets?tool=webui#creating-encrypted-secrets-for-a-repository) (example: `PRIVATE_KEY`)\n4. [Install the App for your Organization](https://docs.github.com/en/apps/using-github-apps/installing-your-own-github-app)\n\n```yml\n# test_and_update_cve_records.yml\non:\n  push:\n    branches:\n      - 'main'\n  pull_request:\n    branches:\n      - 'main'\n  schedule:\n    - cron: \"5 4 * * *\" #  This should be changed to another cron value.\n\n\njobs:\n  test_and_update_cve_records:\n    runs-on: ubuntu-latest\n    steps:\n      # Get the repository's code\n      - name: Checkout\n        uses: actions/checkout@v3\n      # Request Token via App Credentials\n      - uses: actions/create-github-app-token@v1\n        id: app-token\n        with:\n          app-id: ${{ vars.APP_ID }}\n          private-key: ${{ secrets.PRIVATE_KEY }}\n      # Check CVE records and publish them\n      - name: CVE RSUS check and upload\n        uses: DIVD-NL/cna-bot@v1\n        with:\n          # ...\n          github-token: ${{ steps.app-token.outputs.token }} # Use token from `app-token` step\n\n```\n\n## reservations.lock\n\nThe `reservations.lock` file can be used to make sure reservations don't expire and to reserve CVE records. You can also use if for local administration.\n\n### Preventing expiration\n\nYou can CVE ID reservations from automatic expiry to do this you can create one or more `reservation.lock` files anywhere in the `reservations-path`. You must include one CVE ID per line and `#` style comments are allowed.\n\n### Reserving new CVE ids\n\nIn order to reserve a record you can add special lines to the `reservations.lock` file. E.g.\n\n```\nNEW-CVE-2024     # Reserves a single CVE id in the year 2024\nNEW-CVES-2025-12 # Reserves a sequential block of 12 CVEs for 2025\n```\n\nWhen these lines are encountered a number of things will happen\n* The number of records in the year will be requested via the CVE services api\n* Reservation records will we written in the same directory the `reservations.lock` file is in\n* The `reservations.lock` file will be updated to contain the newly reserved CVE IDs\n\n### Local administration\n\nYou can also use this file for some local administration.\n\nE.g.\n```\n# reservations.lock\n\n# DIVD-2010-00001\n# Owner: Frank\nCVE-2010-66666  # Ticket: 1245\nCVE-2010-66667  # Ticket: 1246\n\n# DIVD-2010-00002\nCVE-2010-66668  # Ticket: 1249\nCVE-2010-66669  # Ticket: 1250\n```\n\n\n## Detailed explanation\nI will explain each part of the workflow, in detail\n\n\nWe will run this workflow on pull requests agains main and on pushes to the main branch and run at 4:05 at night.\n```yml\n# test_and_update_cve_records.yml\non:\n  push:\n    branches:\n      - 'main'\n  pull_request:\n    branches:\n      - 'main'\n  schedule:\n    - cron: \"5 4 * * *\"\n```\n\nThe we need to check out the code\n\n```yml\njobs:\n  test_and_update_cve_records:\n    runs-on: ubuntu-latest\n    steps:\n      # Get the repository's code\n      - name: Checkout\n        uses: actions/checkout@v2\n```yml\n\nAfter the code is checkout out, we are going to test the CVE records\n\n\n```yml\n      # Check CVE records and publish them    \n      - name: CVE RSUS check and upload\n        uses: DIVD-NL/cna-bot@v1\n```\n\nThe iputs that start with cve- are our CVE credentials to log in. We suggest you store these in your github secrets\n\n\n```yml\n        with: \n          cve-user        : ${{ secrets.CVE_USER }}\n          cve-org         : ${{ secrets.CVE_ORG }}\n          cve-api-key     : ${{ secrets.CVE_API_KEY }}\n          cve-environment : test                                      # Change to prod for actual use\n```\n\nNext we want to instruct the action to only publish.update records if we have merged them into main.\n```yml\n          publish         : ${{ github.ref == 'refs/heads/main' }}    # Only publish when we merge into the main branch\n```\n\nWe need to tell the action where our records live.\n```yml\n          path            : records/                                  # This is where the CVE records live\n```\n\nWith this option we can ignore certain check, e.g. set it to `published_in_path` if you don't wat to check that each published CVE has a record in this directory.\n```yml\n          ignore          : \"\"                                        # Don't ignore any checks\n```\n\n\nIf the remote record does not match the local record, create a pull reuqest to update the local records. These changes should mostly be about metadata and to incorporate CVE ID reservations into your repo.\n```yml\n          pr              : ${{ github.event_name != 'pull_request' }}  # Create a PR when we push or run on schedule\n          github-token:     ${{ secrets.GITHUB_TOKEN }}          \n```\n\nNote: If you want github actions to run on pull requests created by this action you will have to use either a personal Github Access token or a GitHub app token with at least the `repo`, `org:read` and `discussion:read` scopes.\n\nThe parameters below control CVE record pre-reservation. `min-reserved` sets the minimum number of available CVE records to keep in stock for the (current) year. If the number of reserved records drops below this threshold the action will fail, or reserve more CVE IDs depending on the setting of `reserve`.\nIf `reserve` is set to a positive number, the action will reserve this number of records. If more records are needed to go back the the minimum, this ammount will be reserved instead.\n\n\n```yml\n          min-reserved      : 0                                           # Don't pre-reserve records\n          reserve           : 0                                           # Don't pre-reserve records\n```\nPlease note: pre-reservation of records is *not considered best practise*. These values are set to 0 by default. Instead use the `NEW-CVE-yyyy` or `NEW-CVES-yyyy-nn` syntax in `reservation.lock` files for just in time reservation of records.\n\n```yml\n          expire-after    : \"1y\"\n```\nIf we have reservations of 1 year before last year, in the state `RESERVED`, then automatically create a pull-request to set them to `REJECTED`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdivd-nl%2Fcna-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdivd-nl%2Fcna-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdivd-nl%2Fcna-bot/lists"}