A Calustra - Eloy Coto Pereiro Home About

Make your Golang project more secure with a few simple tools


Over the last few years, I have been jumping between multiple Golang projects within different teams. These are a few tools that are not well-known by many developers but make your code a bit more secure.

These static check tools fit nicely on your CI pipelines. Other tools validate what your code is doing on runtime (Tetragon), and some validate that your dependencies are what it is supposed to be (SigStore).


It's a community-driven tool that does static code analysis based on Golang AST. It prevents your application from common attacks and controls SQL injection, decompression attacks, Insecuring connections, ENV attacks and a few others.

You can use it manually like this:

docker run --rm -w /opt/data/ \
  -v $(PWD):/opt/data/:z \
  docker.io/securego/gosec \
  -exclude-generated /opt/data/...

Or using it on GitHub Actions:

name: Security
    branches: [main]
    branches: [main]

    name: Security Scanner
    runs-on: ubuntu-latest
      - name: Check out code
        uses: actions/checkout@v2

      - name: Run Gosec Security Scanner
        uses: securego/gosec@master
          GOFLAGS: -buildvcs=false
          args: '-exclude-generated ./...'


Semgrep is a broader tool and supports multiple programming languages. It has a lot of rules that are community driven and free, and it also has some extended rules that are only available by paying a subscription.

You can use it manually like this:

$ docker run --rm -v "$(pwd):/src" \
    returntocorp/semgrep \
    semgrep --config "p/golang"


In Golang projects, it is usual to commit the vendor packages inside the application repository. This behaviour can add some issues if one dependency has a CVE that the infra team may be unaware of.

Vuln is a community-driven tool that checks the dependencies that are part of the go.mod and validates that there is no CVE in the current dependency version; if it's any, it'll inform about the dependency.

From my perspective, this tool should run daily in our CI with a clear path to fixing it.

You can use it manually like this:

govulncheck ./...

Or using it on GitHub Actions:

name: My Workflow
on: [push, pull_request]
    runs-on: ubuntu-latest
      - uses: actions/checkout@v3
      - name: Running govulncheck
        uses: Templum/govulncheck-action@<version>
          go-version: 1.18
          vulncheck-version: latest
          package: ./...
          github-token: ${{ secrets.GITHUB_TOKEN }}

These are the tools that I would always add to my CI; they are free and can save your organization from any stupid risk.


Related articles: