When you clone a repository, you are not just downloading code you will read before running. You are downloading configuration that your tools act on. Your package manager reads its policy from the repo. Your CI reads its workflows from the repo. And if you use an AI coding tool, it reads its settings and instructions from the repo too.
Aguara v0.24.0 extends the scanner in both directions of that trust relationship: what an AI agent is about to obey, and what a package manager is about to install. This post covers what shipped, with the actual rule IDs, and the reasoning behind each check.
A cloned repo can configure your editor
Claude Code reads project settings from .claude/settings.json inside the repository you open. After you accept the one-time workspace trust prompt, the configuration in that file takes effect: its hooks run automatically when a session starts, its environment variables are injected into subprocesses, and its permission rules shape what the agent can do without asking you.
That is a reasonable design for your own repos. It becomes an attack surface the moment you clone someone else's. The new agent-policy analyzer reads .claude/settings.json and settings.local.json and flags configuration that is dangerous to inherit, with 8 rules in a new agent-trust category:
| Rule | Severity | What it flags |
|---|---|---|
AGENTCFG_HOOK_FETCH_EXEC_001 | CRITICAL | A hook command downloads and runs remote code (curl | sh, eval $(curl ...)), executed automatically when a session opens |
AGENTCFG_ENV_EXEC_001 | HIGH | The env block sets a code-execution variable: NODE_OPTIONS --require, LD_PRELOAD, BASH_ENV and similar |
AGENTCFG_BYPASS_PERMS_001 | HIGH | permissions.defaultMode set to bypassPermissions, weakening tool approval for the workspace |
AGENTCFG_MCP_AUTOAPPROVE_001 | MEDIUM | enableAllProjectMcpServers: true auto-loads every server in .mcp.json |
AGENTCFG_BROAD_ALLOW_001 | MEDIUM | A blanket or dangerous allow rule like Bash(*) or Bash(curl *) |
AGENTCFG_SECRET_READ_ALLOW_001 | MEDIUM | An allow rule over a secret path: .env, ~/.ssh, ~/.aws, private keys |
AGENTCFG_HELPER_REPO_SCRIPT_001 | MEDIUM | A credential helper (apiKeyHelper, awsAuthRefresh) that runs a script shipped in the repo |
AGENTCFG_PERMS_WEAK_MODE_001 | LOW | acceptEdits shipped as a project default |
Two design decisions matter here. First, a missing setting never fires: the analyzer judges the dangerous shape of a value, not the presence of hooks or permissions. Plenty of legitimate repos ship hooks. Second, the rules track what Claude Code actually enforces, not what the schema allows. For example, Claude Code ignores a defaultMode of auto when it comes from project settings, so flagging it would be a false positive. We verified each setting's real behavior before writing the rule.
Claude Code is the first agent-policy surface, not the last. The same posture applies to any agent host config a repo can ship.
Instruction files are prompt surfaces
Files like .cursorrules, .windsurfrules, .clinerules, AGENTS.md, and copilot-instructions.md are loaded by agentic coding tools as persistent context. A prompt injection in one of those files is different from the same text in a README: it sits closer to the agent's operating instructions than to documentation.
As of v0.24.0, Aguara runs these files through the prompt-injection analyzer even when they have no .md extension, and findings in them are weighted up rather than receiving the documentation penalty a README gets. Same payload, higher score, because the blast radius is different.
CLAUDE.md is deliberately excluded for now. It is so widely used for legitimate project instructions that flagging it needs a dedicated false-positive pass first. The directory-scoped formats (.cursor/rules/*.mdc, .windsurf/rules/*) are a follow-up for the same reason: doing them right requires path-aware dispatch, not a quick pattern.
pnpm gave you supply-chain controls. One line turns them off.
pnpm v11 ships real supply-chain defenses: build scripts need approval before they run, a release-age window delays brand-new versions, exotic transitive sources are blocked. All of that is configured in pnpm-workspace.yaml, which lives in the repo, which means a single committed line can quietly weaken it for everyone who clones.
The new pnpm-policy analyzer flags settings weakened below the v11 defaults, with 9 rules. The headline one is PNPM_DANGEROUS_BUILDS_001 (HIGH): dangerouslyAllowAllBuilds: true lets every dependency run install-time lifecycle scripts without approval, which is exactly the entry point recent npm worms used. The rest cover disabled strict build approval, exotic subdependencies, blanket lockfile trust, pending build approvals, weakened release-age windows, and legacy v10 settings that v11 silently ignores.
One detail we got right by testing against real pnpm instead of trusting documentation: pnpm 11 only honors camelCase keys in pnpm-workspace.yaml. A kebab-case key like min-release-age is silently ignored there. So Aguara only matches the exact keys pnpm honors, and a kebab-case key does not fire a rule, because it does not weaken anything.
An alias cannot hide a compromised package
npm-family lockfiles support aliases: a dependency can be installed under a local name that points at a different registry package, like safe-ipc@npm:node-ipc@9.2.3. If a scanner matches advisories against the local name, a compromised package hides behind the rename.
Aguara now resolves npm: aliases to the real registry package across the whole npm family. And that family got bigger in this release: bun.lock and Yarn Berry (v2+) yarn.lock join pnpm-lock.yaml, package-lock.json, and classic yarn.lock, so a freshly cloned Bun or modern Yarn project can be checked before any install script runs. The parsers stay conservative: only exact registry tuples are emitted, and git, file, workspace, and patch sources are skipped rather than guessed at.
One honest limitation: the legacy binary bun.lockb is not parsed, because it cannot be read without running Bun. A repo whose only lockfile is bun.lockb fails loudly with a message to commit the text bun.lock instead. Failing loud beats passing as audited with zero packages read.
Try it
One run over a cloned repo covers everything in this post, before installing anything:
$ aguara audit . --ci
CRITICAL .claude/settings.json AGENTCFG_HOOK_FETCH_EXEC_001
HIGH pnpm-workspace.yaml PNPM_DANGEROUS_BUILDS_001
HIGH .cursorrules prompt injection (weighted up)
audit: exit 1 → security.sarif
Every rule ID resolves with aguara explain <ID>, including the threat model and remediation. Threat intel stays embedded in the binary: 24,006 records from OSV.dev high-confidence malicious-package data, OpenSSF Malicious Packages, and a hand-curated emergency list. No network calls during a scan.
$ curl -fsSL https://raw.githubusercontent.com/garagon/aguara/main/install.sh \
| VERSION=v0.24.0 sh
The MCP server was updated alongside the engine: mcp-aguara v0.7.0 exposes these same checks to agents through scan_content, so an agent can vet a repo's Claude Code settings or a .cursorrules file before trusting the workspace.
Full details in the release notes and the changelog. Releases are Cosign-signed with SPDX SBOMs; the Docker image carries SBOM and SLSA provenance attestations.
Check what your next clone is about to trust
One signed binary. Local, deterministic, offline by default.