Supported ecosystems
This is the one list. When another page names ecosystems, it follows this page.
Dependency scanning
Dependency scanning (osv-scanner, on every pull request and on the default branch) reads these files:
| Ecosystem | Files |
|---|---|
| npm | package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lock (not the binary bun.lockb) |
| PyPI | requirements.txt, poetry.lock, uv.lock, pdm.lock, Pipfile.lock |
| Go | go.mod |
| Maven | pom.xml, with every dependency it pulls in: resolved through your organisation’s Maven proxy, without running Maven; see Maven dependency resolution |
| Gradle | gradle.lockfile |
| Cargo | Cargo.lock |
| RubyGems | Gemfile.lock |
| Composer | composer.lock |
| Hex | mix.lock |
| pub | pubspec.lock |
| Conan | conan.lock |
| CRAN | renv.lock |
| NuGet | through Trivy, with the container image scan of the repository |
| Terraform and OpenTofu providers | .terraform.lock.hcl: the provider binaries the lock pins; see Terraform and OpenTofu providers |
| GitHub Actions | the uses: lines of the workflow files in .forgejo/workflows/, .gitea/workflows/ and .github/workflows/; see CI action versions |
Container images are scanned by Trivy: the operating-system packages and the language packages inside each image. See Container image scanning.
Maven dependency resolution
A pom.xml names only its direct dependencies. To see what those pull in, dependency scanning resolves each pom.xml the way Maven would: parent poms, imported BOMs, <dependencyManagement>, properties, scopes, exclusions and version ranges. It reads poms only. No Maven, no plugin and no code from your repository runs.
- Where the poms come from. Every pom is read through your organisation’s Maven proxy, with the platform’s proxy as the fallback. A multi-module build’s own modules are read from the repository.
<repositories>declared in a pom are not contacted: an artifact that only a private repository holds is not resolved, and is named (below). No resolution service outside fremforge is asked. - What uses the result. The resolved tree is what dependency findings, the
fremforge/dep-scanstatus, the repository’s SBOM and transitive fix pull requests read, so they agree. - Cached. A tree is reused for 24 hours while the poms are unchanged. Advisories are matched afresh on every scan, so a new advisory is never hidden by the cache.
When a pom cannot be resolved, it never reads clean. Its direct dependencies are still checked, and:
- the
fremforge/dep-scanstatus says so even when it is green:1 pom.xml not fully resolved: transitive dependencies not checked; - the pull request comment lists the pom under Not fully checked, with the reason and the artifacts the proxy did not have, even when there are no findings;
- the dependency findings and SBOM pages show Not fully checked, with a link to the dependency proxy when an artifact is missing;
- the SBOM carries it as a coverage note (CycloneDX: the
fremforge:coverage:maven-unresolvedproperty and anincompletecomposition; SPDX: the creation comment); GET /orgs/{org}/code-security/deps/coverage(scopefindings:read) returns it for the default branch. By default it lists only repositories with something not fully checked;all=truelists every repository with a coverage record, andrepo=<name>filters to one.
curl -sS -H "Authorization: Bearer $FREMFORGE_TOKEN" \
"https://frem.sh/_app/api/v1/orgs/<org>/code-security/deps/coverage"The usual reason is an artifact your Maven proxy does not have, such as an internal library published elsewhere: add that repository as an upstream of the proxy. Other reasons are the proxy not answering, a timeout, or a build with more than 60 poms (the rest are reported, not resolved).
Known limits. The resolution reads the poms; it does not run the build. So:
- a build that rewrites its dependencies with a plugin (
maven-shade-pluginrelocation,flatten-maven-plugin, a generated pom) is checked as its poms declare it, not as the plugin changes it; - a profile that depends on your build machine’s environment (a system property, a file, the operating system or the JDK) may not be applied the way your build applies it.
For the exact tree your build ships, push a CycloneDX SBOM from CI; it is matched as well.
Terraform and OpenTofu providers
There is no advisory database for Terraform providers, but a provider is a Go program. For each provider version in a .terraform.lock.hcl, fremforge scans the provider binary for the Go modules it was built from, and reports their advisories as dependency findings of the repository:
- Ecosystem
Terraform, package the provider address (for exampleregistry.terraform.io/hashicorp/null), version the locked version, manifest the lock file. The summary names the Go module and its version, for examplegoogle.golang.org/grpc@v1.69.4 (built into the provider). - Only the binary the lock installs. A finding is reported only when one of the lock’s hashes (
zh:orh1:) is the provider zip that was scanned. A lock that accepts other bytes gets no findings for a binary it would not install. - The same check as any dependency. The findings go through your dependency threshold, dismissals and the comparison with the base branch, so a pull request is blocked only by findings it adds.
- The first scan of a version is not immediate. A version fremforge has not seen before is queued when a lock that pins it is first scanned, and scanned in the background, usually within the hour. Its findings appear on the next scan of each repository that locks it; until then that version has none.
- Reachability. Each finding says whether the provider binary links a function the advisory names: reachable or not reachable, or unknown when that cannot be decided. See Reachability.
- Fixed version. The fixed version of a finding is the first provider release whose binary no longer carries the advisory, among the next ten releases after yours and the newest one. fremforge scans those releases the same way, so it can take an hour or two after the first scan of your version to appear. It stays empty when no such release exists yet, which is common: a provider’s newest release often still ships the vulnerable module.
- Where the binary comes from. The
linux_amd64zip is fetched once, through fremforge’s own provider mirror, from the location the provider’s registry publishes. For HashiCorp’s providers that is HashiCorp’s release site,releases.hashicorp.com, which fremforge does not operate: it is used only to fetch the public provider zip, nothing about your repository is sent to it, and fremforge keeps the copy it scanned.
Not covered: Terraform modules; a provider built before Go 1.18 (for example hashicorp/null 3.1.0), whose binary carries no module list to read; and the Go standard library the provider was built with. A security fix for a provider is not opened: update the version in your configuration and run tofu init -upgrade or terraform init -upgrade.
CI action versions
Every uses: owner/repo@<version> in a workflow file directly under .forgejo/workflows/, .gitea/workflows/ or .github/workflows/ is matched against the GitHub Actions advisories (GHSA) in fremforge’s own copy of the OSV database, since 18 October 2026. No call is made to GitHub: the advisories come from that copy and the version from your workflow file.
- The version is the tag (
actions/download-artifact@v4.1.2), or, for an action pinned to a commit, the version comment beside it (actions/download-artifact@<sha> # v4.1.2), which is how pinning tools write it. A pinned action without such a comment has no version to match. - A finding is a dependency finding: ecosystem
GitHub Actions, packageowner/repo, the workflow file as the manifest. It goes through your dependency threshold, dismissals and the comparison with the base branch, so a pull request is blocked only by findings it adds, in thefremforge/dep-scancheck. - If fremforge’s copy of the GitHub Actions advisories is missing, a repository whose workflows name versioned actions fails its dependency scan rather than passing with no findings.
Not covered: a major-only tag (@v4) or a branch, which names no version; workflow files in sub-directories or outside those three directories, composite actions’ own action.yml, and symlinked workflow files. Whether a reference is pinned to a commit is checked separately; see Workflow pinning.
Security fixes
Security fixes open a pull request for:
- npm, including Yarn, pnpm and Bun with
bun.lock(not the binarybun.lockb: runbun install --save-text-lockfileonce to switch); - Go;
- PyPI;
- Maven;
- Gradle with a lockfile, which is refreshed in a job on your organisation’s own runner;
- NuGet;
- Cargo;
- Composer,
composer.jsonandcomposer.lock; - pub,
pubspec.yamlandpubspec.lock; - RubyGems,
Gemfile.lock, which is updated in a job on your organisation’s own runner (Bundler reads theGemfile, which is Ruby code fremforge does not run); - Hex,
mix.lock, which is updated in a job on your organisation’s own runner, in the officialelixirimage (Mix readsmix.exs, which is Elixir code); - GitHub Actions, the workflow file: the action is moved to the lowest version that fixes every open advisory, pinned to that tag’s commit with the tag as a comment (
@<sha> # v4.1.3). The tags are read from the action mirror on frem.sh, never from github.com; - base images: the
FROMline of a Dockerfile, within the same major version.
They fix direct dependencies, and these transitive ones (see Transitive dependencies):
- npm with
package-lock.json, pinned withoverrides; - pnpm with
pnpm-lock.yaml(lockfile version 9.0), pinned withoverrides; - Yarn 1 with
yarn.lock, pinned withresolutions(Yarn 2 and later are not supported); - PyPI with
uv.lockorpoetry.lock, by moving the lock entry; - Maven, pinned with
<dependencyManagement>in thepom.xmlthe finding came from (or the rootpom.xml, for a package seen in an uploaded SBOM); - Gradle with
gradle.lockfile, pinned with a dependency constraint; - Go modules marked
// indirectingo.mod; - Composer packages that
composer.jsondoes not name, by updatingcomposer.lockin a job on your organisation’s own runner; - RubyGems and Hex: every fix is a lock file update, so a package another package pulls in is fixed the same way as one the manifest names.
Not fixed, each with its reason on the finding: bun.lockb, which only Bun can rewrite, and pub and Bun packages that the manifest does not name. For any other ecosystem, a fix request answers not yet supported.
Reachability
Reachability gives a verdict for:
| Ecosystem | Level |
|---|---|
| npm | function, or import when the advisory names no functions |
| Go | function, from the Go binaries in your images |
| PyPI | import |
| Maven | import |
| Terraform and OpenTofu providers | function, from the provider binary the lock pins |
Every other ecosystem gets the verdict unknown.
Dependency proxy
The dependency proxy serves npm, PyPI, Maven, NuGet, Go, Cargo, Helm and RPM packages, container images, and Terraform and OpenTofu modules.
Not covered
Terraform modules and Helm chart versions are not checked against vulnerability advisories. CI action versions are; see CI action versions. Terraform and OpenTofu providers are, from their binaries; see Terraform and OpenTofu providers. The container images a Helm chart deploys are; see Images your Helm charts deploy. Infrastructure-as-code files get misconfiguration checks only, in their own check, fremforge/iac-scan; see IaC scanning. Whether action references are pinned to a commit is checked too; see Workflow pinning.