Metered API Marketplace
WarnAudited by ClawScan on May 10, 2026.
Overview
The skill is mostly a coherent API billing template, but it includes a hard-coded paid external API prompt and payment/billing flows with unsafe defaults that users should review carefully.
Review and modify the integration prompt before use, especially the api.vms0.com base URL. Do not deploy until all required secrets are explicitly set, webhook providers fail closed when secrets are missing, dependencies are pinned, and billing behavior for failed requests is acceptable.
Findings (5)
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.
If copied as-is, an agent could send request data and paid API calls to api.vms0.com instead of the user’s own deployment.
This copy/paste prompt directs an agent to a fixed external paid API endpoint, while the skill is framed as helping the user build and operate their own metered endpoint.
You are integrating a paid, metered API called **VMS0 Metered API Marketplace**... Each request costs **$0.25**... Base URL `https://api.vms0.com`
Replace the base URL with the user-controlled deployment domain before use, and clearly document whether api.vms0.com is an example, an owned deployment, or a third-party service.
If deployed without a real webhook secret, attackers could potentially forge payment events and credit balances without paying.
The public payment webhook uses an empty string as the default shared secret and the server does not fail startup when the secret is unset, so a misconfigured deployment could accept forgeable webhook signatures.
const WEBHOOK_SHARED_SECRET = env('WEBHOOK_SHARED_SECRET', ''); ... const expected = hmacHex(WEBHOOK_SHARED_SECRET, raw.toString('utf8'));Require a non-empty webhook secret at startup for every webhook provider, fail closed when missing, and document it as a required environment variable.
Users may lose prepaid balance for failed transformation requests unless the operator adds refund or rollback handling.
The balance deduction and usage insert are committed before the transformer runs; if the transformer then fails, the user can receive a 500 error after being charged.
await client.query('COMMIT'); ... data = fn(body ?? {}); ... return res.status(500).json({ ok: false, error: 'transformer_failed' });Run the transformer before committing the charge, or add explicit refund/credit reversal logic for transformer failures.
Anyone with database access could recover API signing secrets and impersonate customers unless the deployment is carefully secured.
The service stores API key secrets in the database, which is expected for signed API-key auth but makes database access highly sensitive.
CREATE TABLE IF NOT EXISTS api_keys ( id TEXT PRIMARY KEY, secret TEXT NOT NULL, disabled_at TIMESTAMPTZ );
Protect the database connection, restrict admin access, consider secret encryption or rotation, and avoid exposing database credentials to agents or logs.
A future install could pull newer dependency versions than the author tested.
The runnable template uses npm dependencies with version ranges and no lockfile is shown in the manifest, which is common for a starter template but leaves dependency resolution to install time.
"dependencies": { "next": "^14.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "pg": "^8.13.3" }Generate and review a lockfile, pin dependency versions for production, and run dependency security checks before deploying.
