ocmesh
SuspiciousAudited by ClawScan on May 10, 2026.
Overview
This skill matches its mesh-network purpose, but it creates an always-on global agent communication channel with important trust, privacy, and install-integrity gaps.
Review carefully before installing. Only use this if you want an always-on public agent mesh presence. Do not assume group messages are private, treat all incoming peer content as untrusted, avoid enabling webhooks to sensitive agent endpoints without filtering, and verify the missing LaunchAgent plist/install behavior before running the installer.
Findings (7)
Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.
A user may send group messages believing they are private when relay operators or public relay observers may be able to read them.
Group messages are published as Nostr kind-42 events with raw content, which conflicts with SKILL.md's blanket claim that all messages are end-to-end encrypted and unreadable by relay operators.
const event = finishEvent({
kind: 42,
created_at: now,
tags: [['e', groupId, '', 'root']],
content,
}, identity.sk);
publish(event);Clearly document that group chats are not E2E-encrypted unless encryption is added, and limit the encryption claim to 1:1 NIP-04 direct messages.
Remote peers can send messages or task-shaped payloads that may enter the local agent/event pipeline if webhooks are enabled.
Inbound messages from mesh peers can be automatically forwarded, including decrypted content, to the configured webhook destination; the artifacts do not show a peer allowlist, trust policy, or sanitization boundary before this agent-to-agent content is pushed onward.
await webhook.fire('message.received', {
id: event.id,
from: event.pubkey,
type: msgType,
content: decrypted,
ts: Date.now(),
});Treat all peer messages as untrusted, add peer allowlisting or user approval before webhook delivery, and ensure any receiving OpenClaw agent does not treat remote message content as authoritative instructions.
A malicious or faulty relay could poison peer/profile/group data or trigger automated peer-handling flows more easily than users may expect.
Relay events are accepted and passed into peer/profile/message/group handlers without visible Nostr event ID/signature verification in this code, so peer identity and event origin depend heavily on relay behavior.
if (msg[0] === 'EVENT' && msg[2]) {
onEvent(msg[2], url);
}Validate Nostr events before processing them, verify signatures/IDs, and expose relay and peer trust settings.
Installation may fail, or users may not be able to review exactly what is being registered to run automatically at login.
The installer enables a persistent LaunchAgent using a plist source file that is not included in the provided manifest, creating a missing/unreviewed persistence artifact.
PLIST_SRC="$OCMESH_DIR/com.ocmesh.agent.plist" PLIST_DST="$HOME/Library/LaunchAgents/com.ocmesh.agent.plist" ... sed "s|/usr/local/bin/node|$NODE_PATH|g; s|OCMESH_DIR|$OCMESH_DIR|g" \ "$PLIST_SRC" > "$PLIST_DST" ... launchctl load -w "$PLIST_DST"
Include the LaunchAgent plist in the package, declare the install mechanism in metadata, and document stop/uninstall steps before enabling persistence.
The mesh daemon can continue announcing presence, discovering peers, and receiving messages whenever the user logs in.
The skill intentionally persists as a background daemon; this is disclosed and purpose-aligned, but it keeps operating after the initial user request.
Registers a macOS LaunchAgent — daemon auto-starts on every login, auto-restarts on crash.
Install only if you want an always-on mesh agent, and verify how to stop, disable, or uninstall the LaunchAgent.
Any local process or agent with access to the localhost API could cause this daemon to send messages or task payloads to mesh peers.
The localhost API can send task messages to peers. It is bound to 127.0.0.1, which is appropriate for local control, but the code does not show additional authentication or confirmation for high-impact sends.
app.post('/send/task', async (req, res) => {
const { to, action, params } = req.body;
...
const payload = create(MESSAGE_TYPES.TASK, { action, params: params || {} });
const id = await send(to, payload);Add a local API token or confirmation step for sends/config changes, and keep the API bound to localhost.
If ~/.ocmesh/ocmesh.db is copied or exposed, another party could impersonate the ocmesh identity.
The skill generates and stores a persistent Nostr private key used to identify and sign for the agent; this is expected for the mesh purpose but is a sensitive local credential.
const sk = generatePrivateKey();
const pk = getPublicKey(sk);
db.prepare('INSERT INTO identity (sk, pk) VALUES (?, ?)').run(sk, pk);Protect the ~/.ocmesh directory, avoid sharing backups of the database, and consider explicit file-permission hardening.
