registry  /  constellai  /  0.5.1

constellai@0.5.1

AI Security Review

scanned 5d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The risky primitives are tied to an explicit local AI-agent management CLI and server runtime.

Static reason
One or more suspicious static signals were detected.
Trigger
npm install postinstall; user runs constella/constellai CLI or update command
Impact
Install may chmod shipped bins; runtime may create ~/.constella state, run migrations/server/worker, watch workspace markdown, and update global package only on user request.
Mechanism
CLI launcher with sqlite setup, local web/worker server, workspace watcher, and explicit self-update
Rationale
Static source inspection shows lifecycle, network, child_process, watcher, and updater behavior, but each is explained by the package's advertised local AI-agent control-plane runtime and is user-invoked or local-only. I found no stealth install-time execution beyond chmod, no credential harvesting/exfiltration, and no unconsented agent control-surface writes.
Evidence
package.jsonscripts/postinstall.mjsbin/constella.mjsbin/constella-update.mjsbin/worker.mjsscripts/start-all.mjsscripts/trim-next.mjs~/.constella/.env~/.constella/run.json~/.constella/constella.db~/.constella/organizations
Network endpoints5
registry.npmjs.org/constellai/latest127.0.0.1:<port>/api/cron/tick127.0.0.1:<port>/api/sync/file127.0.0.1:<port>/api/telegram/polltailscale.com/install.sh

Decision evidence

public snapshot
AI called this Clean at 87.0% confidence as Benign with low false-positive risk.
Evidence for block
  • package.json defines install-time postinstall and CLI bins constella/constellai
  • scripts/postinstall.mjs chmods bin/constella.mjs and bin/worker.mjs on POSIX
  • bin/constella.mjs uses child_process to run dependency CLIs, system probes, migrations, Next, and worker
  • bin/constella-update.mjs can run npm install -g constellai@latest during explicit update
  • bin/worker.mjs sends local worker-secret HTTP POSTs and watches ~/.constella/organizations workspaces
Evidence against
  • postinstall only changes executable bits and does not fetch, spawn shell, or harvest data
  • Network endpoints are package-aligned: npm registry update check, localhost worker routes, optional Tailscale install in vps mode
  • Update installer is reached by constella update/in-app update, not automatic install-time execution
  • Worker blocks sending its secret to non-loopback BASE unless explicit opt-in env is set
  • No credential exfiltration, persistence implant, destructive hidden behavior, or AI-agent control-surface mutation found
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNativeBindingsNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 26 file(s), 168 KB of source, external domains: 127.0.0.1, registry.npmjs.org, tailscale.com

Source & flagged code

11 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.mjs
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/constella-update.mjsView file
26*/ L27: import { spawnSync, spawn, execFileSync } from "node:child_process"; L28: import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
High
Child Process

Package source references child process execution.

bin/constella-update.mjsView on unpkg · L26
65const alive = (p) => { try { process.kill(p, 0); return true; } catch { return false; } }; L66: const psout = (s) => { try { return execFileSync("powershell", ["-NoProfile", "-Command", s], { timeout: 9000, windowsHide: true }).toString(); } catch { return ""; } }; L67: const ints = (s) => s.split(/\r?\n/).map((x) => +x.trim()).filter((n) => n > 0);
High
Shell

Package source references shell execution.

bin/constella-update.mjsView on unpkg · L65
11* Order matters: it INSTALLS FIRST, with the server still running. A live Constella does NOT lock the L12: * global package files (verified on Windows — `npm i -g` succeeds with the server up), so installing first L13: * just works, and if it can't we haven't taken the host down. Only THEN does it restart the server to load ... L26: */ L27: import { spawnSync, spawn, execFileSync } from "node:child_process"; L28: import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

bin/constella-update.mjsView on unpkg · L11
bin/constella.mjsView file
318// on Windows. Best-effort — never blocks boot; the server binds 0.0.0.0 regardless. L319: if (runMode === "vps" && process.env.CONSTELLA_SKIP_TAILSCALE !== "1") { L320: if (process.platform === "win32") { ... L323: const root = typeof process.getuid === "function" && process.getuid() === 0; L324: const sh = (cmd) => { try { execFileSync("sh", ["-c", cmd], { stdio: "inherit" }); } catch { /* best-effort */ } }; L325: const tsOk = () => { try { return spawnSync("tailscale", ["version"], { stdio: "ignore" }).status === 0; } catch { return false; } }; L326: if (!tsOk()) { console.log("• Installing Tailscale…"); sh(`curl -fsSL https://tailscale.com/install.sh | ${root ? "" : "sudo "}sh`); } L327: if (tsOk()) {
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

bin/constella.mjsView on unpkg · L318
19import { mkdirSync, existsSync, readFileSync, writeFileSync, chmodSync, readdirSync, rmSync } from "node:fs"; L20: import { spawnSync, spawn, execFileSync } from "node:child_process"; L21: import { createInterface } from "node:readline"; ... L33: const cand = join(dir, "node_modules", pkg); L34: if (existsSync(join(cand, "package.json"))) return cand; L35: const parent = dirname(dir); ... L46: try { L47: const b = JSON.parse(readFileSync(join(d, "package.json"), "utf8")).bin; L48: const rel = typeof b === "string" ? b : (b?.[binName] ?? b?.[pkg]); ... L97: try { L98: if (process.platform === "win32") { L99: const d = (p[0] || "C").toUpperCase();
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

bin/constella.mjsView on unpkg · L19
65package = constellai; repositoryIdentity = constella; dependency = better-sqlite3 L65: // So we must actually OPEN a db to trigger the dlopen and surface an ABI mismatch. L66: const tryLoad = () => { try { const D = nativeRequire("better-sqlite3"); new D(":memory:").close(); return null; } catch (e) { return e; } }; L67: const first = tryLoad();
High
Copied Package Dependency Bridge

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

bin/constella.mjsView on unpkg · L65
scripts/vps-update.shView file
path = scripts/vps-update.sh kind = build_helper sizeBytes = 3309 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/vps-update.shView on unpkg
skills/front-end/web-artifacts-builder/scripts/shadcn-components.tar.gzView file
path = skills/front-end/web-artifacts-builder/scripts/shadcn-components.tar.gz kind = compressed_blob sizeBytes = 19967 magicHex = [redacted]
Medium
Ships Compressed Blob

Package ships compressed or archive-like blobs.

skills/front-end/web-artifacts-builder/scripts/shadcn-components.tar.gzView on unpkg
skills/design/theme-factory/theme-showcase.pdfView file
path = skills/design/theme-factory/theme-showcase.pdf kind = high_entropy_blob sizeBytes = 124310 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

skills/design/theme-factory/theme-showcase.pdfView on unpkg

Findings

8 High6 Medium5 Low
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/constella-update.mjs
HighShellbin/constella-update.mjs
HighSame File Env Network Executionbin/constella.mjs
HighSandbox Evasion Gated Capabilitybin/constella.mjs
HighCopied Package Dependency Bridgebin/constella.mjs
HighRuntime Package Installbin/constella-update.mjs
HighShips High Entropy Blobskills/design/theme-factory/theme-showcase.pdf
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperscripts/vps-update.sh
MediumShips Compressed Blobskills/front-end/web-artifacts-builder/scripts/shadcn-components.tar.gz
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings