Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/sec/analyzer_development_guide.md')
-rw-r--r--doc/development/sec/analyzer_development_guide.md185
1 files changed, 185 insertions, 0 deletions
diff --git a/doc/development/sec/analyzer_development_guide.md b/doc/development/sec/analyzer_development_guide.md
new file mode 100644
index 00000000000..a35bc2b7237
--- /dev/null
+++ b/doc/development/sec/analyzer_development_guide.md
@@ -0,0 +1,185 @@
+---
+stage: Secure
+group: Static Analysis
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Sec section analyzer development
+
+Analyzers are shipped as Docker images to execute within a CI pipeline context. This guide describes development and testing
+practices across analyzers.
+
+## Shared modules
+
+There are a number of shared Go modules shared across analyzers for common behavior and interfaces:
+
+- The [`command`](https://gitlab.com/gitlab-org/security-products/analyzers/command#how-to-use-the-library) Go package implements a CLI interface.
+- The [`common`](https://gitlab.com/gitlab-org/security-products/analyzers/common) project provides miscellaneous shared modules for logging, certificate handling, and directory search capabilities.
+- The [`report`](https://gitlab.com/gitlab-org/security-products/analyzers/report) Go package's `Report` and `Finding` structs marshal JSON reports.
+- The [`template`](https://gitlab.com/gitlab-org/security-products/analyzers/template) project scaffolds new analyzers.
+
+## How to use the analyzers
+
+Analyzers are shipped as Docker images. For example, to run the
+[semgrep](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) Docker image to scan the working directory:
+
+1. `cd` into the directory of the source code you want to scan.
+1. Run `docker login registry.gitlab.com` and provide username plus
+ [personal](../../user/profile/personal_access_tokens.md#create-a-personal-access-token)
+ or [project](../../user/project/settings/project_access_tokens.md#create-a-project-access-token)
+ access token with at least the `read_registry` scope.
+1. Run the Docker image:
+
+ ```shell
+ docker run \
+ --interactive --tty --rm \
+ --volume "$PWD":/tmp/app \
+ --env CI_PROJECT_DIR=/tmp/app \
+ -w /tmp/app \
+ registry.gitlab.com/gitlab-org/security-products/analyzers/semgrep:latest /analyzer run
+ ```
+
+1. The Docker container generates a report in the mounted project directory with a report filename corresponding to the analyzer category. For example, [SAST](../../user/application_security/sast) generates a file named `gl-sast-report.json`.
+
+## Analyzers development
+
+To update the analyzer:
+
+1. Modify the Go source code.
+1. Build a new Docker image.
+1. Run the analyzer against its test project.
+1. Compare the generated report with what's expected.
+
+Here's how to create a Docker image named `analyzer`:
+
+```shell
+docker build -t analyzer .
+```
+
+For example, to test Secret Detection run the following:
+
+```shell
+wget https://gitlab.com/gitlab-org/security-products/ci-templates/-/raw/master/scripts/compare_reports.sh
+sh ./compare_reports.sh sd test/fixtures/gl-secret-detection-report.json test/expect/gl-secret-detection-report.json \
+| patch -Np1 test/expect/gl-secret-detection-report.json && Git commit -m 'Update expectation' test/expect/gl-secret-detection-report.json
+rm compare_reports.sh
+```
+
+You can also compile the binary for your own environment and run it locally
+but `analyze` and `run` probably won't work
+since the runtime dependencies of the analyzer are missing.
+
+Here's an example based on
+[SpotBugs](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs):
+
+```shell
+go build -o analyzer
+./analyzer search test/fixtures
+./analyzer convert test/fixtures/app/spotbugsXml.Xml > ./gl-sast-report.json
+```
+
+## How to test the analyzers
+
+Video walkthrough of how Dependency Scanning analyzers are using [downstream pipeline](../../ci/pipelines/downstream_pipelines.md) feature to test analyzers using test projects:
+
+[![How Sec leverages the downstream pipeline feature of GitLab to test analyzers end to end](http://img.youtube.com/vi/KauRBlfUbDE/0.jpg)](http://www.youtube.com/watch?v=KauRBlfUbDE)
+
+### Testing local changes
+
+To test local changes in the shared modules (such as `command` or `report`) for an analyzer
+you can use the
+[`go mod replace`](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive)
+directive to load `command` with your local changes instead of using the version of command that has been
+tagged remotely. For example:
+
+```shell
+go mod edit -replace gitlab.com/gitlab-org/security-products/analyzers/command/v3=/local/path/to/command
+```
+
+Alternatively you can achieve the same result by manually updating the `go.mod` file:
+
+```plaintext
+module gitlab.com/gitlab-org/security-products/analyzers/awesome-analyzer/v2
+
+replace gitlab.com/gitlab-org/security-products/analyzers/command/v3 => /path/to/command
+
+require (
+ ...
+ gitlab.com/gitlab-org/security-products/analyzers/command/v3 v2.19.0
+)
+```
+
+#### Testing local changes in Docker
+
+To use Docker with `replace` in the `go.mod` file:
+
+1. Copy the contents of `command` into the directory of the analyzer. `cp -r /path/to/command path/to/analyzer/command`.
+1. Add a copy statement in the analyzer's `Dockerfile`: `COPY command /command`.
+1. Update the `replace` statement to make sure it matches the destination of the `COPY` statement in the step above:
+`replace gitlab.com/gitlab-org/security-products/analyzers/command/v3 => /command`
+
+## Versioning and release process
+
+Analyzers are independent projects that follow their own versioning. `Patch` version bumps tend to correspond to a `Minor` version bump of the underlying tools (i.e. [`bandit`](https://wiki.openstack.org/wiki/Security/Projects/Bandit)), allowing us greater flexibility in reserving `Minor` bumps for more significant changes to our scanners. In case of breaking changes imposed by the wrapped scanner, creating a new analyzer on a separate repository must be considered.
+
+The analyzers are released as Docker images following this scheme:
+
+- each push to the `master` branch will override the `edge` image tag
+- each push to any `awesome-feature` branch will generate a matching `awesome-feature` image tag
+- each Git tag will generate the corresponding `Major.Minor.Patch` image tag. A manual job allows to override the corresponding `Major` and the `latest` image tags to point to this `Major.Minor.Patch`.
+
+To release a new analyzer Docker image, there are two different options:
+
+- Manual release process
+- Automatic release process
+
+### Manual release process
+
+1. Ensure that the `CHANGELOG.md` entry for the new analyzer is correct.
+1. Ensure that the release source (typically the `master` or `main` branch) has a passing pipeline.
+1. Create a new release for the analyzer project by selecting the **Deployments** menu on the left-hand side of the project window, then selecting the **Releases** sub-menu.
+1. Select **New release** to open the **New Release** page.
+ 1. In the **Tag name** drop down, enter the same version used in the `CHANGELOG.md`, for example `v2.4.2`, and select the option to create the tag (`Create tag v2.4.2` here).
+ 1. In the **Release title** text box enter the same version used above, for example `v2.4.2`.
+ 1. In the `Release notes` text box, copy and paste the notes from the corresponding version in the `CHANGELOG.md`.
+ 1. Leave all other settings as the default values.
+ 1. Select **Create release**.
+
+After following the above process and creating a new release, a new Git tag is created with the `Tag name` provided above. This triggers a new pipeline with the given tag version and a new analyzer Docker image is built.
+
+If the analyzer uses the [`analyzer.yml` template](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/b446fd3/includes-dev/analyzer.yml#L209-217), then the pipeline triggered as part of the **New release** process above automatically tags and deploys a new version of the analyzer Docker image.
+
+If the analyzer does not use the `analyzer.yml` template, you'll need to manually tag and deploy a new version of the analyzer Docker image:
+
+1. Select the **CI/CD** menu on the left-hand side of the project window, then select the **Pipelines** sub-menu.
+1. A new pipeline should currently be running with the same tag used previously, for example `v2.4.2`.
+1. After the pipeline has completed, it will be in a `blocked` state.
+1. Select the `Manual job` play button on the right hand side of the window and select `tag version` to tag and deploy a new version of the analyzer Docker image.
+
+Use your best judgment to decide when to create a Git tag, which will then trigger the release job. If you
+can't decide, then ask for other's input.
+
+### Automatic release process
+
+The following must be performed before the automatic release process can be used:
+
+1. Configure `CREATE_GIT_TAG: true` as a [`CI/CD` environment variable](../../ci/variables/index.md).
+1. Check the `Variables` in the CI/CD project settings. Unless the project already inherits the `GITLAB_TOKEN` environment variable from the project group, create a [project access token](../../user/project/settings/project_access_tokens.md) with `complete read/write access to the API` and configure `GITLAB_TOKEN` as a [`CI/CD` environment variable](../../ci/variables/index.md) which refers to this token.
+
+After the above steps have been completed, the automatic release process executes as follows:
+
+1. A project maintainer merges an MR into the default branch.
+1. The default pipeline is triggered, and the `upsert git tag` job is executed.
+ - If the most recent version in the `CHANGELOG.md` matches one of the Git tags, the job is a no-op.
+ - Else, this job automatically creates a new release and Git tag using the [releases API](../../api/releases/index.md#create-a-release). The version and message is obtained from the most recent entry in the `CHANGELOG.md` file for the project.
+1. A pipeline is automatically triggered for the new Git tag. This pipeline releases the `latest`, `major`, `minor` and `patch` Docker images of the analyzer.
+
+### Steps to perform after releasing an analyzer
+
+1. After a new version of the analyzer Docker image has been tagged and deployed, please test it with the corresponding test project.
+1. Announce the release on the relevant group Slack channel. Example message:
+
+ > FYI I've just released `ANALYZER_NAME` `ANALYZER_VERSION`. `LINK_TO_RELEASE`
+
+**Never delete a Git tag that has been pushed** as there is a good
+chance that the tag will be used and/or cached by the Go package registry.