# dependency-validator: pinning an SBOM to the newest Git tags

> Dependency Validator is a Go command line tool that compares the versions in a CycloneDX JSON SBOM against the highest semantic version Git tag in each configured upstream repository, and exits non-zero when something is behind. It checks only the dependencies you allowlist, and it deliberately does not scan for vulnerabilities or licence problems.

**Cadeusept/dependency-validator** — Сhecks whether the versions of the specified libraries are up to date

- Repository: https://github.com/Cadeusept/dependency-validator
- Stars: 620 · Forks: 0
- Language: Go
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/cadeusept-dependency-validator

## The problem it solves: a stale pinned dependency

An SBOM exists so that someone can enumerate what is inside a build. The gap the project fills is narrower and more specific: knowing when a dependency in that SBOM is no longer the newest released version.

The tool is a command line utility that compares dependencies in a CycloneDX SBOM with the latest semantic version tags in their source repositories. It is aimed at local development and CI, and the framing is an explicit allowlist of dependencies that must stay on the newest tagged release.

That framing matters. This is not a scanner that inspects everything in your build and reports what it finds. It is a check against a list you write yourself, which means the output is a short list of named dependencies rather than a wall of findings. The README states the rule plainly: only dependencies listed in the configuration are checked, and components present in the SBOM but absent from the configuration are ignored.

The users are engineers who have already decided which upstream libraries they track, and who want a CI job that fails loudly when one of those libraries ships a new tag. It is also useful as a periodic local check for a developer who wants to know what has moved since the last sweep.

## The four step pipeline and its exit code

The mechanism is described in four steps. Dependency Validator finds an SBOM in the current directory. It reads library names and versions from a CycloneDX JSON document. For every repository in .dependency-validator-config.yaml, it finds the highest valid semantic version Git tag. And it exits with status 1 when at least one configured dependency is outdated.

That last point is the whole contract with CI. A non-zero exit is the signal, and it is the only signal you need to wire up. A job step that runs the binary and fails the build on a non-zero status is the entire integration.

The use of Git tags as the source of truth is a deliberate choice rather than an API lookup against a package registry. The version that a project has published is the tag on its repository, so the tool reads the same artefacts you would install from, and it needs no registry credentials for public repositories. The requirement listed for Git is stated plainly: it is used to read remote repository tags.

Note the constraint that follows from this. A tag that is not valid semantic versioning is ignored, so a project that tags releases as v1.2.3 is handled, and a project whose tags follow some other scheme is not going to be reported correctly.

## Installing it and building from source

The normal installation path is go install against the latest tag:

```bash
go install github.com/Cadeusept/dependency-validator@latest
```

The project also ships an installation script:

```bash
curl -sSfL https://raw.githubusercontent.com/Cadeusept/dependency-validator/master/install.sh | sh
```

And prebuilt archives are published on the GitHub Releases page.

Building the current source by hand is three commands:

```bash
git clone https://github.com/Cadeusept/dependency-validator.git
cd dependency-validator
go build -o dependency-validator .
```

The toolchain requirement is specific and worth noting before you plan a pipeline around it. The README asks for Go 1.26.4 or newer when installing or building from source, and the go.mod file in the repository declares go 1.26.4. That is a recent language version, so a CI image pinned to an older Go release will not build this tool.

The dependency list is short, which is a good sign for a tool that runs in CI. It requires github.com/stretchr/testify at v1.11.1 for tests, golang.org/x/mod at v0.38.0, and gopkg.in/yaml.v2 at v2.4.0 for configuration parsing. The repository also carries a .golangci.yml file, so linting is configured in the project itself.

## The configuration file is an allowlist with optional tokens

You create.dependency-validator-config.yaml in the project directory. The shape is a repos list, where each entry has a name, a repo_url and an optional token:

```yaml
repos:
  - name: github.com/pedroalbanese/kuznechik
    repo_url: https://github.com/pedroalbanese/kuznechik

  - name: github.com/stretchr/testify
    repo_url: https://github.com/stretchr/testify
    token: ${GITHUB_TOKEN}

  - name: gitlab.com/private_username/private_repo
    repo_url: https://gitlab.com/private_username/private_repo
    token: ${GITLAB_TOKEN}
```

Three rules govern those keys. The name must match the component name in the SBOM, which is the join between the two files and the thing most likely to bite you on first run. The repo_url must be a Git repository whose releases use valid semantic version tags such as v1.2.3. The token is optional, and environment variables in the configuration are expanded before it is parsed, which is how the placeholder syntax above works.

That last point is also the security model. The project states the instruction directly: do not commit access tokens, pass them through an environment variable or your CI secret store. Since the token is expanded at parse time from the environment, a committed file can reference a secret without containing it.

Note the repository naming in the config is a full host and path, for example gitlab.com/private_username/private_repo, not just a module path. The private_repository example shows that a GitLab repository is expected to work the same way as a GitHub one, with the token covering the rate limit and the private access.

## A first run: generate the SBOM, then validate it

The validator expects a CycloneDX JSON SBOM in the current directory, and the README recommends Syft as the generator. The generation command is:

```bash
syft . --output cyclonedx-json=bom.json
```

Then you run the validator from the directory that holds both the SBOM and the configuration file:

```bash
dependency-validator
```

The documented output shows the sequence of messages. It reports the SBOM file it found, then names each repository as it checks it, and for an outdated dependency it states the version in use and the latest tag, and finally prints a list of the outdated dependencies with their current and latest versions.

The last point is what you would parse in a CI log, since the summary line carries both values for each entry.

One subtlety worth flagging: the SBOM is generated at whatever moment you run Syft, so the check reflects the state of your working tree at that moment. A CI job that generates the SBOM and validates it in the same run is checking the code as built, which is the behaviour you want.

## Wiring it into GitHub Actions

The README shows the workflow step, and the workflow is worth reading because it sequences the tools correctly. The configuration file stays in the repository, the workflow checks out the code, sets up Go, installs the validator and Syft, generates the SBOM, and then runs the check.

```yaml
name: Check dependencies

on:
  pull_request:
  push:
    branches: [master]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.26.4'

      - name: Install Dependency Validator
        run: go install github.com/Cadeusept/dependency-validator@latest

      - name: Install Syft
        run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b ./bin

      - name: Generate CycloneDX SBOM
        run: ./bin/syft . --output cyclonedx-json=bom.json

      - name: Check dependency versions
        run: "$(go env GOPATH)/bin/dependency-validator"
```

Two details in that YAML are easy to get wrong. The Syft install script is invoked with a trailing -b ./bin, which puts the binary in the working directory rather than on the PATH, so the generate step calls ./bin/syft explicitly. And the validator is invoked through the full GOPATH path, since go install puts it there rather than in the current directory.

The workflow triggers on pull requests and on pushes to master, and the validator binary needs no arguments because it reads both files from the working directory.

## What it deliberately does not check

The scope section is where this tool is most misunderstood, so it is worth reading closely.

Only CycloneDX JSON input is parsed. There is no support for other SBOM formats, and no support for the XML variant of CycloneDX.

Upstream versions must be valid semantic version Git tags. A repository that releases without tags, or with tags in a different format, will not produce a usable latest version.

Most importantly, the utility checks whether configured versions are current, and it does not scan for vulnerabilities, license violations, dependency conflicts, or unused packages. Four categories of problem that people often want from an SBOM tool are explicitly out of scope. If you are looking for a tool that tells you whether a dependency has a known CVE, this is the wrong one, and the project is clear about it.

The last limitation is operational. Repository access requires network connectivity and may require a token for private repositories or rate-limited environments. So the tool needs outbound Git access from wherever it runs, and on a shared CI runner the number of repositories you list translates directly into tag lookups that can hit an unauthenticated rate limit.

For context on the alternative approach: tools that read a package manager manifest and check the registry for newer versions work from a different source of truth and do not need a Git remote at all. This tool instead treats the Git tag as the definition of the release, which is the right choice when your dependencies are consumed as source or as libraries outside a package registry, and the wrong one when they are ordinary registry packages where the registry already knows the latest version.

## Licence, releases and the pace of the project

The project is released under the Apache-2.0 licence, with a LICENSE file and a NOTICE file at the repository root. The Apache 2.0 terms permit use inside proprietary and open source tooling, require the copyright and licence notices to be kept with copies, and ask you to state notable modifications when redistributing. Your own review is what decides how the terms apply to your build.

The release history shows three tagged versions. v1.0.1 and v1.0.2 landed on 2025-06-20 and 2025-06-23, and v1.1.0 was released on 2026-08-03. The repository is not archived, and the last push was on 2026-08-03, the same day as that release.

So the project is young and small, with a version 1.x line and a short history. The Go 1.26.4 requirement and the recent v1.1.0 tag suggest a tool that is still being shaped, which is a good thing for a utility you wire into CI and a risk if you need a long term support commitment.

The repository also carries the housekeeping files a project like this should have, including CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md. The SECURITY.md file in particular tells you where to report a problem, which matters for a tool that fetches tags from repositories you do not control, since a compromised upstream tag is the kind of thing you want a reporting channel for.

## Conclusion

dependency-validator fits a team that already produces a CycloneDX SBOM with Syft and wants a hard gate on the handful of upstream libraries it actually cares about, since the allowlist model keeps the check fast and its intent explicit. It does not fit as a general supply chain scanner, because the project states that it does not look for vulnerabilities, licence violations, dependency conflicts or unused packages. Before adopting it, write the allowlist in .dependency-validator-config.yaml with the exact component names your SBOM uses, keep tokens in environment variables rather than in the file, and confirm your network and GitHub or GitLab token limits cover the number of tag lookups a run performs.

## FAQ

### How do I install dependency-validator?

Run go install github.com/Cadeusept/dependency-validator@latest, or use the install.sh script, or download a prebuilt archive from the GitHub Releases page. Building from source requires Go 1.26.4 or newer.

### What file does dependency-validator need to run?

It needs a CycloneDX JSON SBOM and a .dependency-validator-config.yaml in the current directory. The SBOM is generated with syft . --output cyclonedx-json=bom.json, and Syft is the recommended generator.

### How do I check a private repository with dependency-validator?

Add a token field to the repo entry, referencing an environment variable such as ${GITHUB_TOKEN}, and pass the secret through your CI secret store. The project states that access tokens should not be committed, and environment variables in the configuration are expanded before it is parsed.

### Does dependency-validator find vulnerable or conflicting dependencies?

No. The project states that the utility only checks whether configured versions are current, and that it does not scan for vulnerabilities, license violations, dependency conflicts or unused packages.

### How does dependency-validator fail a CI pipeline?

It exits with status 1 when at least one configured dependency is outdated. In the documented GitHub Actions workflow the binary is invoked directly as a step, so a non-zero exit fails the job.

## Sources

- [Cadeusept/dependency-validator on GitHub](https://github.com/Cadeusept/dependency-validator)
- [Issues](https://github.com/Cadeusept/dependency-validator/issues)
- [License: Apache-2.0](https://github.com/Cadeusept/dependency-validator/blob/master/LICENSE)
- [README](https://github.com/Cadeusept/dependency-validator/blob/master/README.md)
- [Releases](https://github.com/Cadeusept/dependency-validator/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cadeusept-dependency-validator
