Kesekit Check
cdppcorp/KESE-KIT
Run a pre-deployment security compliance checklist based on KISA guidelines.
Security review of an open-autonomy agent service — cryptographic key handling, dynamic code execution, ABCI authentication and replay, secret exposure, dependency supply chain, and deployment…
$ npx skills add valory-xyz/open-autonomy --skill security-review -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install valory-xyz/open-autonomy security-review --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/claude-skills/security-review .claude/skills/security-review && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .claude/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-reviewType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add valory-xyz/open-autonomy --skill security-review -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install valory-xyz/open-autonomy security-review --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .agents/skills && cp -r skills-src/claude-skills/security-review .agents/skills/security-review && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .agents/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add valory-xyz/open-autonomy --skill security-review -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install valory-xyz/open-autonomy security-review --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/claude-skills/security-review .cursor/skills/security-review && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .cursor/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/valory-xyz/open-autonomy.git --path claude-skills/security-review--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add valory-xyz/open-autonomy --skill security-review -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install valory-xyz/open-autonomy security-review --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/claude-skills/security-review .gemini/skills/security-review && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .gemini/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install valory-xyz/open-autonomy security-reviewInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add valory-xyz/open-autonomy --skill security-review -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .github/skills && cp -r skills-src/claude-skills/security-review .github/skills/security-review && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .github/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add valory-xyz/open-autonomy --skill security-review -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install valory-xyz/open-autonomy security-review --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/valory-xyz/open-autonomy.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/claude-skills/security-review .opencode/skills/security-review && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "security-review" agent skill from https://github.com/valory-xyz/open-autonomy/tree/main/claude-skills/security-review into .opencode/skills/security-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "security-review", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
security-reviewSecurity review of an open-autonomy agent service — cryptographic key handling, dynamic code execution, ABCI authentication and replay, secret exposure, dependency supply chain, and deployment…
Security Review is an agent skill from valory-xyz/open-autonomy. Security review of an open-autonomy agent service — cryptographic key handling, dynamic code execution, ABCI authentication and replay, secret exposure, dependency supply chain, and deployment hardening
Its SKILL.md is about 11k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Security, covering Security review, Cryptography and Supply chain security. The repository describes itself as: A framework for the creation of autonomous agent services. The licence is Apache-2.0.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 62033a2. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
makepipdockergitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use pip, docker and git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
API_KEYPRIVATE_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Security Review loads about 11k tokens when it runs. Until then it costs about 55 tokens; SKILL.md has 5,189 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
/` charts, GitHub Actions workflows, or `.env*` files committed to the repo.- `.env`, `.env.local`, `.env.production` committed to git (these should be in `.gitignore`)itHub Actions encrypted secrets; ensure `.env*` is gitignored; rotate any value found.Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from valory-xyz/open-autonomy at commit 62033a2, republished under its Apache-2.0 licence (© valory-xyz). 5,189 words, ~10,851 tokens.
.claude/skills/security-review/SKILL.md (or your agent's skills folder).You are an expert security reviewer for open-autonomy agent services. Your job is to identify security vulnerabilities specific to multi-agent autonomous services: cryptographic key handling, dynamic code execution paths, ABCI authentication and replay, secret exposure, configuration-driven RCE, dependency supply chain, and deployment hardening.
Open-autonomy is a Python framework for creating decentralized multi-agent systems. Source and docs: https://github.com/valory-xyz/open-autonomy
This skill is complementary to the other audit skills:
/audit-fsm — FSM correctness and safety. If a finding is about consensus correctness or round logic, cite the relevant audit-fsm check ID instead of duplicating here./audit-resilience — external request resilience (timeouts, retries, idempotency). If a finding is about HTTP-level robustness, cite that skill.Security findings that overlap with those skills (e.g. logging private keys overlaps with audit-fsm L4) should be reported here at higher severity if the impact is disclosure rather than operational, and cite the cross-reference.
$ARGUMENTS is provided, audit only those paths (e.g. packages/valory/skills/transaction_settlement_abci)$ARGUMENTS is empty, audit the whole repo: packages/, autonomy/, plugins/, services/, customs/ (if present), and deployment artifacts (Dockerfile*, docker-compose*, *.yaml configs)This section encodes the threat model. Use it as ground truth — do not rely on external documentation.
Open-autonomy agents hold private keys for one or more chains. Default file locations:
ethereum_private_key.txtsolana_private_key.txtcosmos_private_key.txtLoaded by aea core via aea.crypto.wallet.Wallet (and the underlying CryptoStore) at startup. Used for:
sender field on consensus payloads)priv_validator_key.json)Threat surface:
docker inspect, /proc/<pid>/environ, supervisor logs.A leaked agent key generally allows:
ABCI payloads carry sender: str (agent address). The framework verifies via Tendermint signature that the payload was signed by the claimed sender. The round then verifies:
sender is in the active participant setpayload_classCollectSameUntilThresholdRound requires N agents to agree)What the framework DOES guarantee (do not re-report as findings against standard rounds):
BaseTxPayload.round_count is monotonic and never resets across periods. The standard collection rounds (CollectSameUntilThresholdRound, etc.) verify it in process_payload() (packages/valory/skills/abstract_round_abci/base.py:1417): if payload.round_count != self.synchronized_data.round_count: raise ABCIAppInternalError(...). A payload from a closed period therefore cannot be re-submitted in a later period as long as the round's process_payload invokes the parent's check.What is NOT verified by the framework:
process_payload() without invoking the standard round_count verification re-opens the replay surface. This is the surface H6 audits._MetaPayload keys payloads by "{module}.{ClassName}". Renaming the payload class or moving its module breaks deserialization of persisted Tendermint state — and creates a window where two distinct payload types share a registry key during rollout. Cross-reference: audit-fsm M1 (Payload Class Mismatch) and T6 (_MetaPayload.registry Not Saved/Restored).customs/)Scope caveat. customs/ and FILE_HASH_TO_STRATEGIES are downstream service patterns (e.g. valory-xyz/trader, valory-xyz/optimus) — they do NOT exist in open-autonomy itself. Audits scoped to the framework repo will produce vacuous "no findings" output for this section and for C3. Apply this subsection only when auditing a downstream service that adopts the pattern.
Strategies under customs/ (e.g. kelly_criterion, fixed_bet) are loaded by IPFS hash at runtime:
aea-config.yaml / service.yaml — typically as a param like FILE_HASH_TO_STRATEGIES mapping IPFS hashes to strategy module names.Trust boundary: the configured hash is the only thing standing between the agent and arbitrary code execution. The strategy code runs with full agent privileges:
Wallet / CryptoStore (aea.crypto.wallet)synchronized_data (consensus-critical state)Threat surface:
Web3.eth.send_raw_transaction).skill.yaml, aea-config.yaml, service.yaml support env-var interpolation:
api_url: ${API_URL:str:https://default.example}
api_key: ${API_KEY:str:dummy}Resolution happens at agent startup. Resolved values flow into Params / Model instances and are read at runtime by behaviours.
Threat surface:
dummy / empty defaults in production: if the env var isn't set, the agent runs with the placeholder. Anonymous requests to authenticated endpoints, wrong addresses, "test" keys.docker-compose.yaml checked into git: anyone with read access to the repo has the secret.ENV API_KEY=... in a Dockerfile persists in the image even if overridden at runtime.subprocess / shell calls without sanitization: command injection.importlib.import_module(os.environ['MODULE'])): RCE.Each agent ships with a Tendermint sidecar:
abci connection listens on (packages/valory/connections/abci/connection.py:110 DEFAULT_ABCI_PORT); Tendermint dials in to deliver CheckTx / DeliverTx etc. A 0.0.0.0 bind here lets any peer drive the application directly, bypassing TendermintThreat surface:
0.0.0.0 instead of localhost / agent network → external read of all consensus statepriv_validator_key.json) misplaced or world-readable → consensus signature forgeryautonomy deploy build produces docker-compose / k8s manifests. Common defaults:
Threat surface:
Open-autonomy uses poetry / pipenv and tomte for tooling. License policy (per CLAUDE.md):
Third-party trading libraries (py_clob_client, web3, httpx, requests, exchange-specific clients) are full-trust runtime deps with full keychain access.
Threat surface:
python-requests vs requests, crpytography vs cryptography)bandit, safety in runtime container)The repo's tox -e safety allowlist already pins known-unfixed CVEs in transitive deps. Audit the allowlist itself.
What: eval, exec, compile, or dynamic import where the input is not statically known. Untrusted input includes anything sourced from: HTTP request, ABCI payload, env var, file content, IPFS, external API response.
Search patterns:
eval(, exec(, compile( — any usage in packages/, customs/, autonomy/importlib.import_module(, __import__( with non-literal argumentspickle.load, pickle.loads on data not produced by the same trust boundary (file written by user, network response, IPFS payload)marshal.loads, shelve.open on untrusted datayaml.load(...) without Loader=SafeLoader — pre-5.4 FullLoader had CVE-2020-14343 (arbitrary object construction); PyYAML ≥ 6.0 raises TypeError on missing Loader. Always pass Loader=SafeLoader (or yaml.safe_load) explicitly — even on PyYAML 6 — to be robust against future loader-default changessubprocess.* with shell=True AND interpolated arguments (f"cmd {var}", "cmd " + var, cmd % var)os.system( with interpolated argumentsTemplate(...).substitute(...) where the template itself comes from untrusted inputBug example:
# BUG: payload field interpolated into shell
def process_strategy(self, payload):
strategy = payload.strategy_name
subprocess.run(f"python -m {strategy}", shell=True) # RCEFix: never eval/exec; use yaml.safe_load; use subprocess.run([cmd, arg1, arg2], shell=False); for pickle, sign and verify or replace with JSON.
Severity escalation: If the input source is an ABCI payload or IPFS content, this is unconditionally Critical — a single malicious / compromised peer can pivot to RCE on every agent.
What: Any code path that emits, persists, or returns a private key, mnemonic, seed, or signing material outside the AEA crypto/wallet boundary (aea.crypto.wallet.Wallet, Crypto.sign_message, CryptoStore).
Search patterns:
logger.*, print(, return, response builders, payload constructors:private_key, priv_key, pk, sk, secret, seed, mnemonic, entropy, signing_key, wallet.private_keyWallet / CryptoStore and return values in the response body (debug endpoints in particular)payload fields broadcast over Tendermintopen(..., 'w') with key in body)raise ValueError(f"Bad key: {key}"))__repr__ / __str__ of wallet / signer objects that includes the keyBug example:
# BUG: full HTTP response body logging includes Authorization header containing the agent key
self.context.logger.info(f"Sent: {request}, Got: {response.json()}")
# request includes signed message that derives from the private keyCross-reference: audit-fsm L4 covers this at the operational level. /security-review escalates to Critical because the impact is permanent disclosure.
Fix: never log key material; redact in __repr__; constrain key access to a single module that exposes only sign(...) not get_key(); review every debug endpoint.
What: Code paths that load Python modules from IPFS without hash verification, OR that allow the configured hash to be derived at runtime from untrusted input.
Search patterns:
importlib / exec / compile of fetched bytesFILE_HASH_TO_STRATEGIES (or similar param) populated from external source rather than static configcustoms/ loader code that fetches and evaluates without hash checkdummy, empty) — production agents may run with unverified strategyThreat: the IPFS hash IS the trust boundary. Bypassing it = arbitrary code execution with full agent privileges (keys, network, on-chain authority).
Fix: statically configure hashes; verify content hash matches configured hash before executing; reject placeholder defaults in production builds.
What: Connection / handler code that deserializes inbound payloads using formats that allow code execution (pickle, yaml.load, marshal).
Search patterns: in connections/*/connection.py, handlers.py, ABCI message handlers:
pickle.loads(message.body), pickle.loads(srr_message.payload)yaml.load(...) without Loader=SafeLoadermarshal.loads(...)eval field valuesDistinct from audit-resilience BP14. BP14 audits whether the connection's on_send / _route_request catches JSONDecodeError from json.loads(message.payload) — i.e. a malformed-input robustness concern. C4 audits whether the deserializer itself is code-executing — i.e. an RCE concern. A connection can simultaneously have a BP14 finding (no exception handling) and a clean C4 (uses json.loads), or vice versa (uses pickle.loads inside a generous try-except → C4 finding without BP14). Different threat classes; report independently.
Fix: use JSON; if a binary format is needed, use protobuf / msgpack with strict schemas.
What: API keys, JWTs, mnemonics, private keys, OAuth tokens, AWS credentials, or webhook URLs with embedded tokens, committed in source.
Tooling: tox -e gitleaks runs in CI. /security-review re-runs and reviews:
gitleaks.toml allowlist for over-broad patternsSearch patterns beyond gitleaks defaults. Gitleaks's built-in rules already cover common SaaS / cloud token shapes (Slack, GitHub, GitLab, AWS, Stripe, JWT, OpenAI, etc.) — do NOT re-list those literals here, listing them would re-trigger gitleaks on this file. Audit-specific additions:
0x[a-fA-F0-9]{64} — 32-byte hex shape in non-test files. High false-positive rate: the same form matches Ethereum transaction hashes, block hashes, Keccak-256 outputs, storage-slot keys, IPFS CID v1 binary fields, and any bytes32 literal. Triage before flagging: require proximity to a variable name in {key, secret, mnemonic, pk, sk, private}, OR exclude matches adjacent to {tx_hash, block_hash, ipfs_hash, topic, slot}. Without this triage, the rule fires on every block-hash literal in tests and tooling AND lets reviewers dismiss real keys as "just a hash"mnemonic = "...", mnemonic-shaped 12/15/18/21/24-word strings in sourceSeverity: Critical regardless of intent — once committed, must be assumed compromised even after removal (git history retention).
Fix: rotate the disclosed credential; remove from history (git filter-repo); replace with env-var or secrets-manager reference; add to gitleaks.toml as a tested negative.
What: subprocess.*(..., shell=True) or os.system(...) where any argument is composed from external input (env var, payload field, HTTP query param, file content).
Search patterns:
subprocess.run(, subprocess.call(, subprocess.Popen( with shell=Trueos.system(, os.popen(commands.getoutput( (if Python 2 legacy), pty.spawn(For each, check whether arguments are static literals or interpolated.
Bug example:
# BUG: agent_id from HTTP request flows into shell
@app.post("/restart")
def restart(agent_id: str):
subprocess.run(f"systemctl restart agent-{agent_id}", shell=True)Fix: shell=False and pass argv as a list; use shlex.quote for unavoidable shell paths; validate via allowlist before interpolation.
What: service.yaml / aea-config.yaml / skill.yaml with env-var-interpolated auth credentials whose default is dummy, empty string, or a placeholder. Production deployments depend on the env var being set; if it isn't, the agent runs unauthenticated or with shared known-bad credentials.
Search patterns in YAML configs:
${[A-Z_]+:str:dummy}, ${[A-Z_]+:str:}, ${[A-Z_]+:str:test}, ${[A-Z_]+:str:placeholder}*_api_key, *_token, *_secret, *_password, *_credential*_url, *_endpoint where placeholder is suspicious (localhost, example.com)Fix: require env var (no default), or default to a value that fails closed (e.g. an unauthenticated client that only allows read-only ops); add a startup check that refuses to run with placeholder values in production mode.
What: Secrets in docker-compose.yaml, Dockerfile*, kubernetes.yaml, helm/ charts, GitHub Actions workflows, or .env* files committed to the repo.
Search patterns:
Dockerfile*: ENV API_KEY=, ARG SECRET=, RUN echo "..." > /keydocker-compose.yaml: literal values in environment: blocks (vs ${VAR} references).github/workflows/*.yml: literal tokens (vs ${{ secrets.X }}).env, .env.local, .env.production committed to git (these should be in .gitignore)kubernetes/*.yaml: data: blocks with base64-encoded plaintext (Secret manifests)Fix: use Docker secrets / Kubernetes Secret resources with mounted files; use GitHub Actions encrypted secrets; ensure .env* is gitignored; rotate any value found.
What: Dockerfiles without a USER directive, or with USER root, leave the agent process running as root inside the container.
Search patterns: Dockerfile*, especially deployments/Dockerfiles/*/Dockerfile:
USER directive (Docker default = root)USER root explicitly setRUN chown -R root:root /app patternsWhy high not critical: root-in-container isn't immediate RCE on the host, but combined with any container-escape CVE (e.g. cgroup vulnerabilities, kernel bugs), the blast radius is much larger than non-root.
Fix: create a non-root user (adduser --system --no-create-home agent), USER agent, ensure mounted key files are readable by that uid only.
What: Tendermint RPC port (default 26657) bound to 0.0.0.0 or exposed in docker-compose.yaml ports: section without auth.
Search patterns:
docker-compose*.yaml: ports: entries that publish 26657 / 26656 to the hostconfig.toml): laddr = "tcp://0.0.0.0:26657" instead of tcp://127.0.0.1:26657type: LoadBalancer for TendermintThreat: Tendermint RPC exposes block data, validator info, mempool state, and (in some configurations) broadcast_tx_* endpoints that allow anyone to submit transactions.
Fix: bind to localhost or to the agent-internal network; use a network policy / firewall to restrict ingress; require auth proxy for any external RPC access.
What: Payload fields read by end_block() or process_payload() that are used in security-sensitive contexts (signing material, addresses, amounts, contract addresses, URLs) without explicit validation.
Search patterns:
payload.<field> and uses it for: Web3.toChecksumAddress(...), Account.sign_message(...), contract write calls, HTTP requests to user-controlled URLsstr or Any (no Pydantic / dataclass-validation hooks)Threat scenario: a compromised agent submits a payload with a malicious URL, address, or amount. If the round accepts the payload without bounds-checking, the consensus value drives downstream actions across all agents.
Fix: validate at check_payload() (round side) and at payload construction (behaviour side); use strict type hints (Address, URL, PositiveInt); reject out-of-range values.
What: Standard collection rounds inherit process_payload() from the framework, which verifies payload.round_count == self.synchronized_data.round_count (packages/valory/skills/abstract_round_abci/base.py:1417). H6 audits the narrower residual surface: custom rounds that override process_payload() without invoking the parent check (e.g. via super().process_payload(payload) or an equivalent round_count assertion).
How to check:
process_payload (def process_payload(self, payload).super().process_payload(payload), ORif payload.round_count != self.synchronized_data.round_count: raise ... check.Threat: an adversary captures a payload signed by a participant in period N and re-submits it in period M to re-trigger a state-changing action. Standard rounds reject this at process_payload; overriding rounds may not.
Distinct from audit-resilience BP15. BP15 protects against the same logical action being re-submitted via FSM retry / connection-layer retry (accidental, internal trigger). H6 protects against an old payload from a closed period being replayed on the consensus layer (adversarial, external trigger). Different attacker model, different mitigation surface — the mitigations partially overlap (idempotency on the action vs nonce/round_count on the payload) but require independent assessment.
Fix: in every custom process_payload override, either call super().process_payload(payload) first, or replicate the round_count check explicitly.
What: Run tox -e safety (which uses tomte's allowlist) against the resolved environment. Each unaddressed CVE in a runtime dep is a finding. pip-audit is optional second-source coverage but is NOT pre-configured in this repo — there is no [testenv:pip-audit] stanza in tox.ini and make security runs only safety, bandit, and gitleaks. If you want pip-audit cross-check, install it manually (pip install pip-audit) and run separately; note in the report.
Process:
tox -e safety. Optionally pip install pip-audit && pip-audit -r <lockfile> for second-source coverage.-i 37524 -i 38038 ... in tox.ini) — for each pinned CVE, check whether upstream has shipped a fix that allows the pin to be removed.Fix: upgrade the dep; if upgrade is impossible, document the mitigation in the allowlist with a date and re-check quarterly; for unreachable CVEs, document why they don't apply.
What: Mounted private-key files with permissive mode (0644, 0755), or container-internal copies created without chmod.
Search patterns:
Dockerfile*: COPY ethereum_private_key.txt without subsequent RUN chmod 600docker-compose*.yaml: volume mounts of key files without explicit read_only: truecp keys without chmod 600defaultMode: 0644Fix: chmod 600 *_private_key.txt after copy / mount; use Kubernetes Secret defaultMode: 0400; mount read-only.
What: Flask Tendermint monitor (port 8080), agent debug routes, or health endpoints that return more than {"status": "ok"} — e.g. agent address, validator info, signed-payload count, configured params, last block.
Search patterns:
flask.*route(, @app.route(, @app.get(, @app.post( in packages/, autonomy/, deployments/make_response(, jsonify( returning rich structuressynchronized_data, params, address, validatorThreat: reconnaissance for a targeted attack. Validator addresses + chain → fund tracing; configured RPCs → MITM target list; agent address → on-chain identity disclosure.
Fix: strip non-essential fields from health responses; gate debug routes behind DEBUG=true env var; require auth for any internal-state endpoint.
What: HTTP handlers in handlers.py that accept request bodies without schema validation. Audit-resilience covers crash patterns; /security-review M3 covers exploitability:
open(f"data/{request.name}.json"))requests.get(request.url))defusedxmlSearch patterns:
open( with interpolated path componentrequests.get(...) with URL from requestxml.etree.ElementTree.parse(, lxml.etree.parse( without defusedxml.format() building SQL queriesFix: validate inputs against a whitelist; resolve and check filesystem paths (Path(...).resolve().is_relative_to(allowed_root)); disallow user-controlled outbound URLs or restrict to allowlisted hosts; use defusedxml.ElementTree.
What:
random.* for security-critical randomness (use secrets)hmac.compare_digest for comparison)Search patterns:
hashlib.md5(, hashlib.sha1( — flag if used in verify, auth, sign, mac contextsCrypto.Cipher.AES.MODE_ECB, AES.new(..., AES.MODE_ECB, ...)random.randint(, random.choice(, os.urandom( (the latter is OK, but check usage) where the value is used as a key, IV, nonce, or token== comparison of HMACs / signatures (timing attack)Fix: SHA-256+ for hashing; AES-GCM / ChaCha20-Poly1305 for encryption; secrets.token_bytes(32) for tokens; hmac.compare_digest for comparison.
What: HTTP services (Flask Tendermint monitor, agent UI) with Access-Control-Allow-Origin: * or missing security headers (X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, Content-Security-Policy).
Search patterns:
Access-Control-Allow-Origin with *flask_cors.CORS(app) with default config (= permissive)Fix: restrict CORS to known origins; set security headers via middleware; for read-only endpoints, document the threat model explicitly.
What: Per CLAUDE.md, only MIT / BSD / Apache 2.0 are allowed; GPL / LGPL / MPL are prohibited. Dependency tree may include prohibited licenses transitively.
Process:
pip-licenses --format=markdown (or tomte's license tooling if available) against the resolved environment.Fix: replace the dep; add explicit exception with legal review; document in NOTICE / SBOM.
C2 covers individual-call-site disclosure. L1 asks the systemic question: is there a redaction layer in the logging pipeline (formatter / structlog processor / logging.config.dictConfig filter) that masks secret-shaped values, or does every author bear the burden individually? If the latter, file as L1 — defense-in-depth gap.
What: Even with H1 fixed (no insecure defaults), there's value in a startup check that asserts every required secret env var is set and matches an expected shape (e.g. API_KEY must be 32+ chars, PRIVATE_KEY must be 64 hex chars).
Fix: add a validate_secrets() call at agent startup; fail fast with a clear error if a required secret is missing or malformed.
What: persistent_peers configured statically rather than via service discovery. Not a vulnerability per se, but limits the network's resilience to peer churn.
Fix: documented as informational; consider DNS-based or registry-based peer discovery for production.
What: Are container images built with reproducibility / SBOM attestation? Are wheels installed from a verified PyPI mirror? Is the build pipeline signed?
Fix: generate SBOM via cyclonedx-py or syft; sign images with cosign; pin to an internal index where possible.
What: Are key operations (key-file load, on-chain tx submission, ABCI payload signing, strategy load, config-reload) recorded to a separate audit log distinct from operational logs? Without this, post-incident forensics is hard.
Fix: route security events to a dedicated logger / external audit sink; include timestamp, agent id, operation, outcome.
These patterns look suspicious but are correct by design. Do NOT report them:
Test fixtures (tests/, plugins/aea-test-autonomy/, conftest.py) routinely include hardcoded test private keys for deterministic test setup. These are well-known throwaway keys used by Hardhat / Ganache / test Tendermint. Do NOT flag these as C5. Limit C5 to non-test code paths.
Test YAML configs (tests/test_data/, aea-test-autonomy fixtures) use placeholder URLs / keys / addresses for hermetic testing. Don't flag these as H1 — they aren't deployed.
pickle.loads of internally-produced dataIf a pickle.loads reads a file or buffer that the agent itself wrote in the same process or container (e.g. local cache restore), it is not RCE-exposed in the same way as network input. Reduce severity to High and note the trust assumption.
subprocess.run(..., shell=False) with interpolated argsArgument interpolation is safe when shell=False because the shell isn't involved — argv is passed directly to execve. Don't flag these as C6. C6 requires shell=True.
random.* for non-security usesrandom.choice for jitter, log sampling, A/B test bucketing, etc. is fine. Limit M4 to uses where the output is a key, IV, nonce, token, password, or anything that protects a secret.
Tendermint RPC bound to 127.0.0.1 or an internal Docker network without external publication is the framework's default and is OK. H4 only applies when the port is published to a host interface or routable network.
eval( in framework metaprogrammingSome framework-internal code uses eval for limited purposes (e.g. enum.Enum value coercion in metaclass init). If the input is statically constructed inside the same module and not user-controlled, do not flag as C1. Verify the input source before flagging.
customs/ / package_overridesContract addresses are public on-chain. They are not secrets. Don't conflate with API keys.
Two sets of guardrails apply: the cross-skill ones already documented in /audit-fsm and /audit-resilience, and the security-specific ones below.
Apply the cross-skill guardrails from the sibling Methodology Guardrails sections without restating them here:
These reduce duplication and prevent drift when the sibling skills evolve. Below are the guardrails that are genuinely specific to security review.
Wallet.crypto_objects[<ledger>].entity / .private_key is callable from a behaviour).C2 is for disclosure. Exposure is M-level at most, often L (defense in depth). Don't over-escalate exposure to Critical.
For C1, C4, C6, M3 findings: name the source of the untrusted input (HTTP request body, ABCI payload field, env var, file content, IPFS payload). If you can't name it, downgrade or drop the finding.
If a finding fits /audit-fsm or /audit-resilience better, cite that skill's check ID as the primary and demote here. Examples:
logger.info(f'key={k}') → cite audit-fsm L4 first; /security-review C2 adds only the disclosure framing.requests.get(...) with no timeout → audit-resilience BP8 / CC5 owns this; /security-review flags only if the missing timeout enables a security-relevant DoS or resource-exhaustion attack on a trust boundary.This skill audits agent-process security in the open-autonomy codebase. The following are explicitly NOT covered — call this out in every report:
cryptography, eth_keys, web3.py etc. as black boxes. CVEs in those libraries surface via H7.Companion skills:
/audit-fsm — FSM correctness and safety/audit-resilience — external request resilienceInclude a "What this audit did not cover" section in every report.
Before manual inspection, run the framework's tooling and capture the output:
# Bandit — static analysis for common Python security issues
tox -e bandit
# Safety — known CVEs in pinned dependencies (uses tomte allowlist)
tox -e safety
# Gitleaks — secrets scanning across history
tox -e gitleaks
# Or run all three in parallel
make securityProcess the output:
B602 ≈ C6, B301 ≈ C4).Tooling-unavailable case. If the tox envs cannot run (network restrictions, missing tomte version), note in the report and proceed with manual checks. Do NOT block the audit on tool availability.
Launch up to 3 parallel Explore agents, dividing the codebase:
packages/, autonomy/, plugins/, customs/ for the C/H/M/L patterns above. For each match, capture file:line, the surrounding context, and the input source.aea-config.yaml, every service.yaml, every skill.yaml under audit. Extract env-var-interpolated params; flag insecure defaults (H1) and any param with security-relevant naming.Dockerfile*, docker-compose*.yaml, deployments/, kubernetes/ if present, and .github/workflows/*.yml. Flag root containers (H3), exposed RPC (H4), hardcoded secrets in deployment artifacts (H2), key-file permissions (M1).Each agent should return a structured list of candidates with check ID, file:line, and a short justification.
For each candidate from Step 1, an analysis agent:
After per-finding analysis:
Merge all findings into the output format below.
Present the security review as follows:
# Security Review
**Scope:** [list of audited paths / packages / services]
**Date:** [current date]
**Tools run:** bandit (Y/N), safety (Y/N), gitleaks (Y/N), pip-audit (Y/N — optional second-source; install manually)
## Executive Summary
- Critical findings: N
- High findings: N
- Medium findings: N
- Low findings: N
[2-3 sentences on the highest-impact findings and the systemic patterns they reveal]
## Critical Findings
### [C#]: [Title]
- **File:** `path/to/file.py:line`
- **Threat:** [what compromise this enables, who can trigger it]
- **Code:**
```python
[problematic code snippet][corrected code snippet][same format]
[same format]
[same format]
| Secret | Storage | Loaded by | Rotation policy |
|---|---|---|---|
| Ethereum private key | mounted volume | aea.crypto.wallet.Wallet | manual |
| ... |
| Boundary | Input source | Validator | Findings |
|---|---|---|---|
| ABCI payload | Tendermint network | check_payload() per round | H5 if missing |
| HTTP handler | external HTTP | per-handler _validate_* | M3 if missing |
| IPFS strategy | IPFS network | content-hash check | C3 if missing |
| Env-var config | host environment | none / startup check | H1 if defaulted |
| ... |
| Package | Version | License | CVE status |
|---|---|---|---|
| ... |
[counts by severity, top categories]
[CVEs not in allowlist]
[hits, by file]
/audit-fsm)/audit-resilience)
If no findings at a severity level, include the section header with "No findings." underneath.© valory-xyz, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in claude-skills/security-review of valory-xyz/open-autonomy.
Open the folder on GitHubat commit 62033a2
Security Review next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Security Review this skillvalory-xyz/open-autonomy | 129 | — | ~11k | Automated safety check: Notes | Apache-2.0 | |
| Kesekit Checkcdppcorp/KESE-KIT | 360 | — | ~1.3k | Automated safety check: Pass | MIT | |
| Bom Explorecdxgen/cdxgen | 1.1k | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| EdgeOne ClawScanTencent/AI-Infra-Guard | 6.8k | — | ~9.5k | Automated safety check: Pass | MIT | |
| Implementing Aes Encryption For Data At RESTmukul975/Anthropic-Cybersecurity-Skills | 34k | — | ~1.1k | Automated safety check: Pass | Apache-2.0 | |
| Runtime Trace Bomcdxgen/cdxgen | 1.1k | — | ~2k | Automated safety check: Pass | Apache-2.0 |
cdppcorp/KESE-KIT
Run a pre-deployment security compliance checklist based on KISA guidelines.
cdxgen/cdxgen
Explores and triages a CycloneDX BOM interactively with the cdxi REPL, using built-in commands for dependency trees, licenses, services, cryptographic assets, audit findings, evidence occurrences…
Tencent/AI-Infra-Guard
Runs a security health check on an OpenClaw environment and audits skills before or after installation for supply-chain and data-leak risks.
mukul975/Anthropic-Cybersecurity-Skills
Guides implementing AES-256 encryption in GCM mode (FIPS 197) for files and data stores at rest, covering key derivation, IV/nonce management, and authenticated encryption.
cdxgen/cdxgen
Produces a dynamic CycloneDX BOM by executing a command under the cdxgen safer-exec sandbox with tracebom, tracing dlopen shared-library loads, eBPF HTTP URL access, cryptographic library and…
sickn33/agentic-awesome-skills
Harden Docker/container images and runtime deployments with secure base images, non-root users, CVE scanning, SBOM/signing, seccomp/AppArmor, and Kubernetes pod security controls.
valory-xyz/open-autonomy
Audit open-autonomy FSM apps for correctness and safety. An agent skill from valory-xyz/open-autonomy.
valory-xyz/open-autonomy
Bump open-autonomy and open-aea (and their plugins / upstream-pin tags) to the latest released versions across any Valory downstream repo.
valory-xyz/open-autonomy
Audit all external HTTP requests in an open-autonomy agent service for resilience — failure modes, FSM propagation, crash/stuck/side-effect classification, and prioritized fix plan
Categories
Security review of an open-autonomy agent service — cryptographic key handling, dynamic code execution, ABCI authentication and replay, secret exposure, dependency supply chain, and deployment…. Security Review is an agent skill from valory-xyz/open-autonomy.
Security Review fits situations like: tasks that involve Security review; tasks that involve Cryptography; tasks that involve Supply chain security.
Run `npx skills add valory-xyz/open-autonomy --skill security-review -a claude-code`. Or copy the skill folder (claude-skills/security-review in valory-xyz/open-autonomy) into .claude/skills/security-review in your project. Claude Code loads it when a task matches its description.
Run `npx skills add valory-xyz/open-autonomy --skill security-review -a codex`. Or copy the skill folder (claude-skills/security-review in valory-xyz/open-autonomy) into .agents/skills/security-review in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add valory-xyz/open-autonomy --skill security-review -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/security-review, .gemini/skills/security-review, .github/skills/security-review and .opencode/skills/security-review in your project.
Going by SKILL.md and its folder, Security Review needs the command-line tools its instructions call (make, pip, docker and git) and credentials named API_KEY and PRIVATE_KEY. Our summary lists: Python 3; Docker; A credential in API_KEY.
SKILL.md contains no URLs. Its commands use pip, docker and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Security Review is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 11k tokens (SKILL.md is roughly 43k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Security Review: Kesekit Check (cdppcorp/KESE-KIT, 360 stars), Bom Explore (cdxgen/cdxgen, 1.1k stars), EdgeOne ClawScan (Tencent/AI-Infra-Guard, 6.8k stars) and Implementing Aes Encryption For Data At REST (mukul975/Anthropic-Cybersecurity-Skills, 34k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
valory-xyz (a GitHub organization) maintains it in valory-xyz/open-autonomy, which has 129 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on September 14, 2026.
Source: valory-xyz/open-autonomy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.