{"id":18488317,"url":"https://github.com/NodeSecure/ci","last_synced_at":"2025-04-08T20:33:01.239Z","repository":{"id":37964973,"uuid":"438778250","full_name":"NodeSecure/ci","owner":"NodeSecure","description":"NodeSecure tool enabling secured continuous integration","archived":false,"fork":false,"pushed_at":"2025-03-01T19:18:18.000Z","size":459,"stargazers_count":21,"open_issues_count":4,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-19T17:42:53.538Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NodeSecure.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-15T21:29:35.000Z","updated_at":"2025-01-22T09:34:45.000Z","dependencies_parsed_at":"2024-01-21T22:55:22.977Z","dependency_job_id":"256eb90e-65b7-46e4-8faf-e752fb5f21c5","html_url":"https://github.com/NodeSecure/ci","commit_stats":{"total_commits":156,"total_committers":13,"mean_commits":12.0,"dds":0.3910256410256411,"last_synced_commit":"f749729571b6a6be6e611395fa3ce551942b285e"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NodeSecure%2Fci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NodeSecure%2Fci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NodeSecure%2Fci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NodeSecure%2Fci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NodeSecure","download_url":"https://codeload.github.com/NodeSecure/ci/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247923606,"owners_count":21019028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-06T12:51:33.197Z","updated_at":"2025-04-08T20:33:01.226Z","avatar_url":"https://github.com/NodeSecure.png","language":"TypeScript","readme":"# Secure Continuous Integration\n\n![ci-banner](https://user-images.githubusercontent.com/4438263/226020356-5790c025-bff1-40d5-b847-360863f53a9a.jpg)\n![version](https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge\u0026url=https://raw.githubusercontent.com/NodeSecure/ci/master/package.json\u0026query=$.version\u0026label=Version)\n[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=for-the-badge)](https://github.com/NodeSecure/ci/graphs/commit-activity)\n[![OpenSSF\nScorecard](https://api.securityscorecards.dev/projects/github.com/NodeSecure/ci/badge?style=for-the-badge)](https://api.securityscorecards.dev/projects/github.com/NodeSecure/ci)\n[![mit](https://img.shields.io/github/license/NodeSecure/ci.svg?style=for-the-badge)](https://github.com/NodeSecure/ci/blob/master/LICENSE)\n![build](https://img.shields.io/github/actions/workflow/status/NodeSecure/ci/node.js.yml?style=for-the-badge)\n\n## Installation\n\nThis package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).\n\n```bash\n$ npm i @nodesecure/ci\n# or\n$ yarn add @nodesecure/ci\n```\n\n## Getting Started\n\n@nodesecure/ci brings together a set of tools to identify dependencies vulnerabilities and track most common malicious code and patterns.\n\nBefore going further, here is an overview of the available features depending on your project configuration:\n\n| Static Analysis | Compatibility |\n| --------------- | ------------- |\n| JavaScript      | ✅            |\n| TypeScript      | ❌            |\n\nStatic Analysis is powered by [@nodesecure/js-x-ray](https://github.com/NodeSecure/js-x-ray) and [@nodesecure/scanner](https://github.com/NodeSecure/scanner).\n\n\u003e For now, TypeScript can't directly be analyzed on the fly. However as you might know, any transpiled TypeScript code is JavaScript code hence can be analyzed.\n\u003e Moreover, it is recommended to launch the Static Analysis with a source code state as\n\u003e close as possible to the state of your production code (and before minification).\n\u003e In fact, you want to make sure that you are not introducing anything malicious\n\u003e when you're compiling your code at some point (for production or when transpiling with TypeScript).\n\n| Vulnerabilities Strategy | package-lock.json | yarn.lock | npm-shrinkwrap.json | none |\n| ------------------------ | ----------------- | --------- | ------------------- | ---- |\n| npm                      | ✅                | ❌       | ✅                 | ❌  |\n| snyk                     | ✅                | ✅       | ✅                 | ✅  |\n| sonatype                 | ✅                | ✅       | ✅                 | ✅  |\n| [**DEPRECATED**] node    | ✅                | ✅       | ✅                 | ✅  |\n\nVulnerabilities strategies are powered by [@nodesecure/vulnera](https://github.com/NodeSecure/vulnera).\n\n## Usage example\n\n@nodesecure/ci can be used as a Script, as an API or [through the GitHub action](https://github.com/marketplace/actions/nodesecure-continuous-integration)\n\nLet's see how to use @nodesecure/ci in these three different ways:\n\n- API\n- Script\n- GitHub Action\n\n### API\n\n@nodesecure/ci exposes its pipeline runner as an API to allow use in any other combined workflow.\n\n```ts\nimport { runPipeline } from \"@nodesecure/ci\";\n\nconst optionsExample = {\n  directory: process.cwd(),\n  strategy: \"sonatype\",\n  vulnerabilities: \"medium\",\n  warnings: {\n    \"unsafe-regex\": \"error\",\n    \"obfuscated-code\": \"warning\",\n    \"encoded-literal\": \"off\"\n  },\n  reporters: [\"console\"]\n};\n\nawait runPipeline(optionsExample);\n// =\u003e the process can either exit with error code (1)\n// or no error code (0), depending on the pipeline status.\n```\n\nIf you need a more fine-grained control over the pipeline process, you can provide an **autoExitAfterFailure** property to the entry point options to manually exit or interpret the returned payload.\n\n```ts\nconst { status, data } = await runPipeline({ autoExitAfterFailure: false });\n\nif (status === \"success\") {\n  console.log(\"Congrats, your code passed all security checks!\");\n} else {\n  console.log(\"Whoops, the pipeline failed to pass all checks :(\");\n  // Interpret the data to explain why it failed\n}\n```\n\n---\n\n### Script\n\nFirst, reference the **nsci** .bin in the package.json\n\n```json\n{\n  \"scripts\": {\n    \"nsci\": \"nsci\"\n  }\n}\n```\n\nThen run it\n\n```bash\n$ npm run nsci\n```\n\nOnce the script is run, the @nodesecure/ci pipeline will look for dependencies warnings and vulnerabilities in the current working directory.\nIf any warning or dependency is met, the pipeline will eventually fail depending on the provided .nodesecurerc file.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/43391199/158816859-636dad37-e212-444b-beca-bda969dec205.gif\"\u003e\n\u003c/p\u003e\n\n---\n\n### GitHub Action\n\n[The documentation of the @nodesecure/ci GitHub Action is detailed here](https://github.com/marketplace/actions/nodesecure-continuous-integration)\n\n### Custom configuration\n\n#### .nodesecurerc (runtime configuration file)\n\nA custom configuration can now be provided using the brand new **.nodesecurerc** config file.\n\n\u003e **When a .nodesecurerc file is present in the project it will take priority over any other\n\u003e configuration provided (through the CLI or when using the API).**\n\nTo generate this file, the best way is to use the **init** command exposed by the CLI.\n\n```bash\n$ npm run nsci init\n```\n\nHere is the content of the **.nodesecurerc** file generated by default:\n\n```json\n{\n  \"version\": \"1.0.0\",\n  \"i18n\": \"english\",\n  \"strategy\": \"github-advisory\",\n  \"ci\": {\n    \"reporters\": [\"console\"],\n    \"vulnerabilities\": {\n      \"severity\": \"medium\"\n    },\n    \"warnings\": \"error\"\n  }\n}\n```\n\nIn the same way as for the other types of configuration (API/CLI), **warnings** can be specifically configured to enable a custom analysis. When you configure a custom **warnings** section, only the warnings specified in that section will be\nused by the runner.\n\n```json\n{\n  \"version\": \"1.0.0\",\n  \"i18n\": \"english\",\n  \"strategy\": \"github-advisory\",\n  \"ci\": {\n    \"reporters\": [\"console\"],\n    \"vulnerabilities\": {\n      \"severity\": \"medium\"\n    },\n    \"warnings\": {\n      \"unsafe-regex\": \"error\",\n      \"obfuscated-code\": \"warning\",\n      \"encoded-literal\": \"off\"\n    }\n  }\n}\n```\n\nIf you don't have the possibility to generate a **.nodesecurerc** file, there are three other configuration options left:\n\n- via the CLI when using as a script\n- via the API options when using the exposed Node.js module\n- via the .yaml config file for the [GitHub action](https://github.com/marketplace/actions/nodesecure-continuous-integration)\n\nThe idea is to provide same options for all types of configuration. Nevertheless for now, the specific way to set a **warnings** dictionary (other than \"error\" | \"warning\" | \"off\" options) is only available when using the **.nodesecurerc** or **API** configurations.\n\n#### .nodesecureignore (ignore file)\n\nDuring your NodeSecure journey it's possible that you'll find false positives. The `.nodesecureignore` is the perfect tool to address these cases.\n\nLet's say that you want to exclude `\"unsafe-regex\"` from `express`:\n\n1. Create your `.nodesecureignore` file at the root of your project\n\n2. Add the following JSON content:\n\n```json\n{\n  \"warnings\": {\n    \"unsafe-regex\": [\"express\"]\n  }\n}\n```\n\n3. Run your analysis as usual: no more `unsafe-regex` for `express` package.\n\n\u003e Found the list of warnings available [here](https://github.com/NodeSecure/js-x-ray#warnings)\n---\n\n#### CLI\n\nAdd CLI options directly in the package.json script\n\n```json\n{\n  \"scripts\": {\n    \"nsci\": \"nsci --directory=/Users/user1/myproject\"\n  }\n}\n```\n\nOr provide it from the \"npm run [script]\" command (don't forget to supply \"--\") or\nthe params will be applied to the \"npm run [script]\" command.\n\n```bash\n$ npm run nsci -- --directory=/Users/user1/myproject\n$ npm run nsci -- --strategy=npm\n$ npm run nsci -- --vulnerability=medium\n$ npm run nsci -- --warnings=error\n$ npm run nsci -- --reporters=console\n```\n\nOr use yarn (params are provided to the target script by default)\n\n```bash\n$ yarn nsci --reporters=console\n```\n\nTo see all available options, you can run:\n\n```bash\n$ npm run nsci -- --help\n```\n\n---\n\n#### API\n\n```ts\nimport { runPipeline } from \"@nodesecure/ci\";\n\nconst optionsExampleWithGlobalWarningsRule = {\n  directory: process.cwd(),\n  strategy: \"sonatype\",\n  vulnerabilities: \"medium\",\n  // any warning met will be reported as an \"error\" hence will make the pipeline fail\n  warnings: \"error\",\n  reporters: [\"console\"]\n};\n\nconst optionsExampleWithCustomWarningsRules = {\n  directory: process.cwd(),\n  strategy: \"sonatype\",\n  vulnerabilities: \"medium\",\n  /**\n   * Set custom rules for specific types of warnings.\n   * Only \"unsafe-regex\" warnings can make the pipeline fail.\n   * \"obfuscated-code\" warnings will be reported but ignored by the pipeline checks.\n   * \"encoded-literal\" is neither reported or included in the pipeline checks.\n   */\n  warnings: {\n    \"unsafe-regex\": \"error\",\n    \"obfuscated-code\": \"warning\",\n    \"encoded-literal\": \"off\"\n  },\n  reporters: [\"console\"]\n};\n\nawait runPipeline(optionsExample);\n// =\u003e the process can either exit with error code (1)\n// or no error code (0), depending on the pipeline checks status.\n```\n\n#### Mixing configurations when providing options from multiple sources\n\nGiven that it's possible to mix configurations between the one defined in **.nodesecurerc** and the one\ndefined either through the API or CLI, it is important to understand the order in which the options will be chosen.\n\n| Priority | Type of configuration                       |\n| -------- | ------------------------------------------- |\n| 1️⃣       | .nodesecurerc                               |\n| 2️⃣       | CLI or API (can't be both at the same time) |\n\nAnything **valid and defined** in the .nodesecurerc file will be used no matter what options are defined in the CLI or the API.\nHowever if anything is missing in the .nodesecurerc file, options provided from the CLI or API can naturally complete the runtime configuration.\n\n## Reporters\n\nTwo reporters are targeted to work with the @nodesecure/ci. For now,\nonly the \"Console\" reporter is available.\n\n- [x] Console\n- [ ] HTML\n\n## Requirements\n\n- [Node.js](https://nodejs.org/en/) v20 or higher\n\n## Contributors ✨\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/antoine-coulon\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/43391199?v=4?s=100\" width=\"100px;\" alt=\"Antoine\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAntoine\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/NodeSecure/ci/commits?author=antoine-coulon\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/NodeSecure/ci/commits?author=antoine-coulon\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-antoine-coulon\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://tonygo.dev\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/22824417?v=4?s=100\" width=\"100px;\" alt=\"Tony Gorez\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTony Gorez\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/NodeSecure/ci/commits?author=tony-go\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/NodeSecure/ci/commits?author=tony-go\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/PierreDemailly\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/39910767?v=4?s=100\" width=\"100px;\" alt=\"PierreD\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ePierreD\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/NodeSecure/ci/commits?author=PierreDemailly\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/NodeSecure/ci/commits?author=PierreDemailly\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-PierreDemailly\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.linkedin.com/in/thomas-gentilhomme/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/4438263?v=4?s=100\" width=\"100px;\" alt=\"Gentilhomme\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGentilhomme\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#maintenance-fraxken\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e \u003ca href=\"https://github.com/NodeSecure/ci/pulls?q=is%3Apr+reviewed-by%3Afraxken\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/fabnguess\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/72697416?v=4?s=100\" width=\"100px;\" alt=\"Kouadio Fabrice Nguessan\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKouadio Fabrice Nguessan\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#maintenance-fabnguess\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://sofiand.github.io/portfolio-client/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/39944043?v=4?s=100\" width=\"100px;\" alt=\"Yefis\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYefis\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#maintenance-SofianD\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/halcin\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/7302407?v=4?s=100\" width=\"100px;\" alt=\"halcin\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ehalcin\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/NodeSecure/ci/commits?author=halcin\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/Yaziidev\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/156483754?v=4?s=100\" width=\"100px;\" alt=\"Yaziidev\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYaziidev\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/NodeSecure/ci/commits?author=Yaziidev\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n## License\n\nMIT\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNodeSecure%2Fci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNodeSecure%2Fci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNodeSecure%2Fci/lists"}