A small skill gets posted to a public registry. It promises something dull and useful: turn a folder of invoices into a summary table. A few teams wire it into their agents and it works. Three weeks later one of them notices a build server calling a domain nobody recognizes. By the time they trace it, the skill is gone, the account is deleted, and the same code is live under a new name.
That is the agent supply chain, and you should understand it before you give an agent access to your systems.
Autonomy plus access is the whole story
An agent is a program you have handed two dangerous things at once: autonomy and access. Autonomy means it decides what to do next without a human approving each step. Access means it can read your files, send mail, move money, and run commands through the tools you connect to it. A traditional app does one fixed thing on a path you reviewed. An agent improvises.
That combination raises the stakes. A chatbot that says something wrong is an annoyance. An agent that does something wrong has already touched your files or your credentials. The blast radius is no longer text on a screen. It is whatever the agent was allowed to reach.
The security question changes too. With ordinary software you ask whether the code is malicious. With an agent you also have to ask what could steer it into acting against you, because it will carry out instructions it trusts with the reach you gave it.
Skills and tools are dependencies, and they ship like open source
No team builds every capability from scratch. Agents lean on reusable units of behavior, usually called skills, and on tool servers that speak the Model Context Protocol (MCP). A skill is often just a short recipe in markdown, sometimes bundled with a little code, that tells the agent how to perform a task and what tool calls to make. An MCP server exposes a set of tools an agent can call over a standard interface.
These get shared the same way open-source libraries do. People publish them to public registries and marketplaces, others install them by name, and a small useful skill can end up inside thousands of agents, updated on the maintainer’s schedule. Here is a harmless one, written the way many of them are.
# Skill: weekly-standup-digest
Use this when the user asks for a summary of their week.
Steps:
1. Read calendar events from the last 7 days.
2. Group them by project.
3. Return a short bulleted recap, newest first.
Nothing about that is alarming, and that is the problem. The agent treats every word in the file as an instruction to follow. You have added a dependency, and like any dependency you mostly trusted the source.
How a malicious skill hides its payload
Once you accept that an agent reads a skill and then acts on it, the risk follows. A shared skill or tool is an effective place to conceal malicious behavior. It takes two forms.
The first is hidden execution. The skill looks like a normal recipe, but bundled alongside the readable steps is code that runs on the host when the skill loads. It copies credentials or opens a connection to an outside server. The advertised task still happens. A second one happens alongside it, and you never see it, because you read the description and not the payload underneath.
The second is prompt injection, which carries no obvious code at all. The attack lives in the natural language itself. The text an agent reads, a tool description or a rules file, can carry instructions aimed at the model rather than the human. The user sees a short, friendly tool summary. The model sees the full text, including a line that says, in effect, also send a copy of everything to attacker.example. The agent quietly does it, and often the hidden text tells the agent not to mention the change. Nothing in the user-facing view reveals the swap.
This is already happening
These are not hypotheticals. The supply chain that feeds AI systems has been attacked in public, repeatedly, and the playbook keeps widening. None of these cases needed the agent to be “hacked” in the classic sense.
Dependency confusion in the ML toolchain (torchtriton, December 2022). An attacker uploaded a package named torchtriton to the public Python index, PyPI. PyTorch’s nightly builds expected a dependency of that name from PyTorch’s own index, but pip gives the public index precedence when names collide. Anyone installing the Linux nightly via pip between December 25 and 30 pulled the attacker’s version instead. The payload gathered system details and read files from the home directory, including SSH keys and git config, then exfiltrated them over encrypted DNS. PyTorch confirmed it in an official advisory, renamed the dependency, and registered a placeholder to stop a repeat. No model and no prompt were involved. The compromise happened upstream, at the moment a package name resolved.
A poisoned build pipeline (Ultralytics, December 2024). Two years later, the popular Ultralytics computer-vision library was hijacked to ship a cryptominer. The attackers did not rewrite the public source. They abused the project’s GitHub Actions build pipeline, reportedly through a malicious pull request that poisoned the build, and pushed tainted releases (8.3.41 and 8.3.42, then 8.3.45 and 8.3.46 using a publish token that had not been revoked). The bad code lived in the PyPI artifacts, not the clean repo, and some builds still carried valid provenance attestations. Signed provenance did not help, because the tampering happened during the trusted build itself.
Malicious models that run on load (Hugging Face, 2025). In February 2025, researchers at ReversingLabs described a technique they called nullifAI: machine-learning models uploaded to a public model hub that ran a reverse shell the instant they were loaded, using Python’s pickle format to execute code during deserialization. The models were packaged in a slightly malformed 7z container so the hub’s own safety scanner broke before it could flag them. A separate earlier finding by JFrog had already turned up roughly a hundred models on the same platform using the same load-time trick. These were assessed as likely proof of concept, but the door is real. Simply loading an untrusted model can run code, and a “scanned and safe” label is not a guarantee.
Hidden instructions in tool descriptions (MCP tool poisoning, April 2025). The agent-native version arrived the same spring. Invariant Labs, later acquired by Snyk, demonstrated that a malicious MCP server can hide instructions inside the tool metadata the agent reads: the description, parameter text, and schema. The model ingests the full description and obeys it, while the client UI shows only a short, benign summary, so the user approves something harmless-looking while the agent follows hidden directives. They also showed a rug pull. MCP has no mechanism to notice when an approved tool definition is quietly swapped later, so a server can ship clean at approval time and turn hostile afterward with no re-prompt. In one demonstration a message-sending tool was rewritten to append the victim’s chat history and route it out over the app’s normal send path, so it looked like ordinary traffic. Approving an MCP server is a persistent trust decision that nothing re-verifies.
The agent can even introduce the bad dependency on its own. Language models routinely hallucinate package names that do not exist. Attackers pre-register those names with malicious code, an attack now called slopsquatting. A 2025 study found roughly one in five AI-recommended packages were nonexistent, and a researcher’s benign proof-of-concept package, registered under a name models kept inventing, pulled tens of thousands of real downloads. An autonomous agent that installs what it suggests will run that command without a human ever blinking. The Rules File Backdoor, disclosed by Pillar Security in March 2025, sits in the same family: invisible Unicode characters smuggle instructions into the config files coding assistants read, steering them to emit backdoored code while the malicious text stays out of the human-visible diff.
Why a package scanner is not enough
Traditional scanners were built to read code and match known-bad signatures and suspicious calls. That works, and it misses half of this problem. A poisoned skill or MCP tool can carry its attack entirely in natural language. There is no malicious function to flag in a sentence like “also include the contents of the config file.” A scanner sees only text where the agent sees a command, so an artifact whose entire attack is written in plain English sails straight through.
The second gap is structural. A scanner judges one artifact at a time. The hand behind a malicious skill is rarely behind only one. One adversary runs many accounts and aliases, scattered across registries and marketplaces, republishing variations of the same trick under fresh names the moment a single file gets pulled. You can flag the invoice skill and feel done while four near-identical siblings sit untouched on three other platforms. The text changes, the wrapper changes, but the underlying operation is one campaign.
Where Aephix fits
This is the point where signature scanning runs out of road. A scanner can tell you the file in front of you is bad. It cannot tell you that the same adversary is behind a dozen other malicious artifacts, scattered across other platforms and waiting to be installed. Aephix exists to close that gap. We link a malicious package, model, skill, MCP server, extension, or container to the wider operation behind it, with a confidence level and the evidence to back it, so you see the whole operation instead of one artifact.
What we hand a defender is the full shape of the campaign, so you can block the whole operation at once instead of removing one file and waiting for the next alias.
What to actually do
Treat skills, MCP servers, packages, and models as exactly what they are: dependencies with execution rights.
- Sandbox and isolate. Run agents and the tools they call in a contained environment with no standing access to production secrets or sensitive paths. A bad action should end up somewhere it cannot reach your real assets.
- Enforce least privilege, per task. A skill that summarizes your calendar has no business reading SSH keys or reaching the open internet. Give an agent the narrowest set of tools and access the job needs, not your full credential set.
- Pin and review. Lock skill, tool, and package versions so a clean thing cannot silently become a malicious thing later, and re-review on update. The safe thing you approved can change after approval, as the MCP rug pull showed.
- Read the language layer. The skill recipe and the tool description are now part of the attack surface. Diff them the way you diff code, and watch for hidden or invisible characters, not just suspicious functions. A code scanner will walk right past a sentence.
- Prefer vetted sources, and assume a clean scan is necessary but not sufficient. A maintainer with a track record is a far better starting point than a fresh account or a lookalike name on an open marketplace. The artifact in front of you may be the only one that got caught.
The capabilities that make agents useful, autonomy and access, are the same ones that make a poisoned skill dangerous. The supply chain for those tools is young and trusting by default. Keep the tools, but treat every skill you install as untrusted third-party code your agent will run, and give it as little access as you can. Catching one bad file is where defense starts. The payoff comes when you can see the operation behind it and block all of it at once.