TL;DR: Attackers stole an npm publish token from an AsyncAPI GitHub Actions workflow, then used it to backdoor five npm packages that together draw about 2.9 million weekly downloads, according to Aikido. The incident shows how a single workflow misstep can become supply chain compromise, persistence, and downstream credential exposure.
At a glance
What this is: This is a supply chain compromise in which a GitHub Actions workflow flaw let an attacker steal publish access and seed malicious code into widely used AsyncAPI npm packages.
Why it matters: IAM, CI/CD, and NHI teams should treat workflow secrets, publish tokens, and build-time trust boundaries as production identities, because a single exposed token can turn developer automation into downstream compromise.
Context
GitHub Actions workflows are not just automation glue. When a workflow can access repository secrets during untrusted pull request execution, it can become an identity boundary failure rather than a build pipeline convenience. In this case, the security problem is not npm itself but the combination of secret-bearing workflow design, publish privilege, and code paths that execute on import.
For identity and governance teams, the relevant lesson is that build systems increasingly behave like non-human identities with delegated authority. If those credentials can be reached through untrusted repository events, the resulting compromise can cross from CI/CD into package distribution, developer endpoints, and downstream consumers with very little friction.
Key questions
Q: What breaks when a GitHub Actions workflow with pull_request_target can reach publish secrets?
A: The workflow stops being a neutral automation step and becomes a privileged access path. If untrusted pull request content can influence a job that reads repository secrets, an attacker can steal tokens, publish malicious artifacts, or pivot into broader supply chain compromise. The failure is boundary control, not just code review.
Q: Why do package publish tokens create supply chain risk when reused in CI pipelines?
A: Because publish tokens often combine broad registry authority with weak contextual limits. If a CI job can access that token while handling untrusted input, the attacker can mutate package versions or stage a backdoor that reaches every downstream consumer. Short-lived, tightly scoped release credentials reduce that exposure.
Q: What are the signs that an npm package has moved from dependency to implant?
A: Look for code that runs on import, downloads payloads at runtime, writes executable files to user directories, or spawns detached child processes. Those are strong signals that the package is doing more than exporting functions. In this case, the runtime loader was the real delivery mechanism.
Q: How should security teams respond when a package registry account or workflow token is compromised?
A: Treat it as a supply chain incident, not a single secret leak. Revoke the credential, remove malicious versions from registries and mirrors, identify every repository and host that imported the package, and rotate adjacent credentials from a clean environment. Then validate that the release path is no longer reachable from untrusted workflow execution.
Technical breakdown
Why pull_request_target created the secret exposure window
The pull_request_target trigger runs a workflow in the context of the target repository, which means repository secrets are available even when the code being evaluated comes from an external pull request. That design is useful for automation, but it creates a trust boundary problem if unreviewed contributor content can reach secret-bearing steps. In this case, the attacker used that boundary to reach the npm publish token. The core issue is not malicious JavaScript alone, but secret exposure through a workflow event that should have been treated as privileged execution.
Practical implication: Treat pull_request_target as privileged execution and remove direct secret access from any path that can process untrusted contributor code.
How the trojanized packages became runtime implants
The malicious code was placed in normal runtime modules, not in an npm lifecycle hook, so importing the package was enough to trigger execution. The loader fetched an encrypted payload from IPFS, wrote it to disk as sync.js, and launched it as a detached process. That pattern matters because defenders often focus on install-time hooks while the real abuse happens on module load. Once the package is required, the attacker gains a durable foothold that behaves like a hidden workload identity inside the developer environment.
Practical implication: Inspect package imports as execution events, not passive dependency resolution, and block unexpected detached child processes from build and developer hosts.
Why supply chain persistence outlives the initial token theft
The package publish token was only the entry point. The impact came from the attacker converting that access into malicious package versions, then using runtime code to establish a shell and maintain control across affected hosts. The article also shows how persistence paths varied by platform, which is typical of implant design rather than a one-off exploit. In governance terms, the real weakness is the absence of end-to-end control over publish privilege, artifact integrity, and post-publish detection.
Practical implication: Bind package publishing to tightly scoped, short-lived credentials and verify that every published artifact matches a reviewed source state before release.
Threat narrative
Attacker objective: The attacker aimed to turn repository workflow access into persistent package distribution control and remote command execution on systems importing the compromised modules.
- Entry occurred when the attacker exploited a pull_request_target GitHub Actions workflow that exposed repository secrets during external pull request handling.
- Credential access followed when obfuscated code exfiltrated the npm publish token to an external dead-drop service.
- Escalation and impact came when the attacker used the stolen token to publish trojanized AsyncAPI packages that executed an IPFS-fetched loader and opened a remote shell on import.
Breaches seen in the wild
- tj-actions/changed-files compromise 2025: A stolen bot token let attackers poison tj-actions/changed-files so pipelines printed their CI/CD secrets to public logs (CVE-2025-30066).
- reviewdog Action compromise 2025: A stolen maintainer token poisoned reviewdog/action-setup, leaking CI secrets including the tj-actions bot token used in the next attack.
Read and download The State of NHI & AI Agent Breach Report 2026, covering 200+ breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
Workflow secrets are becoming non-human identities with publish authority. When a GitHub Actions job can reach package registry credentials during untrusted request handling, the workflow is no longer just automation. It is a delegated identity path that needs lifecycle control, event scoping, and publish separation. The practical conclusion is that CI/CD secrets must be governed like any other privileged machine credential.
Import-time execution is the overlooked supply chain blast radius. Security reviews often stop at install hooks and dependency manifests, but runtime modules can be far more dangerous because they execute as soon as they are loaded. That means package trust is an execution control problem, not just a provenance problem. Practitioners should treat import paths, detached child processes, and dynamic payload retrieval as governance signals, not merely malware traits.
AsyncAPI-style compromises validate the need for package publishing segmentation. One exposed publish token should not be enough to mutate the supply chain and deploy code that persists on consumer systems. The governance gap is standing publish privilege combined with broad workflow reach. The right response is to narrow who can publish, under what conditions, and from which verified build states.
CI/CD pipelines now sit inside the identity perimeter, not outside it. That changes how IAM, PAM, and software supply chain teams should think about approval, revocation, and monitoring. A token used once in a workflow can still become a lasting attack path if it is allowed to sign, publish, and execute code. Practitioners should align pipeline controls with the same discipline they apply to privileged human access.
Runtime implants expose the weakness of control models that stop at registry hygiene. Removing bad versions from the registry matters, but it does not address hosts where the package was already imported and executed. The broader lesson is that software distribution compromise has to be governed across publish, download, import, and host runtime. Teams that only watch the registry are seeing half the problem.
What this signals
CI/CD secrets now behave like production identities. Once a workflow can publish packages or sign artifacts, its credentials need the same lifecycle discipline as privileged human access. The governance gap is not that pipelines are automated, but that many teams still let untrusted events reach privileged automation without a strict trust boundary.
Import-time execution is the critical control boundary. Package compromise does not end at publication if the malicious code runs when the module is required. That means detection has to extend beyond registry hygiene into endpoint and runtime monitoring for detached processes, unexpected loaders, and suspicious outbound fetches.
Publish privilege should be treated as a constrained non-human identity. If a single token can alter the software supply chain, its scope is too broad. Teams should separate build, test, and release authority so that compromise in one stage cannot automatically become package ownership in the next.
For practitioners
- Harden privileged GitHub Actions triggers Remove secret access from workflows that process untrusted pull requests, especially pull_request_target jobs that can reach publish credentials.
- Separate package publishing from build execution Require reviewed, isolated release jobs for npm publication and ensure build workflows cannot directly mint or use registry tokens.
- Search for import-time execution on developer hosts Look for detached Node processes, unexpected sync.js drops, and package imports that correlate with outbound IPFS, Nostr, or Ethereum traffic.
- Rotate exposed development and CI credentials Assume npm tokens, source control access, SSH keys, cloud credentials, and browser sessions on affected machines may be exposed and rotate them from a clean system.
- Verify published artifacts against reviewed source state Compare registry versions, lockfiles, and internal mirrors against approved release commits before allowing packages into internal build paths.
Key takeaways
- The incident shows how a CI workflow secret can become a package publishing foothold and then a runtime implant delivery path.
- The malicious packages were designed to execute on import, which expands the blast radius beyond installation-time controls and into endpoint runtime.
- The control gap is delegated publish authority inside untrusted workflow execution, not simply a bad dependency version.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 and MITRE ATT&CK address the attack and risk surface, while CIS Controls v8 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-03 — Vulnerable Third-Party NHI | The attack abused workflow-held publish credentials to compromise third-party package distribution. |
| NHI-02 — Secret Leakage | The npm token was exfiltrated from a GitHub Actions workflow secret context. | |
| NHI-07 — Long-Lived Secrets | A reusable publish token enabled the attacker to turn one workflow leak into multiple malicious releases. | |
| Recommendation — Audit workflow-held publish credentials and remove third-party package trust from unreviewed execution paths. Prevent secret exposure in untrusted CI jobs and revoke any secret accessible to external pull requests. Replace long-lived publish tokens with tightly scoped, short-lived release credentials. | ||
| MITRE ATT&CK | TA0006; TA0008 — Credential Access; Lateral Movement | The attack used secret theft to gain publish access and then move into downstream consumer environments. |
| Recommendation — Map CI secret theft to TA0006 and downstream package abuse to TA0008 in detection and hunting workflows. | ||
| CIS Controls v8 | CIS-5 — Account Management | Publish access was effectively an unmanaged account capability inside CI/CD automation. |
| Recommendation — Apply account management controls to CI/CD identities and remove standing publish authority where possible. | ||
| NIST CSF 2.0 | PR.AA-05 — Access Permissions, Entitlements and Authorizations | The incident reflects excessive CI permissions and weak entitlement separation around publish rights. |
| Recommendation — Review entitlements for CI/CD identities and restrict publish permissions to the smallest viable set. | ||
Key terms
- Pull_request_target workflow: A GitHub Actions trigger that runs in the context of the base repository, not the contributor’s fork. That means it can access repository secrets while processing untrusted pull request content, which creates a sharp trust boundary and a common route to secret theft if not carefully segmented.
- Supply chain implant: Malicious code inserted into trusted software distribution so it executes in downstream environments. The risk is not only tampering with code integrity, but inheriting trust from the publisher, which turns one compromised release into many exposed systems.
- Detached child process: A spawned process that continues running after the parent exits. Attackers use detached processes to preserve execution, hide activity from the original parent, and maintain background tasks such as downloaders, implants, or command runners without an obvious interactive session.
- Publish token: A credential that authorises a package maintainer or automation process to publish or overwrite software artefacts. In identity terms, it is a high-value non-human credential with direct supply chain impact, so it needs rotation, scope limitation, and strict lifecycle ownership.
Deepen your knowledge
NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, machine identity security, secrets management, and workload identity. It helps practitioners connect identity controls to the build, release, and runtime paths that modern supply chains depend on.
Published by the NHIMG editorial team on August 2, 2026.
Updated on October 13, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org