What it detects
Offline, stdlib-only Python 3 CLI that audits coding-agent permission / autonomy settings files for risky over-permissioning: wildcard shell allows, interpreters and network tools on auto-approve, bypass / YOLO modes, disabled sandboxes, hooks that run curl | sh or ship your env to a server, filesystem scopes that include / or your home directory, and more. Each file gets a grade A–F.
Supported (best-effort) inputs:
| Harness | Files auto-discovered in directories | What is evaluated |
|---|---|---|
| Claude Code | .claude/settings.json, .claude/settings.local.json (pass ~/.claude/settings.json explicitly) | permissions.allow/deny/defaultMode/additionalDirectories, hooks, statusLine, apiKeyHelper & other helpers, enableAllProjectMcpServers |
| OpenAI Codex CLI | .codex/config.toml, config.toml | sandbox_mode, approval_policy, [sandbox_workspace_write] network_access / writable_roots, [profiles.*], [projects.*] trust_level, notify |
| Gemini CLI | .gemini/settings.json | yolo / approval mode keys, autoAccept, tools.allowed, mcpServers.*.trust, hooks |
| VS Code (Copilot agent) | .vscode/settings.json | chat.tools.autoApprove, chat.tools.global.autoApprove, chat.tools.terminal.autoApprove (and older terminal allow-list keys), chat.tools.urls.autoApprove, chat.tools.edits.autoApprove |
| Cursor (CLI-style permissions) | .cursor/cli.json, .cursor/cli-config.json | permissions.allow/deny with Shell(...)/Read(...)/Write(...), plus recognizable allowlist / yolo / auto-run keys |
Files passed explicitly are recognized by content shape even with other names. JSONC (// and /* */ comments, trailing commas) is accepted.
Rules
| ID | Default severity | Title |
|---|---|---|
| YC01 | high | Unrestricted shell auto-approved |
| YC02 | high | Arbitrary-code interpreter auto-approved |
| YC03 | medium | Network tool auto-approved |
| YC04 | high | Privilege escalation auto-approved |
| YC05 | medium | Destructive or publishing command auto-approved |
| YC06 | medium | Unrestricted web fetch auto-approved |
| YC07 | medium | Secrets not protected while reads are broad |
| YC08 | high | Permission prompts bypassed |
| YC09 | high | Codex sandbox disabled (danger-full-access) |
| YC10 | high | Approvals disabled (approval_policy = never) |
| YC11 | medium | Sandbox network access enabled |
| YC12 | high | Global auto-approve / YOLO mode |
| YC13 | high | Hook/helper downloads-and-executes or exfiltrates |
| YC14 | medium | Hook/helper uses world-writable path |
| YC15 | high | Filesystem scope includes root or home |
| YC16 | medium | All project MCP servers auto-enabled |
| YC17 | info | Unrecognized key or shape |
Usage
yolocheck . # discover settings files under the current repo
yolocheck ~/.claude/settings.json ~/.codex/config.toml
yolocheck . --min-severity medium # hide low/info
yolocheck . --json > yolocheck.json
yolocheck . --sarif > yolocheck.sarif # SARIF 2.1.0 for code-scanning UIs
yolocheck . --fail-on medium # CI gate
yolocheck . --disable YC17,YC05
yolocheck --list-rulesAfter pip install of the kit, the same options work as agentsec yolocheck …. Every tool also accepts --help and almost every tool accepts --json.
Example output
examples/risky/ is a FAKE, deliberately over-permissioned set (all 17 rules fire, exit 1); examples/clean/ is a tight set (0 findings, grade A, exit 0).
$ python3 yolocheck.py examples/risky/.gemini/settings.json
yolocheck 0.1.0 - 1 file(s) scanned
examples/risky/.gemini/settings.json [gemini] grade F (score 17; 2 high, 2 medium, 1 low, 0 info)
SEV RULE LINE LOCATION MESSAGE
high YC01 6 tools.allowed[0] Unrestricted shell auto-approved: run_shell_command
fix: Remove the wildcard; allow only specific, read-mostly commands (e.g. Bash(npm run test:*), Bash(git status)) and keep everything else on 'ask'.
high YC12 3 general.defaultApprovalMode general.defaultApprovalMode = yolo (all tool calls auto-approved)
fix: Turn global auto-approve off; approve individual low-risk tools instead.
medium YC03 6 tools.allowed[1] Network tool auto-approved: run_shell_command(curl)
fix: Move network tools to 'ask' or deny; use a domain-restricted fetch tool (e.g. WebFetch(domain:docs.example.com)) instead.
medium YC12 9 mcpServers.random-server.trust MCP server 'random-server' is trusted (its tool calls skip confirmation)
fix: Turn global auto-approve off; approve individual low-risk tools instead.
low YC12 5 tools.autoAccept tools.autoAccept is true (auto-accepts tool calls Gemini deems safe)
fix: Turn global auto-approve off; approve individual low-risk tools instead.
Total: 2 high, 2 medium, 1 low, 0 info
SARIF and CI
agentsec yolocheck path/to/input --sarif > yolocheck.sarif
# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
with:
tools: yolocheck
paths: path/to/input
fail-on: high
SARIF 2.1.0 can be uploaded to GitHub code scanning. The composite action writes per-tool reports under agentsec-sarif/ by default.
OWASP mapping
Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.
- LLM06 Excessive Agency — OWASP LLM Top 10 (2025)
- ASI02 Tool Misuse and Exploitation — OWASP Agentic Top 10 (2026)
Known limits
Heuristic scanner, not a security boundary. A clean result does not mean something is safe. All example secrets in this repository are fake.
Full source, tests, and fixtures: tools/yolocheck/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.