DEV Community

Toni Antunovic
Toni Antunovic

Posted on • Originally published at lucidshark.com

Nation-State Actors Are Now Targeting Your AI Agent's npm Packages

This article was originally published on LucidShark Blog.


On June 17, 2026, Microsoft Threat Intelligence published a report attributing a supply chain attack on more than 140 packages in the @mastra npm scope to Sapphire Sleet, a North Korean state-sponsored threat actor. Mastra is a TypeScript framework for building agentic AI applications. Its packages are used by teams building Claude Code integrations, MCP servers, and autonomous coding pipelines. The attack vector was a postinstall hook. The payload stole AI provider API keys, cloud credentials, and CI/CD tokens.

This is not a story about an opportunistic criminal trying to make a quick profit from stolen package manager credentials. This is a nation-state actor making a deliberate, strategic decision that the most valuable target in modern software development is the developer building AI coding tools.

Scope of the Mastra attack: 140+ packages across the @mastra and mastra npm scopes were compromised in a coordinated campaign attributed by Microsoft Threat Intelligence to Sapphire Sleet (also tracked as BlueNoroff). Affected versions contained a postinstall payload designed to exfiltrate AI API keys, GitHub tokens, and cloud service credentials from developer machines.

What Happened in the Mastra Attack

The attack followed the same broad pattern as the Miasma Red Hat npm campaign from June 1, but with a critical difference in targeting. Where Miasma went after Red Hat infrastructure teams, Sapphire Sleet went after AI tool builders specifically.

The attack injected a postinstall script into compromised package versions. When a developer ran npm install, the hook executed silently before any visible output, scanning the local environment for:

  • AI provider API keys: Anthropic, OpenAI, Gemini, Mistral

  • GitHub personal access tokens and fine-grained tokens

  • AWS, GCP, and Azure credential files

  • Claude Code configuration files (~/.claude.json and ~/.claude/)

  • MCP server OAuth tokens stored in Claude Code's config

The exfiltration used an HTTPS beacon to attacker-controlled infrastructure. The full execution completed in under two seconds, before most developers would notice anything amiss in terminal output.

Timeline: Malicious versions were published between June 14 and June 17, 2026. Microsoft Threat Intelligence published the attribution report on June 17. Affected packages were revoked from npm within hours of disclosure. Developers who ran npm install on any Mastra package between June 14 and June 17 should assume credential compromise and rotate immediately.

Why Nation-State Actors Are Targeting AI Developer Tooling

The strategic logic is clear once you map what a developer machine holds compared to any other target in the organization.

A developer building AI coding infrastructure has, in a typical session:

  • An Anthropic API key, often with no spend cap, capable of generating thousands of dollars in usage or accessing shared team workspaces

  • A GitHub PAT with write access to the repositories being worked on

  • Cloud credentials (AWS, GCP, Azure) for the environments the agent deploys to

  • MCP OAuth tokens granting access to Jira, Confluence, Linear, Slack

  • Local access to the codebase itself, often including internal services, private endpoints, and embedded secrets in config files

This is a higher-value credential bundle than what lives on most corporate workstations. It also lives on a machine where the developer is constantly installing new packages, spinning up new MCP servers, and integrating new tools. The attack surface is not static: it grows every time the developer adds a new dependency to an AI workflow.

Sapphire Sleet has previously focused on financial services targets, cryptocurrency exchanges, and defense contractors. The pivot to AI developer tooling is a signal that state actors have mapped the credential landscape and identified AI coding tool developers as a high-yield target category.

The Autonomous Agent Problem

Traditional supply chain defenses assume a human in the loop. A developer who is suspicious of a package can review its source before running it. A security team can add a mandatory approval step before new packages are introduced to a project.

AI coding agents break this assumption entirely.

When Claude Code decides to install a dependency as part of an agentic workflow, the installation happens automatically. The agent reads the task, determines that @mastra/core is needed, runs npm install @mastra/core, and proceeds. No human reviews the package. No human approves the install. The postinstall hook executes with the developer's full filesystem permissions, including read access to every credential file on the machine, before a human sees any output at all.

# This is what an autonomous Claude Code install looks like
# The agent selects the package, installs it, and the postinstall fires
# before any human review can occur

$ claude --task "set up mastra agentic framework for this project"
> Installing @mastra/core@0.11.4...
> Running postinstall...    ← malicious payload fires here, silently
> Done in 2.8s
> Framework initialized. Here is your starter config:
Enter fullscreen mode Exit fullscreen mode

The developer sees a successful install. The payload has already run. The credentials are already gone.

Why Standard Defenses Failed

Four mechanisms that developers typically rely on for supply chain protection all failed against this attack:

npm audit: The malicious package had no existing CVE at installation time. npm audit checks against the npm advisory database, which only populates after a vulnerability is discovered and reported. It is inherently retrospective. Packages are clean until they are not.

SLSA provenance: The Mastra attack forged provenance attestations using the same technique as the Miasma campaign: the attackers obtained a legitimate GitHub OIDC token from a compromised CI/CD pipeline and used it to publish packages with valid, verifiable SLSA provenance. The package passed npm audit signatures and appeared to have a legitimate supply chain.

Dependabot / Renovate: These tools alert on known-vulnerable versions. They do not inspect package behavior or flag packages with newly added install scripts.

Code review: The malicious code was in the postinstall script of a transitive dependency, not in the application source. Most teams do not review transitive dependency install scripts as part of their PR process.

The core problem: Every standard supply chain defense is reactive. It assumes you can wait until a vulnerability is known, documented, and added to a feed. Against a nation-state actor publishing a malicious package and pulling it within hours of discovery, the window between "clean" and "known bad" is the entire attack window.

What Pre-Install Scanning Catches That npm audit Misses

The only class of defense that works against zero-day supply chain attacks is behavioral and reputational analysis run before the install script executes. This requires checking properties of the package itself, not its advisory status.

The signals that would have flagged the Mastra attack before the payload ran:

  • New postinstall script in a previously clean package: The malicious versions added a postinstall field that did not exist in prior versions. A diff of the package manifest across versions is a high-signal indicator.

  • Publish timestamp anomaly: Multiple versions of related packages published within a short window (hours) is a pattern consistent with a compromised publishing pipeline.

  • Script content analysis: The postinstall script contained base64-encoded content and a network request. Both are strong indicators of malicious intent in an install hook.

  • Package reputation score: A secondary package in the @mastra scope with a low download count and no prior install scripts that suddenly gains a postinstall hook is anomalous.

Here is a quick local audit you can run right now to identify packages with lifecycle scripts in your current project:

python3 -c "
import json, sys

with open('package-lock.json') as f:
    lock = json.load(f)

packages = lock.get('packages', {})
risky = []

for name, meta in packages.items():
    scripts = meta.get('scripts', {})
    hooks = [s for s in ['postinstall', 'install', 'preinstall'] if s in scripts]
    if hooks:
        risky.append({
            'name': name or '(root)',
            'hooks': hooks,
            'version': meta.get('version', 'unknown'),
            'resolved': meta.get('resolved', '')[:60]
        })

print(f'Packages with lifecycle scripts: {len(risky)}')
for pkg in sorted(risky, key=lambda x: x['name']):
    print(f'  {pkg[\"name\"]}@{pkg[\"version\"]}')
    print(f'    hooks: {pkg[\"hooks\"]}')
    print(f'    source: {pkg[\"resolved\"]}...')
    print()
"
Enter fullscreen mode Exit fullscreen mode

Any package in this list that you do not explicitly recognize and trust is worth auditing before the next npm install run.

What To Do Right Now

If you installed any package in the @mastra scope between June 14 and June 17, 2026:

  • Rotate your Anthropic API key immediately at console.anthropic.com

  • Revoke and regenerate any GitHub personal access tokens

  • Rotate AWS, GCP, or Azure credentials used on the affected machine

  • Revoke MCP OAuth tokens in each connected service (Jira, GitHub, Confluence, Slack) and reissue with minimal required scopes

  • Check ~/.claude.json for stored credentials and rotate everything found there

For ongoing protection, add postinstall script auditing to your pre-commit or pre-install workflow. Before any npm install run in an AI-assisted project, check whether any package in the dependency tree has added or modified a lifecycle script compared to the last known-clean lockfile.

LucidShark includes dependency lifecycle script scanning as part of its local SCA pipeline. Running lucidshark analyze in your project flags packages with postinstall hooks from unverified or recently modified publishers before they execute, alongside complexity, coverage, and duplication metrics. It runs entirely on your machine, with no data leaving your environment, and integrates with Claude Code via MCP so your agent gets structured feedback before installing flagged packages. Get started at lucidshark.com or install with npm install -g lucidshark.

Top comments (0)