Back to skill

Security audit

Verified Agent Identity

Security checks for vulnerabilities and agentic risk

Overview

This identity skill is purpose-aligned, but it needs Review because it handles persistent private keys, stores them unencrypted, and relies on missing/unreviewed scripts.

Install only if you are comfortable with an identity tool that may create persistent cryptographic keys under your home directory and send signed identity proofs to other parties. Treat any private key passed on the command line as exposed, verify the missing scripts and dependencies from a trusted source before running setup, and prefer encrypted or OS-backed key storage before using the identity for anything important.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:150
Finding
Unencrypted Private Keys Stored in a Predictable Local File<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 150-160 **Vulnerability Type**: Plaintext storage of cryptographic secrets **Risk Level**: High ### Vulnerable Code Snippet ```markdown ## Security **CRITICAL - Data Storage and Protection:** The directory `$HOME/.openclaw/billions` contains all sensitive identity data: - `kms.json` - **CRITICAL**: Contains unencrypted private keys - `defaultDid.json` - DID identifiers and public keys - `challenges.json` - Authentication challenges history - `credentials.json` - Verifiable credentials - `identities.json` - Identity metadata - `profiles.json` - Profile data ``` ### Technical Analysis The Skill explicitly documents that identity private keys are stored unencrypted in `$HOME/.openclaw/billions/kms.json`. This is a predictable filesystem location, and the documentation does not specify encryption at rest, restrictive file permissions, operating-system keychain integration, process isolation, or any other access-control mechanism. A private key is the root authentication secret for the associated decentralized identity. Any local process or user that can read `kms.json` can copy the key and perform cryptographic operations outside the intended Skill workflow. The restrictions against manually reading or manipulating the directory are agent instructions rather than enforceable security controls and therefore do not protect the file from other processes or a compromised account. ### Attack Path 1. The Skill creates or imports an identity. 2. Its private key is written unencrypted to `$HOME/.openclaw/billions/kms.json`. 3. Another local process, compromised Skill, malicious dependency, backup reader, or user with access to the account reads the predictable file. 4. The attacker extracts the private key. 5. The attacker imports the key into another tool or environment. 6. The attacker signs challenges and impersonates the affected agent identity without using the legitimate Skill. ### Impa ...[truncated 584 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not store raw private keys in plaintext JSON files. - Integrate with an operating-system credential manager, hardware-backed key store, hardware security module, or encrypted keystore. - If filesystem storage is unavoidable, encrypt every private key using a user-supplied secret and a modern authenticated-encryption scheme. - Create the storage directory with permissions limited to the owning user and create secret files with mode `0600`. - Verify ownership and permissions before every key operation and refuse to continue if they are unsafe. - Ensure backups, logs, diagnostics, and error reports exclude private-key material. - Minimize the duration for which decrypted keys remain in process memory and clear sensitive buffers when feasible. - Provide documented key rotation and revocation procedures for suspected compromise. - Add automated tests that verify private keys are never persisted in plaintext. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:35
Finding
Private Keys Accepted Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 35-49 **Vulnerability Type**: Sensitive data exposure through process arguments and execution history **Risk Level**: High ### Vulnerable Code Snippet ```markdown ### createNewEthereumIdentity.js **Command**: `node scripts/createNewEthereumIdentity.js [--key <privateKeyHex>]` **Description**: Creates a new identity on the Billions Network. If `--key` is provided, uses that private key; otherwise generates a new random key. The created identity is automatically set as default. **Usage Examples**: ```bash # Generate a new random identity node scripts/createNewEthereumIdentity.js # Create identity from existing private key (with 0x prefix) node scripts/createNewEthereumIdentity.js --key 0x1234567890abcdef... # Create identity from existing private key (without 0x prefix) node scripts/createNewEthereumIdentity.js --key 1234567890abcdef... ``` ``` ### Technical Analysis The documented interface passes an identity private key through the `--key` command-line argument. Command-line arguments are not an appropriate secret-transport mechanism because they may be exposed through: - Process inspection interfaces and process-listing tools. - Shell history. - Terminal session recording. - Agent tool-call transcripts and execution logs. - Monitoring, telemetry, crash reporting, or audit systems. - Parent processes or other processes operating with sufficient local privileges. Masking the key after argument parsing would not eliminate these exposures because the secret may already have been recorded before the script starts processing it. ### Attack Path 1. A user follows the documented example and runs `createNewEthereumIdentity.js --key <private-key>`. 2. The complete private key becomes part of the process command line. 3. The command is retained in shell history, agent execution history, telemetry, or process-monitoring output. 4. An attacker or unauthorized local operator obtains access to o ...[truncated 701 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `--key` command-line option. - Prefer importing keys directly from an operating-system credential manager or encrypted keystore. - If interactive import is required, read the key from a protected terminal prompt with input echo disabled. - Alternatively, accept the secret through a restricted file descriptor or a securely permissioned temporary input file that is deleted immediately after use. - Do not use environment variables for long-lived private keys, because they may also be visible to process inspection and diagnostic tools. - Redact secrets from tool-call transcripts, telemetry, exceptions, and audit logs. - Warn users that any key previously entered through the command line may remain in history and should be considered exposed. - Document procedures to remove affected history records and rotate or revoke exposed identity keys. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:19
Finding
Unverifiable and Potentially Unsafe Dependency Installation Workflow<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 19-25 **Vulnerability Type**: Missing dependency provenance and unrestricted package installation **Risk Level**: Medium ### Vulnerable Code Snippet ```markdown ### After installing the plugin run the following commands to create an identity and link it to your human DID: ```bash cd scripts && npm install && cd .. # Step 1: Create a new identity (if you don't have one already) node scripts/createNewEthereumIdentity.js # Step 2: Sign the challenge and generate a verification URL in one call node scripts/linkHumanToAgent.js --to <SENDER> --challenge '{"name": <AGENT_NAME>, "description": <SHORT_DESCRIPTION>}' ``` ``` ### Technical Analysis The audited project contains only `SKILL.md`. It does not contain the referenced `scripts/` directory, JavaScript source files, `package.json`, or a lockfile. Consequently, neither the documented scripts nor their dependency graph can be reviewed or verified from the supplied artifact. The instructions also use unrestricted `npm install`. If missing project files are later obtained from another source, this command may resolve unpinned or modified packages and execute package lifecycle scripts. The absence of a reviewed manifest and lockfile prevents verification of package names, versions, integrity hashes, transitive dependencies, and installation hooks. The current artifact does not prove that a malicious dependency exists. The confirmed issue is that the installation and executable behavior are unverifiable as packaged, while the prescribed workflow creates a supply-chain execution opportunity if users acquire or substitute the missing files from an unsafe source. ### Attack Path 1. An operator installs the supplied artifact and follows its setup instructions. 2. The referenced `scripts/` directory and package metadata are found to be missing. 3. To make the Skill operational, the operator obtains the missing files from a separate, unreviewed so ...[truncated 1135 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Include every referenced script and the complete dependency manifest in the reviewed Skill package. - Include a lockfile containing exact dependency versions and integrity data. - Use `npm ci` rather than `npm install` for reproducible installation. - Use `npm ci --ignore-scripts` when package lifecycle scripts are not strictly required. - If lifecycle scripts are required, enumerate, review, and document each one before installation. - Pin direct and transitive dependencies to reviewed versions and monitor them for compromise. - Verify package provenance and integrity through a trusted registry and package-signing or attestation mechanisms where available. - Do not instruct users to retrieve missing executable files from unspecified external sources. - Re-audit the JavaScript implementations and complete dependency tree before treating the identity, signing, messaging, or storage behavior as trusted. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Content
---
name: verified-agent-identity
description: Billions/Iden3 authentication and identity management tools for agents. Link, proof, sign, and verify.
metadata: { "category": "identity", "clawbot": { "requires": { "bins": ["node", "openclaw"] } }}
homepage: https://billions.network/
---

## When to use this Skill

Lets AI agents create and manage their own identities on the Billions Network, and link those identities to a human owner.

1. When you need to link your agent identity to an owner.
2. When you need sign a challenge.
3. When you need link a human to the agent's DID.
4. When you need to verify a signature to confirm identity ownership.
5. When use shared JWT tokens for authentication.
6. When you need to create and manage decentralized identities.

### After installing the plugin run the following commands to create an identity and link it to your human DID:

```bash
cd scripts && npm install && cd
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Credential Access

High
Category
Privilege Escalation
Content
- `kms.json` - **CRITICAL**: Contains unencrypted private keys
- `defaultDid.json` - DID identifiers and public keys
- `challenges.json` - Authentication challenges history
- `credentials.json` - Verifiable credentials
- `identities.json` - Identity metadata
- `profiles.json` - Profile data
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The installation and usage flow tells users to create an identity immediately, while the later security section reveals that private keys are stored unencrypted in $HOME/.openclaw/billions/kms.json. Encouraging key generation and persistence before prominently disclosing that sensitive key material will be retained in plaintext can lead to accidental exposure, backup leakage, or compromise by other local processes.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The skill explicitly instructs agents to sign challenges, generate verification URLs, and send direct messages to external recipients, but it does not prominently warn that identity-related artifacts and metadata leave the local system. In an identity-management skill, this omission increases the chance that operators disclose DID-linked information, proofs, or verification material without understanding the privacy and trust implications.

Static analysis

No suspicious patterns detected.