registry  /  substrate-ai  /  0.21.1

substrate-ai@0.21.1

Substrate — multi-agent orchestration daemon for AI coding agents

AI Security Review

scanned 3h ago · by lpm-firewall-ai

No unconsented install-time attack was found, but the package contains a user-invoked remote agent bridge with filesystem and shell tools. It also has a pipeline recovery path that may install missing npm packages based on build errors.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs substrate CLI pipeline/factory direct backend/init commands
Impact
User project files and commands can be modified/executed by configured agents; dependency install may introduce supply-chain risk if enabled by workflow.
Mechanism
LLM-directed file/shell tooling and runtime package install
Rationale
substrate-ai is an AI coding-agent orchestration CLI, so shell/file/model integrations are package-aligned and user-invoked, with no npm lifecycle mutation or covert exfiltration found. The remote agent bridge and automatic missing-package install are real dangerous capabilities, so warn rather than block.
Evidence
package.jsondist/cli/index.jsdist/run-JrEnvaB0.jsdist/dist-BkhYgJWo.jsdist/health-Cfkv6XoQ.js.substrate/CLAUDE.mdAGENTS.mdGEMINI.md.claude/commands/.claude/skills/.codex/prompts/.codex/skills/
Network endpoints5
api.anthropic.comapi.openai.com/v1generativelanguage.googleapis.comlocalhost:4566/_localstack/healthlocalhost:8080/__admin/health

Decision evidence

public snapshot
AI called this Suspicious at 83.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/run-JrEnvaB0.js exposes read_file/write_file/shell/edit/apply_patch tools to direct LLM backends.
  • dist/run-JrEnvaB0.js direct backend reads ANTHROPIC_API_KEY/OPENAI_API_KEY/GEMINI_API_KEY and calls provider APIs.
  • dist/run-JrEnvaB0.js build-fix path can run `npm install ${missingPkg}` from build output during user-invoked pipeline execution.
  • dist/cli/index.js init scaffolds AI-agent files such as CLAUDE.md, AGENTS.md, GEMINI.md, .claude, and .codex content.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hooks.
  • Dangerous primitives are behind explicit CLI commands such as `substrate run`, `factory run --backend direct`, or `substrate init`.
  • Network endpoints are AI/provider or local telemetry/health endpoints aligned with an AI orchestration package.
  • dist/cli/index.js user-scope Codex install is explicit via `--install-user-scope` and namespaced substrate-* content.
  • No credential harvesting or covert exfiltration path found in inspected entrypoints.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 30 file(s), 2.88 MB of source, external domains: ai.google.dev, api.anthropic.com, api.openai.com, claude.ai, docs.dolthub.com, generativelanguage.googleapis.com, git-scm.com, github.com, json-schema.org, json.schemastore.org, raw.githubusercontent.com, registry.npmjs.org

Source & flagged code

9 flagged · loading source
dist/upgrade-S1oUMH5P.jsView file
1import { createVersionManager } from "./dist-BkhYgJWo.js"; L2: import { execSync, spawn } from "child_process"; L3: import * as readline from "readline";
High
Child Process

Package source references child process execution.

dist/upgrade-S1oUMH5P.jsView on unpkg · L1
dist/run-JrEnvaB0.jsView file
37655cwd, L37656: shell: true L37657: });
High
Shell

Package source references shell execution.

dist/run-JrEnvaB0.jsView on unpkg · L37655
16import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs... L17: import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process"; L18: import * as path$2 from "node:path"; ... L5099: if (existsSync(profilePath)) try { L5100: const raw = readFileSync(profilePath, "utf-8"); L5101: const parsed = yaml.load(raw); ... L35883: apiKey; L35884: baseUrl; L35885: anthropicVersion; ... L37291: "", L37292: "Available tools:", L37293: "- read_file: Read file contents with optional line range (offset/limit)",
High
Remote Agent Bridge

Source exposes local file and command tools to a remote model endpoint.

dist/run-JrEnvaB0.jsView on unpkg · L16
15515try { L15516: execSync(`npm install ${missingPkg}`, { L15517: cwd: resolvedRoot,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/run-JrEnvaB0.jsView on unpkg · L15515
31844try { L31845: var makeValidate = new Function("self", "RULES", "formats", "root", "refVal", "defaults", "customRules", "equal", "ucs2length", "ValidationError", sourceCode); L31846: validate$1 = makeValidate(self, RULES, formats$2, root, refVal, defaults$2, customRules, equal, ucs2length, ValidationError);
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/run-JrEnvaB0.jsView on unpkg · L31844
dist/cli/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = substrate-ai@0.20.148 matchedIdentity = npm:c3Vic3RyYXRlLWFp:0.20.148 similarity = 0.846 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

dist/cli/index.jsView on unpkg
1574try { L1575: const _require = createRequire(join(fromDir, "synthetic.js")); L1576: const pkgJsonPath = _require.resolve("bmad-method/package.json");
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/cli/index.jsView on unpkg · L1574
dist/dist-BkhYgJWo.jsView file
3package = substrate-ai; repositoryIdentity = substrate; dependency = js-yaml L3: import { EventEmitter } from "node:events"; L4: import yaml, { dump, load } from "js-yaml"; L5: import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

dist/dist-BkhYgJWo.jsView on unpkg · L3
dist/cli/templates/statusline.shView file
path = dist/cli/templates/statusline.sh kind = build_helper sizeBytes = 565 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

dist/cli/templates/statusline.shView on unpkg

Findings

1 Critical5 High5 Medium5 Low
CriticalPrevious Version Dangerous Deltadist/cli/index.js
HighChild Processdist/upgrade-S1oUMH5P.js
HighShelldist/run-JrEnvaB0.js
HighRemote Agent Bridgedist/run-JrEnvaB0.js
HighCopied Package Dependency Bridgedist/dist-BkhYgJWo.js
HighRuntime Package Installdist/run-JrEnvaB0.js
MediumDynamic Requiredist/cli/index.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperdist/cli/templates/statusline.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowEvaldist/run-JrEnvaB0.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings