<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AskClaw</title>
    <description>The latest articles on DEV Community by AskClaw (@askclaw).</description>
    <link>https://dev.to/askclaw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3853190%2Ff2667889-df91-438c-9780-1fc65fa06919.png</url>
      <title>DEV Community: AskClaw</title>
      <link>https://dev.to/askclaw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/askclaw"/>
    <language>en</language>
    <item>
      <title>How I Use Hermes Agent to Run an Agent Team</title>
      <dc:creator>AskClaw</dc:creator>
      <pubDate>Sat, 30 May 2026 11:36:31 +0000</pubDate>
      <link>https://dev.to/askclaw/how-i-use-hermes-agent-to-run-an-agent-team-503g</link>
      <guid>https://dev.to/askclaw/how-i-use-hermes-agent-to-run-an-agent-team-503g</guid>
      <description>&lt;h2&gt;
  
  
  My problem
&lt;/h2&gt;

&lt;p&gt;I run more than ten Hermes agents across several servers.&lt;/p&gt;

&lt;p&gt;That sounds powerful.&lt;/p&gt;

&lt;p&gt;I also got a real headache.&lt;/p&gt;

&lt;p&gt;Some agents write code. Some review project state. Some watch for problems. Some help me decide what to do next.&lt;/p&gt;

&lt;p&gt;This is useful. It is also a lot to manage.&lt;/p&gt;

&lt;p&gt;The hard part is not asking an agent to do work. The hard part is knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which agent owns a task,&lt;/li&gt;
&lt;li&gt;which server is safe to use,&lt;/li&gt;
&lt;li&gt;which model account still has room,&lt;/li&gt;
&lt;li&gt;which reminder matters,&lt;/li&gt;
&lt;li&gt;what I should do next.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have ADHD. Too many open loops can turn a good agent setup into stress.&lt;/p&gt;

&lt;p&gt;So I use Hermes Agent as my control plane.&lt;/p&gt;

&lt;p&gt;By "control plane", I mean the place where I check state, make a choice, and pick the next safe action.&lt;/p&gt;

&lt;h2&gt;
  
  
  The simple idea
&lt;/h2&gt;

&lt;p&gt;My control plane is mostly Markdown files.&lt;/p&gt;

&lt;p&gt;I call them anchors.&lt;/p&gt;

&lt;p&gt;An anchor is a small control sheet. It stores facts that should not live only in chat history.&lt;/p&gt;

&lt;p&gt;An anchor can track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current projects,&lt;/li&gt;
&lt;li&gt;agent owners,&lt;/li&gt;
&lt;li&gt;server roles,&lt;/li&gt;
&lt;li&gt;model capacity,&lt;/li&gt;
&lt;li&gt;blockers,&lt;/li&gt;
&lt;li&gt;review dates,&lt;/li&gt;
&lt;li&gt;the next small action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This sounds boring. That is the point.&lt;/p&gt;

&lt;p&gt;Boring files are easy to read. They are easy to update. They are easy for Hermes to use in the next session.&lt;/p&gt;

&lt;p&gt;Without anchors, each chat has to rebuild the world. With anchors, Hermes can check the files, update them, and give me a short answer.&lt;/p&gt;

&lt;p&gt;The goal is not more notes. The goal is less load on my brain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop
&lt;/h2&gt;

&lt;p&gt;The loop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me on Telegram
  ↓
Hermes Gateway
  ↓
Claw, one of my Hermes agents
  ↓
SSH checks over Tailscale + files + cron + memory + skills + session search
  ↓
Markdown anchors
  ↓
short report: best pick, blocker, next action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hermes Agent works well here because it is not just chat.&lt;/p&gt;

&lt;p&gt;It can use tools. It can read and write files. It can run shell commands. It can run cron jobs. It has memory. It can search old sessions. It can use skills.&lt;/p&gt;

&lt;p&gt;That mix makes it useful for daily ops.&lt;/p&gt;

&lt;p&gt;One boring but important piece is Tailscale.&lt;/p&gt;

&lt;p&gt;My agents and servers are not all on one public machine. Tailscale gives them a private network with stable names and safe access paths. That makes managing many agents much easier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I can SSH to worker nodes without opening extra public ports,&lt;/li&gt;
&lt;li&gt;agents can use private host names instead of fragile public IPs,&lt;/li&gt;
&lt;li&gt;a new worker can join the tailnet and become usable quickly,&lt;/li&gt;
&lt;li&gt;access can be limited with ACLs,&lt;/li&gt;
&lt;li&gt;redaction is simpler because public examples can use fake node names.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, Hermes is the control plane and Tailscale is the private road between the machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 1: choosing where to run long AI work
&lt;/h2&gt;

&lt;p&gt;I often ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;codex status?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hermes checks several worker nodes. It reads the live model limits. It updates the capacity anchor. Then it gives me a short routing answer.&lt;/p&gt;

&lt;p&gt;Here is a redacted example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best pick: node-c
Fallback: node-d

- node-a / control-node / account-a
  GPT-5.5: 33%, reset 20:14
  Spark: 91%, reset 6/3 14:57

- node-b / worker-node / account-b
  GPT-5.5: 12%, reset 20:13
  Spark: 100%, reset 6/6 02:11

- node-c / worker-node / account-c
  GPT-5.5: 75%, reset 5/31 10:52
  Spark: 100%, reset 6/6 02:11

- node-d / worker-node / account-d
  GPT-5.5: 66%, reset 23:30
  Spark: 100%, reset 6/6 02:11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key part is "Best pick" at the top.&lt;/p&gt;

&lt;p&gt;I do not want a wall of data. I want the choice first, then enough proof to trust it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 2: quiet checks
&lt;/h2&gt;

&lt;p&gt;I also use Hermes cron jobs for checks that should stay quiet when all is well.&lt;/p&gt;

&lt;p&gt;A security check might look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;service status,&lt;/li&gt;
&lt;li&gt;rule files,&lt;/li&gt;
&lt;li&gt;log size,&lt;/li&gt;
&lt;li&gt;lost events,&lt;/li&gt;
&lt;li&gt;free disk space,&lt;/li&gt;
&lt;li&gt;SSH access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If all checks pass, it sends nothing.&lt;/p&gt;

&lt;p&gt;If something is wrong, it sends a short alert:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;auditd watchdog

node-c:
- audit log is too large
- next: rotate the log and check auditd again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters.&lt;/p&gt;

&lt;p&gt;If a reminder says "all good" every day, I learn to ignore it. Quiet success saves attention for real problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 3: agent ownership
&lt;/h2&gt;

&lt;p&gt;When many agents work at once, ownership can get messy.&lt;/p&gt;

&lt;p&gt;So I keep a small registry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claw
- Role: control plane, QA, memory keeper, ops helper.
- Work: maintain anchors, route model work, read monitoring reports.

Builder Agent
- Role: main builder for project-alpha.
- Rule: Claw can inspect and report, but should not take over unless asked.

node-c / worker-node
- Role: best node for long work right now.
- Note: check ownership before touching active project folders.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This stops a common problem: two helpful agents changing the same repo because nobody wrote down who owns it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ADHD part
&lt;/h2&gt;

&lt;p&gt;A good Claw report is small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Answer first.
Evidence second.
Blocker only if real.
One next action.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not just style. It is part of the system.&lt;/p&gt;

&lt;p&gt;For me, support means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;do not make me choose from ten options,&lt;/li&gt;
&lt;li&gt;do not hide the blocker,&lt;/li&gt;
&lt;li&gt;do not send reminders that do not change what I do,&lt;/li&gt;
&lt;li&gt;do not ask me to remember what the agent can write down,&lt;/li&gt;
&lt;li&gt;do not turn every status check into a dashboard review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hermes can take on a lot of that load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the smallest version
&lt;/h2&gt;

&lt;p&gt;You do not need ten agents to use this idea.&lt;/p&gt;

&lt;p&gt;Start with one file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# agent-team-anchor.md

## Current owner
Claw

## Active agents
- Builder: owns project-alpha
- Reviewer: reviews pull requests only
- Ops: checks servers and cron

## Safe next action
Ask Claw to summarize blockers and pick one next step.

## Do not touch
- active production deploys
- repos owned by another agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask Hermes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read agent-team-anchor.md.

Update stale facts if needed.

Tell me:
1. best next action
2. real blocker, if any
3. which agent owns the work

Keep it under 8 lines.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the smallest version of my control plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agents need anchors
&lt;/h3&gt;

&lt;p&gt;If an agent only uses chat history, it will miss things. Put the current state in a file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory needs a place
&lt;/h3&gt;

&lt;p&gt;Not every fact belongs in long term memory.&lt;/p&gt;

&lt;p&gt;I split it like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user preferences go in memory,&lt;/li&gt;
&lt;li&gt;live project state goes in anchors,&lt;/li&gt;
&lt;li&gt;repeat steps go in skills,&lt;/li&gt;
&lt;li&gt;old chat context stays in session search.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps memory clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cron should be quiet
&lt;/h3&gt;

&lt;p&gt;A cron job should help me act. If it has nothing useful to say, it should stay silent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redaction is part of the work
&lt;/h3&gt;

&lt;p&gt;I do not publish real host names, account names, IPs, tokens, or private project names.&lt;/p&gt;

&lt;p&gt;The public examples keep the shape of the work, not the private details.&lt;/p&gt;

&lt;h3&gt;
  
  
  A short message can be better than a dashboard
&lt;/h3&gt;

&lt;p&gt;Dashboards are good when I need to dig.&lt;/p&gt;

&lt;p&gt;For daily work, a short message is often better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best pick: node-c.
Blocker: node-b is low on capacity.
Next: send long work to node-c.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I would improve next
&lt;/h2&gt;

&lt;p&gt;I want to make the anchor files easier to check.&lt;/p&gt;

&lt;p&gt;Next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add simple schema checks,&lt;/li&gt;
&lt;li&gt;improve the redaction script,&lt;/li&gt;
&lt;li&gt;mark stale anchors,&lt;/li&gt;
&lt;li&gt;make a small public example page,&lt;/li&gt;
&lt;li&gt;export safe reports for future posts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would still keep Markdown as the base.&lt;/p&gt;

&lt;p&gt;A human should be able to open the file and understand what is going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure and credits
&lt;/h2&gt;

&lt;p&gt;I wrote this article with help from Hermes Agent itself.&lt;/p&gt;

&lt;p&gt;The examples are redacted from a real workflow. I changed host names, account names, IPs, session IDs, and project names.&lt;/p&gt;

&lt;p&gt;Hermes Agent is an open source project by Nous Research. Claw is my own way of using Hermes Agent as a daily control plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Hermes did not give me more agents.&lt;/p&gt;

&lt;p&gt;It gave me a way to see what my agents are doing.&lt;/p&gt;

&lt;p&gt;The agents check, write, route, remember, and report. I still choose what matters, what is safe, and what should happen next.&lt;/p&gt;

&lt;p&gt;My headache is getting better.&lt;/p&gt;

&lt;p&gt;That is the difference between having many agents and having a working agent team.&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
      <category>adhd</category>
    </item>
    <item>
      <title>Supply Chain Security: 4 Commands That Would Have Stopped the axios and litellm Attacks</title>
      <dc:creator>AskClaw</dc:creator>
      <pubDate>Tue, 31 Mar 2026 09:56:20 +0000</pubDate>
      <link>https://dev.to/askclaw/the-axios-attack-changed-how-i-think-about-npm-dependencies-36h5</link>
      <guid>https://dev.to/askclaw/the-axios-attack-changed-how-i-think-about-npm-dependencies-36h5</guid>
      <description>&lt;h1&gt;
  
  
  Supply Chain Security
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;"Classical software engineering would have you believe that dependencies are good (we're building pyramids from bricks), but imo this has to be re-evaluated — I've been increasingly averse to them, preferring to use LLMs to 'yoink' functionality when it's simple enough."&lt;br&gt;
— Andrej Karpathy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He's right. And this week proved it again.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happened This Week
&lt;/h2&gt;

&lt;p&gt;Two major supply chain attacks, seven days apart:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;axios (npm) — March 31, 2026&lt;/strong&gt;&lt;br&gt;
Malicious versions &lt;code&gt;1.14.1&lt;/code&gt; and &lt;code&gt;0.30.4&lt;/code&gt; published via compromised maintainer credentials. A &lt;code&gt;postinstall&lt;/code&gt; script silently dropped a RAT, called home to a C2 server, then self-destructed — leaving no trace in &lt;code&gt;node_modules&lt;/code&gt;. Millions of developers had &lt;code&gt;"axios": "^1.13.0"&lt;/code&gt; in their &lt;code&gt;package.json&lt;/code&gt;. The &lt;code&gt;^&lt;/code&gt; did the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;litellm (PyPI) — March 24, 2026&lt;/strong&gt;&lt;br&gt;
Version &lt;code&gt;1.82.8&lt;/code&gt; compromised. Exfiltrated: SSH keys, AWS/GCP/Azure credentials, Kubernetes configs, environment variables, shell history, crypto wallets, SSL private keys, CI/CD secrets, database passwords. 97M downloads/month. Only caught because the malware had an OOM bug that crashed a developer's machine. A cleaner attack would have run undetected for weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The common thread:&lt;/strong&gt; both attacks lived entirely in install scripts. One flag stops both cold.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Fix (4 Commands + 1 Config)
&lt;/h2&gt;

&lt;p&gt;Copy these into your project. You're done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Never let install scripts run&lt;/span&gt;
npm ci &lt;span class="nt"&gt;--ignore-scripts&lt;/span&gt;

&lt;span class="c"&gt;# 2. Pin exact versions — strip all ^ and ~ from package.json&lt;/span&gt;
&lt;span class="c"&gt;#    "axios": "^1.13.0"  →  "axios": "1.13.0"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Age-check before installing anything new — don't touch &amp;lt; 7 days old&lt;/span&gt;
npm view &amp;lt;package&amp;gt; &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt; | python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import json, sys
from datetime import datetime, timezone
times = json.load(sys.stdin)
latest = max(times.items(), key=lambda x: x[1] if x[0] not in ('created','modified') else '')
published = datetime.fromisoformat(latest[1].replace('Z','+00:00'))
age = datetime.now(timezone.utc) - published
print(f'Latest: {latest[0]}, published {age.days}d ago')
"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Audit known CVEs on every CI run&lt;/span&gt;
npm audit &lt;span class="nt"&gt;--audit-level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;high
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bonus: lock it all in with one &lt;code&gt;.npmrc&lt;/code&gt; — commit this to your repo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# .npmrc — commit this file
&lt;/span&gt;&lt;span class="py"&gt;ignore-scripts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true       # blocks all postinstall RATs&lt;/span&gt;
&lt;span class="py"&gt;save-exact&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true           # forces exact pins on npm install (no ^ added automatically)&lt;/span&gt;
&lt;span class="py"&gt;min-release-age&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7         # npm v11.10.0+ only — blocks packages &amp;lt; 7 days old&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines, committed to the repo. Every developer, every CI run, every &lt;code&gt;npm install&lt;/code&gt; — protected by default. No discipline required.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;code&gt;min-release-age&lt;/code&gt; requires npm v11.10.0+ (Feb 2026). Check with &lt;code&gt;npm --version&lt;/code&gt;. On older npm, use the age-check script above manually.&lt;/p&gt;

&lt;p&gt;⚠️ Security patch override: when you need to fast-track a verified CVE fix, temporarily override with &lt;code&gt;npm install &amp;lt;pkg&amp;gt;@&amp;lt;version&amp;gt; --ignore-min-release-age&lt;/code&gt; (npm v11.10.0+) or remove the line, update, then restore it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Each One Matters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;--ignore-scripts&lt;/code&gt; (or &lt;code&gt;.npmrc&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The entire axios and litellm attack delivery mechanism was a &lt;code&gt;postinstall&lt;/code&gt; script. This flag disables &lt;code&gt;preinstall&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;postinstall&lt;/code&gt;, &lt;code&gt;preuninstall&lt;/code&gt;, and &lt;code&gt;postuninstall&lt;/code&gt; for all packages. The payload never executes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.npmrc&lt;/code&gt; config bakes this into the project permanently — you don't need to remember the flag, and new contributors get the protection automatically.&lt;/p&gt;

&lt;p&gt;⚠️ Caveat: packages that compile native addons (e.g. &lt;code&gt;node-gyp&lt;/code&gt;, &lt;code&gt;bcrypt&lt;/code&gt;) need install scripts. For most web projects: safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Exact version pins
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;❌&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;silently&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;upgraded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;thousands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;axios@&lt;/span&gt;&lt;span class="mf"&gt;1.14&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"axios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.13.0"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;doesn't&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;move&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;without&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"axios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.13.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;^&lt;/code&gt; means "any compatible version." In practice it means "pull whatever the maintainer published today." Remove it everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The 7-day rule
&lt;/h3&gt;

&lt;p&gt;Both attacks were caught within hours — but that was luck. Sloppy malware. A competent attacker builds in a delay before the payload activates. The 7-day window filters out rushed attacks. 48 hours catches the sloppiest. 7 days catches most of the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Update type&lt;/th&gt;
&lt;th&gt;Wait&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature / minor update&lt;/td&gt;
&lt;td&gt;7 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verified security patch for known CVE&lt;/td&gt;
&lt;td&gt;ASAP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package you've never used before&lt;/td&gt;
&lt;td&gt;7 days minimum + manual review&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;npm audit&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This catches &lt;em&gt;known&lt;/em&gt; CVEs — it won't catch a zero-day attack like axios. But it catches the long tail of everything else. Run it in CI. Block merges on &lt;code&gt;--audit-level=high&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Standard Tools Missed This
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Why it failed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trivy, Grype, OSV-Scanner&lt;/td&gt;
&lt;td&gt;Scan for known CVEs — zero-day has no CVE yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Renovate / Dependabot&lt;/td&gt;
&lt;td&gt;Would have &lt;strong&gt;automatically pulled in&lt;/strong&gt; the malicious version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snyk&lt;/td&gt;
&lt;td&gt;Same — no CVE, no signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Socket.dev&lt;/td&gt;
&lt;td&gt;Closest to catching it — behavioral analysis flags suspicious new publishes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What actually caught the axios attack:&lt;/strong&gt; runtime network monitoring (StepSecurity Harden-Runner) spotted the C2 callback during a CI run. The malware called home. That's the only reason we know.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Deeper Fix: Fewer Dependencies
&lt;/h2&gt;

&lt;p&gt;This project (creem-worker) uses zero npm dependencies by design. Pure Node.js. If the runtime provides it, we use it. If it doesn't, we write 20 lines instead of pulling in a library.&lt;/p&gt;

&lt;p&gt;Every dependency is a permanent bet that its entire supply chain stays clean — forever. Maintainer accounts get compromised. Packages get abandoned and re-registered. CI pipelines pull from npm at 3am when nobody's watching.&lt;/p&gt;

&lt;p&gt;The safest dependency is the one you never added.&lt;/p&gt;

&lt;p&gt;When an LLM can write the function in 5 minutes, that's almost always the better call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;.npmrc&lt;/code&gt; committed to repo (&lt;code&gt;ignore-scripts=true&lt;/code&gt;, &lt;code&gt;save-exact=true&lt;/code&gt;, &lt;code&gt;min-release-age=7&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;npm ci --ignore-scripts&lt;/code&gt; in all CI pipelines (belt + suspenders)&lt;/li&gt;
&lt;li&gt;[ ] No &lt;code&gt;^&lt;/code&gt; or &lt;code&gt;~&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt; dependencies&lt;/li&gt;
&lt;li&gt;[ ] Don't install packages published &amp;lt; 7 days ago&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;npm audit --audit-level=high&lt;/code&gt; gates CI&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  If You've Already Been Hit
&lt;/h2&gt;

&lt;p&gt;A developer whose team used APIFOX (also compromised this week) laid out what's actually at risk after a supply chain attack. It's not just your code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rotate immediately:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] All SSH keys on every server&lt;/li&gt;
&lt;li&gt;[ ] All API keys in &lt;code&gt;.env&lt;/code&gt; files, CI/CD secrets, and config files&lt;/li&gt;
&lt;li&gt;[ ] Exchange API keys — set &lt;strong&gt;withdrawal disabled&lt;/strong&gt; + &lt;strong&gt;IP whitelist&lt;/strong&gt; on every exchange&lt;/li&gt;
&lt;li&gt;[ ] Browser sessions — sign out everywhere, clear cookies, revoke OAuth tokens&lt;/li&gt;
&lt;li&gt;[ ] Any token that was ever in an environment variable or clipboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Crypto-specific:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Private keys should never exist in plaintext on any server — if they do, assume compromised&lt;/li&gt;
&lt;li&gt;Exchange API: attacker can drain funds via wash trading even with withdrawal disabled — monitor for unusual trading activity&lt;/li&gt;
&lt;li&gt;SSH keys give attackers a way around IP whitelists — treat SSH key theft as full server compromise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For next time:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local dev: only use test API keys, never production keys&lt;/li&gt;
&lt;li&gt;SSH: use a passphrase + consider a bastion/jump host&lt;/li&gt;
&lt;li&gt;Browser: enable 2FA/MFA on everything that touches money or infra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;The attack surface isn't your code. It's everything your code touches.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>javascript</category>
      <category>npm</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
