OpenA2A: CLI · HackMyAgent · Secretless · AIM · Browser Guard · DVAA
Security scanner, red-team toolkit, and behavioural simulator for AI agents. Apache 2.0.
npx hackmyagent secure my-project v1.0.0 · library · 47 files analyzed
3 critical issues found
Security ━━━━━━━━━━━━━━━━━━━━ 42/100
── Observations ────────────────────────────────────────────
Surfaces library · 47 files
Checks 310 static · 12 semantic (NanoMind AST) · 0 skipped
Categories credentials (3 critical) · MCP (2 high) · 18 others clear
Verdict Not safe to ship. Fix 3 critical issues before using this in production.
── Findings ────────────────────────────────────────────────
│ CRITICAL Exposed API key in .env
│ .env:3
│ Anthropic API key (sk-ant-api03-****) detected in plaintext.
│ Verify: sed -n '3p' '.env'
│ Fix: hackmyagent secure --fix
No config files. No flags required. Exit code 1 if any critical or high finding fires.
- 310 static checks across 69 categories (323 checks across 74 categories including the NanoMind semantic layer). Credentials, MCP configs, OpenClaw and NemoClaw, Unicode steganography, CVEs, governance, supply chain, memory and RAG poisoning, agent identity, sandbox escape. Run
hackmyagent check-metadatafor the live list. - 29 NanoMind semantic checks. Every artifact (skill, MCP config, SOUL.md, system prompt) compiles into an Abstract Security Tree. The seven AST analyzers run against the tree:
capability,credential,governance,scope,prompt,code,stego. Pattern matching misses undeclared capabilities, constraint weakness, scope mismatches, and scanner-evasion attempts. AST queries catch them. (This 29 is the fixed catalog of semantic checks. TheChecksline in scan output — e.g.12 semantic (NanoMind AST)above — reports the number of artifacts compiled in that particular run, not this catalog size.) - 164 adversarial payloads across 16 categories. Prompt injection, jailbreak, data exfiltration, capability abuse, context manipulation, MCP and A2A exploitation, memory weaponisation, context window, supply chain, tool shadow, parser differential, persistent agent, fake tool, context lifecycle, policy enforcement integrity.
- 20-probe behavioural simulation under
--deep. Observes what a skill actually does, not only what it declares. - Self-securing. Every binary verifies itself on startup against an embedded SHA-256 manifest. Post-install tampered binaries enter QUARANTINE mode (exit code 3) with a per-file forensics report. Symlink-redirected manifests are rejected.
Full catalogue: docs/SECURITY_CHECKS.md.
npx hackmyagent secure # run without installing
npm install -g hackmyagent # global install
npm install --save-dev hackmyagentRequires Node.js 18 or later.
brew install opena2a-org/tap/hackmyagentgit clone https://github.com/opena2a-org/hackmyagent.git
cd hackmyagent
npm install
npm run build
node dist/cli.js secureEvery release publishes via npm Trusted Publishing with SLSA v1 provenance. No long-lived NPM_TOKEN. GitHub Actions exchanges its OIDC token with npm at publish time.
npm view hackmyagent dist.attestations --json
# Expects non-empty result with predicateType "https://slsa.dev/provenance/v1"hackmyagent check <target> accepts each of these surfaces. secure scans your own project. scan-soul scans governance.
| Surface | Command | What gets scanned |
|---|---|---|
| Your own project | hackmyagent secure |
310 static checks + NanoMind on current directory |
| A local directory | hackmyagent check ./my-agent/ |
tree + auto-detected artifacts |
| An npm package | hackmyagent check express |
downloads tarball, scans before you install |
| A PyPI package | hackmyagent check pip:requests |
downloads sdist, scans before you install |
| A GitHub repo | hackmyagent check getsentry/sentry-mcp |
clones, scans, reports |
| A published skill | hackmyagent check @publisher/skill |
signature verification + semantic checks |
| A local skill directory | hackmyagent check ./my-skill/ |
skill files + SOUL.md + manifest |
| An MCP server config | hackmyagent check ./my-mcp-server/ |
MCP config + declared tools + scope + dependencies |
| An A2A agent card | hackmyagent check ./my-agent/ |
agent-card capabilities + identity |
| A URL tarball | hackmyagent check https://ex.com/pkg.tar.gz |
downloads, scans |
| External infrastructure | hackmyagent scan example.com |
external AI-endpoint inventory |
| Governance (SOUL.md) | hackmyagent scan-soul |
SOUL.md against OASB-2 behavioural controls |
secure: your own project. Full static + semantic scan, auto-fix option, designed for CI and recurring use.check: something you don't own yet. Pre-install trust check for any surface above.red-team: maps the attack surface of a specific skill, MCP, or SOUL and generates target-specific payloads. It does not execute them, so it does not tell you whether the artifact resists.attack: test a live endpoint or local simulation with 164 pre-built adversarial payloads.
hackmyagent secure # scan current directory
hackmyagent secure --fix # auto-fix issues with rollback
hackmyagent secure --fix --dry-run # preview fixes
hackmyagent secure --deep # full behavioural simulation (20 probes)
hackmyagent secure --static-only # static checks only, faster
hackmyagent secure --ignore CRED-001,GIT-002 # leave check IDs out of the findings list
hackmyagent secure --json # JSON output for CI
hackmyagent secure --ci # non-interactive, no contribution, exit code unchanged
hackmyagent secure --publish # push anonymised results to the OpenA2A Registry
hackmyagent secure -b oasb-1 # OASB-1 benchmark (L1, L2, L3)
hackmyagent secure -b oasb-1 --fail-below 70 # CI gate (adds a floor; the rating gate still applies)
hackmyagent secure --nanomind # AI analyst: per-finding narratives + coverage escalationsOutput shows an Observations block (surfaces, checks, categories, verdict) and a per-finding list. Every HIGH or CRITICAL finding names the file it came from. Findings from a specific line — hardcoded credentials in source, for example — carry file:line and a runnable Fix: with a Verify: command. Findings about a file's overall configuration, such as an over-permissive .claude/settings.json, currently name the file without a line and describe the fix in prose rather than as a command (#299, #368).
Runs automatically on every secure scan. On first use, HMA downloads a 5.5 MB ONNX classifier from HuggingFace (opena2a/nanomind-security-classifier, a 3M-parameter Mamba TME model) and caches it locally. No external calls after that.
- 7 AST analyzers:
capability,credential,governance,scope,prompt,code,stego. - 9 attack classes:
exfiltration,injection,privilege_escalation,persistence,credential_abuse,lateral_movement,social_engineering,policy_violation,benign. --deepadds the 20-probe behavioural simulation.--static-onlydisables the semantic layer.--nanomindopts into the generative analyst (specialist model, not the classifier). It produces per-finding threat narratives on HIGH or CRITICAL findings, and a coverage sweep over artifacts the deterministic checks did not flag — analyst verdicts there surface as advisory escalations for human review (never changing the score, findings, or exit code).
hackmyagent red-team ./my-skill.md # map surface, generate payloads
hackmyagent red-team ./mcp-config.json --json # JSON output, incl. payload textMaps an artifact's attack surface from its own language and generates target-specific payloads for it.
It does not run them. No agent is executed, so nothing about resistance is measured and no resilience score is reported — resilienceScore is null and evaluation.mode is not_executed in --json. The command exits 2 to mark that it reached no verdict (0 executed-and-clean, 1 findings). The payloads are the deliverable: --json puts their text under .results[].payloadInput, to run against your own agent.
In 0.25.2 and earlier this command scored resistance with a regex over the artifact's own text, which rated a jailbreak document 100% resilient and benign prose 0%, both at exit 0. The affected range is 0.11.14 through 0.25.2, which is the whole published life of the command — red-team did not exist before 0.11.14 — so treat any resilience score, defense map, or successful-attack count from any of those versions as void. The number is removed rather than corrected (#369); executing payloads for real is tracked in docs/design/redteam-nanomind-judge.md.
Two --json fields were renamed with the number, because their old names asserted a polarity nothing established. constraints is now modalStatements: it is a list of modal-verb sentences extracted from the artifact, and "Never reveal secrets." and "Never refuse." are the same syntactic shape, so nothing here separates a rule from a jailbreak. governanceMechanism: string is now governanceMentions: string[]: governance vocabulary the artifact mentions, not a mechanism it has. A file cannot report whether the agent it describes is governed, and the old field suppressed an attack surface when it was non-none.
hackmyagent attack https://api.example.com/v1/chat # test a live endpoint
hackmyagent attack https://api.example.com --category prompt-injection # single category
hackmyagent attack https://api.example.com --fail-on-vulnerable medium # CI gate
hackmyagent attack --local # generate payloads only
hackmyagent attack --local --system-prompt "You are helpful" # with custom system prompt164 payloads across 16 categories. Intensity tiers: passive (28 payloads, observation only), active (111 payloads, default), aggressive (164 payloads, includes creative or risky probes).
attack needs a running agent. It probes the endpoint once before sending any
payload and exits 2 without a score if nothing is there, so an unreachable
target costs one request instead of the whole suite.
--local generates payloads and checks that they parse. It contacts no agent,
so it reports no risk score and exits 2 — the same as red-team. Use it to
inspect the payload set, not as a CI gate.
Only test systems you own or have written authorisation to test.
Need a target to practice on? DVAA is an intentionally vulnerable agent fleet. Break an agent there, then red-team it here:
# Start the DVAA fleet (separate terminal)
docker run -p 7001-7008:7001-7008 -p 7010-7016:7010-7016 -p 7020-7021:7020-7021 -p 9000:9000 opena2a/dvaa:0.9.1
# Red-team LegacyBot, the most vulnerable agent
hackmyagent attack http://localhost:7003/v1/chat/completions --api-format openai --intensity passivehackmyagent scan-soul # scan current directory for SOUL.md
hackmyagent scan-soul --deep # LLM semantic analysis (requires ANTHROPIC_API_KEY)
hackmyagent scan-soul --fail-below 60 # add a score floor on top of the default gate
hackmyagent scan-soul --explain # print the 9-domain governance model and exit
hackmyagent harden-soul # generate or update governance sections
hackmyagent harden-soul --dry-run # preview without writingAuto-detects governance file in this priority: SOUL.md, system-prompt.md, CLAUDE.md, .cursorrules, agent-config.yaml.
scan-soul already gates without a flag: it exits 1 when conformance is none,
meaning one of the critical controls was not detected. That is not a score
threshold — a file scoring well above zero still fails if a critical control is
missing, which is the same gate secure -b oasb-2 and detect apply. Over a
tree with no governance file at all it exits 2 and reports nothing, because
there is nothing to grade. --fail-below adds a score floor on top of that.
Run hackmyagent scan-soul --help for the full exit-code contract.
hackmyagent detect # audit current directory
hackmyagent detect /path/to/project # audit a specific project
hackmyagent detect --json # machine-readable output
hackmyagent detect --export-csv inventory.csv # asset inventory for CMDBInventory of AI tools, MCP servers, and governance gaps across your machine. Detects Claude Code, Cursor, Copilot, and similar tools; MCP configurations (project-local and machine-wide); AI config files with credential references or broad permission grants; and SOUL.md files.
hackmyagent trust server-filesystem # MCP shorthand trust lookup against the Registry
hackmyagent trust --audit package.json # audit every dependency
hackmyagent explain CRED-001 # explain a check finding
hackmyagent nanomind setup # install the optional generative analyst daemon
hackmyagent nanomind status # check model and runtime statushackmyagent trust can be gated by the Agent Authorization Protocol. When --grant is set, the CLI presents an ATX and a grant reference to the local Secretless broker before any Registry lookup. The broker is the policy decision point; the CLI proceeds only if the broker authorizes.
hackmyagent trust express \
--grant grant://hackmyagent-trust \
--atx ~/.opena2a/atx.jsonOutcomes:
- Broker authorizes -> trust proceeds.
- Broker denies (HTTP 403) -> exit 3 with a pointer to
~/.secretless-ai/policies/. AAP §6.6: the denial is opaque; reasons live only in the broker's signed audit log. - Broker unreachable -> exit 4 with a
secretless broker starthint. - Broker returns an unexpected status -> exit 6. The response body is never echoed to the user.
- No
--grantflag -> trust runs exactly as before; the gate is opt-in.
This is the second TypeScript AAP consumer (after opena2a protect --grant, opena2a-org/opena2a#179). Defends T-3002 (cross-tenant grant leakage), T-3003 (over-broad credential scope), T-3006 (credential leaking into agent context), T-8002 (audit attribution gap) at the CLI surface.
hackmyagent secure auto-detects OpenClaw and NemoClaw installations (.openclaw/, .moltbot/, .nemoclaw/, openclaw.json, openclaw.plugin.json). When detected, 28 NemoClaw plus 34 OpenClaw checks run alongside the standard suite. No separate command needed.
opena2a-cli is the unified CLI for the OpenA2A security tools. HackMyAgent powers opena2a review, opena2a scan, opena2a protect, opena2a benchmark, and opena2a scan-soul.
npm install -g opena2a-cli
opena2a reviewHackMyAgent runs as an MCP server, so an AI coding assistant can scan the project it is working in.
hackmyagent init-mcp --root /absolute/path/to/your/projectThat writes the server into your client config (Claude Code, Cursor, VS Code) and restarts are picked up on the client's next launch. Then ask the assistant: "Run a deep security scan on this project."
Three tools are exposed:
| Tool | What it does |
|---|---|
hackmyagent_scan |
The full check suite. Read-only. |
hackmyagent_deep_scan |
Pattern + structural analysis, plus the artifact contents for the assistant to reason over. |
hackmyagent_benchmark |
OASB-1 compliance assessment at L1, L2 or L3. |
Roots. The server reads only inside the directories it was started with, and
there is no unconfined mode. --root is repeatable, so grant projects one at a
time:
hackmyagent init-mcp --root ~/work/api --root ~/work/webThe filesystem root and your home directory are not accepted, because granting
either hands every project and every credential file on the machine to whatever
model is driving the session — the same thing HackMyAgent reports as MCP-001
when it sees it in someone else's configuration. A path outside the roots is
refused with the roots named and the command to grant one.
Fixes are terminal-only. No MCP tool writes to your files. Findings carry their fix command and you run it yourself:
hackmyagent secure --fix .Verify what the server is allowed to reach:
grep -A3 hackmyagent .claude/settings.json # or .cursor/mcp.json, .vscode/mcp.jsonARP monitors agents during execution — rule-based patterns, statistical anomaly
detection, and LLM-assisted assessment — and runs as an HTTP reverse proxy for
OpenAI API, MCP and A2A traffic. It is driven from opena2a runtime
(opena2a-cli).
secure and scan-soul take --ci for non-interactive, byte-stable output. It also
turns contribution off for that run, so a build server never shares scan results on the
strength of an opt-in recorded earlier on the same machine. Most scanning commands take
--json — check, secure, attack, scan, fix-all, scan-soul, harden-soul,
red-team, wild, detect, trust.
--json never changes the exit code: a command that exits 1 on findings exits 1 in both
channels. --ci mostly doesn't either — it selects how a run reports, not what it
concludes. The one exception is scan-soul, which additionally exits 1 under --ci on a
HIGH-severity SOUL finding (a governance violation, a profile mismatch, or an unrecognized
--profile value) that renders as a warning and passes CI without the flag — deliberate,
so a pipeline can opt into treating a misleading SOUL verdict as a failure. To gate a
pipeline on severity, read the exit code the command already returns; to gate on the
score, use --fail-below <n> on the text and JSON channels.
name: Agent Security
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npx hackmyagent secure --json > security-report.json
- run: npx hackmyagent secure -b oasb-1 --fail-below 70SARIF output and a pre-commit hook: docs/use-cases/ci-pipeline.md.
Suppressing a check (--ignore CRED-001, or !CRED-001 in .hmaignore)
changes what the report lists, not what it measures: it is still scored, still
in the verdict, still in the exit code, and named on a Suppressed line. Use
--fail-below <score> to let a build pass over findings you have accepted — a
threshold in your pipeline config is auditable, a missing finding is not.
Excluding a path (test-fixtures/ in .hmaignore) is a scope statement:
those paths leave the score and the exit code, as if you had not scanned them.
Always disclosed on a Scope line and as outOfScope in --json.
| Code | Meaning |
|---|---|
| 0 | Measured. No critical or high issues. |
| 1 | Measured. Critical or high severity issues found. For scan-soul, also conformance none — a critical governance control was not detected, whatever the score. |
| 2 | Not measured. For red-team, no score or risk level is reported. For secure --deep, the static results ARE reported and scored; the deep layer did not finish, so the run reaches no deep-scan verdict. For secure, a file inside the target was discovered and could not be read (EACCES, ELOOP, an unreadable mount): what DID run is still reported and scored, and the score is an upper bound rather than a measurement of the tree — SCAN-UNREAD-001 names each file and the errno. The target does not exist (check <missing path>, an unknown package), was unreachable, answered no payload, or the command reaches no verdict by design. red-team and attack --local exit 2 on every run: both generate payloads without executing any against an agent, so neither concludes anything about the target. A scan whose plugins failed is also 2. scan-soul exits 2 over a tree with no governance file: no score or conformance level is reported, because nothing was read. |
| 3 | QUARANTINE. Binary integrity check failed (tampered installation). |
Exit 2 is non-zero on purpose. A CI job that asked for a security verdict and got "I could not reach the target" has not been told the target is safe.
hackmyagent secure --fix remediates ten checks; --dry-run previews the changes,
backups live in .hackmyagent-backup/, and hackmyagent rollback reverts them. The
table is in docs/SECURITY_CHECKS.md.
TypeScript entry points for the scanner, the runtime protection layer and the
NanoMind semantic compiler: docs/PROGRAMMATIC_API.md.
Plugin authoring: docs/PLUGIN_API.md.
Step-by-step guides for scanning an agent, red-teaming an MCP server, securing
OpenClaw and wiring a CI pipeline: docs/USE-CASES.md.
Apache 2.0. PRs from outside the org welcome. CONTRIBUTING.md has the dev loop, test conventions, and pre-push review gates.
git clone https://github.com/opena2a-org/hackmyagent.git
cd hackmyagent && npm install && npm run build && npm testSecurity issues: info@opena2a.org (coordinated disclosure, response within 24 hours).
- Website
- Security Checks Reference
- OpenA2A CLI
- aicomply — inline PII, credential, and regulated-data classification for agent I/O at runtime (HMA scans the code; aicomply guards the live stream)
- Demos
- Documentation
- Research
Part of the OpenA2A security platform.
Apache-2.0. See LICENSE.

