← All posts

Dormant maintainer accounts are a supply-chain risk

SleeperGem shows how old, trusted package-maintainer accounts can become a quiet path from normal dependency updates to malware delivery.

A package does not need to be new to be risky. Sometimes the most dangerous release comes from a project everyone stopped thinking about years ago.

That is the useful lesson from Aikido’s SleeperGem report, which describes a RubyGems supply-chain attack built around dormant maintainer accounts and trusted gems. The initial package, git_credential_manager, looked like a small utility. Under the surface, Aikido says it downloaded binaries from a public Forgejo instance, disabled TLS certificate verification, and executed the payload on developer machines.

The important part is not only that RubyGems was targeted. It is that old trust was reused. A maintainer account that had been quiet for years suddenly became a delivery path again.

What happened

Aikido reports that git_credential_manager published four versions in rapid succession. The package downloaded binaries from git.disroot[.]org/git-ecosystem/, a public Forgejo host where the attacker had registered a convincing-looking git-ecosystem username.

According to the report, the early version already behaved like a dropper: it built a URL to the hardcoded host, fetched a binary with certificate verification disabled, and handed the downloaded file to /bin/sh on Unix-like systems or PowerShell on Windows. A later release made the Unix execution quieter by piping output to /dev/null.

The most important change came next. Aikido says version 2.8.2 wired the installer into the gem’s load path, so merely requiring git_credential_manager could trigger the installation flow. Version 2.8.3 then made the payload live. That moved the risk from “someone ran this tool” to “application code loaded a dependency that now performs unexpected work.”

The campaign also tried to avoid CI environments. Aikido found logic that checked for roughly 30 environment variables associated with CI systems such as GitHub Actions, GitLab CI, CircleCI, Travis, Jenkins, and Vercel, then skipped installation if those variables were present. That points the attack toward developer workstations rather than disposable build runners.

Why dormant accounts change the risk model

Most dependency review focuses on obvious changes:

Dormant maintainer-account compromise is harder to spot because it starts from existing trust. A package may already be approved. A maintainer may already have the right to publish. A gem may have sat harmlessly in a dependency graph for years.

Aikido says it found more than one affected maintainer account. One package, Dendreo, first published in 2017, received fresh releases around the same time and added git_credential_manager as a dependency. Another affected project, fastlane-plugin-run_tests_firebase_testlab, had more than 574,000 total downloads and belonged to a different maintainer.

That pattern matters. If an attacker can reactivate old accounts and push a new dependency into trusted projects, defenders cannot treat “we already use this package” as a complete approval signal. The package name may be familiar while the current release path is not.

What teams should check

If you use RubyGems in application or build tooling, start by looking for the affected packages and versions named in the report:

Then widen the search from package names to behavior:

Lockfiles and SBOMs are useful here because they give you a record of exactly which versions entered which projects. Registry proxy logs and package-manager caches are useful for a different question: which machines actually pulled the package?

Those two questions are different. An SBOM can tell you that a build included a package. Install logs can tell you whether a developer laptop or CI runner fetched a version during the exposure window. Incident response usually needs both.

Why this is not just a RubyGems story

RubyGems may be the ecosystem in this incident, but the control problem is broader.

Every package registry has some version of the same trust chain:

  1. maintainers or automation accounts can publish,
  2. downstream users trust package names and version ranges,
  3. dependency managers resolve updates automatically,
  4. developer machines and CI systems execute build or runtime code with useful credentials nearby.

When a maintainer account goes dormant, the risk does not disappear. In some ways it becomes easier to miss. There may be no active community watching changes, no recent release cadence to compare against, and no human memory of what a normal update should look like.

That makes “maintainer freshness” and “release surprise” useful signals. A dependency that suddenly wakes up after six years should be reviewed differently from a dependency with an active, predictable release pattern.

What to do next

The practical response is not to panic about every old dependency. It is to make old trust visible again.

A good baseline looks like this:

The SleeperGem pattern is uncomfortable because it uses the quietest part of the dependency graph: packages and accounts that teams stopped actively thinking about. That is exactly why inventory matters. You cannot review every line of every dependency every day, but you can keep enough history to notice when an old dependency starts behaving like a new risk.


boring.tools takes the CycloneDX or SPDX SBOM your CI already produces, matches it against OSV continuously — including transitive dependencies — and keeps every triage decision with its history. See how it works →