registry  /  @holt-os/holt  /  0.8.4

@holt-os/holt@0.8.4

An open-source personal agent OS: any LLM, private memory you can see and walk.

AI Security Review

scanned 5d ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
Explicit CLI commands such as holt init, setting, telegram, mcp, schedule, run, or chat
Impact
A configured user can expose local agent execution to Telegram or scheduled jobs; no unconsented install-time mutation was found.
Mechanism
User-configured agent automation and messaging integrations
Policy narrative
Scanner findings map to real capabilities, but source inspection shows they are part of a documented CLI agent product. The Telegram path sends selected brain output to the configured chat and accepts prompts only from the saved chat id. Persistence-like behavior is schedule/alias creation behind explicit CLI flows, not npm lifecycle execution.
Rationale
Because the package provides dangerous agent-facing automation but lacks unconsented lifecycle execution, credential theft, or author-controlled exfiltration, it should not be publish-blocked. The residual risk is user-invoked AI agent capability abuse rather than malware.
Evidence
package.jsondist/cli.jsREADME.md./.holt/config.json./.holt/memory/turns.jsonl./.holt/memory/facts.md./.holt/skills/~/.holt/trust.json~/.holt/credentials.json~/.holt/telegram.json~/.holt/schedules.json~/.holt/logs/<id>.log~/Library/LaunchAgents/com.holt.<id>.plist~/.zshrc~/.bashrc~/.profile
Network endpoints5
api.telegram.org127.0.0.1:11434api.anthropic.com/v1/messagesapi.openai.com/v1/chat/completionsgenerativelanguage.googleapis.com/v1beta/models/

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/cli.js exposes user-invoked Telegram bot that long-polls api.telegram.org and runs allowed chat messages through runTask.
  • dist/cli.js schedule add writes launchd plist or crontab entries for recurring holt run tasks after an interactive trust prompt.
  • dist/cli.js can install a shell alias/shim for holt chat via setting/init when user selects a launch command.
  • dist/cli.js mcp command auto-trusts the launch folder and exposes memory/skill tools over stdio.
Evidence against
  • package.json has no install/preinstall/postinstall lifecycle hooks.
  • All high-risk paths are CLI subcommands, not install-time or import-time execution.
  • Telegram setup requires pasted bot token and allowed chat id; messages from other chat ids are ignored.
  • Network endpoints are product-aligned: local Ollama, configured LLM APIs, and Telegram when explicitly configured.
  • No evidence of credential harvesting or package-author exfiltration; stored keys are used for selected providers.
  • MCP setup only prints client config and does not rewrite foreign agent config files.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 133 KB of source, external domains: 127.0.0.1, api.anthropic.com, api.openai.com, api.telegram.org, generativelanguage.googleapis.com, github.com, ollama.com, productsdecoded.com

Source & flagged code

4 flagged · loading source
dist/cli.jsView file
13import readline from "readline"; L14: var on = process.stdout.isTTY && !process.env.NO_COLOR; L15: var wrap = (code) => (s) => on ? `\x1B[${code}m${s}\x1B[0m` : s; ... L43: }); L44: const ask = (q) => new Promise((resolve4) => { L45: if (q) process.stdout.write(q); L46: if (buffer.length) resolve4(buffer.shift()); ... L53: // src/workspace.ts L54: var GLOBAL_DIR = join(homedir(), ".holt"); L55: var TRUST_PATH = join(GLOBAL_DIR, "trust.json"); ... L66: try { L67: return JSON.parse(readFileSync(TRUST_PATH, "utf8"));
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

dist/cli.jsView on unpkg · L13
13Trigger-reachable chain: manifest.bin -> dist/cli.js L13: import readline from "readline"; L14: var on = process.stdout.isTTY && !process.env.NO_COLOR; L15: var wrap = (code) => (s) => on ? `\x1B[${code}m${s}\x1B[0m` : s; ... L43: }); L44: const ask = (q) => new Promise((resolve4) => { L45: if (q) process.stdout.write(q); L46: if (buffer.length) resolve4(buffer.shift()); ... L53: // src/workspace.ts L54: var GLOBAL_DIR = join(homedir(), ".holt"); L55: var TRUST_PATH = join(GLOBAL_DIR, "trust.json"); ... L66: try { L67: return JSON.parse(readFileSync(TRUST_PATH, "utf8"));
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/cli.jsView on unpkg · L13
199// src/brains.ts L200: import { spawn, spawnSync } from "child_process"; L201: var MAX_REPLAY_TURNS = 12;
High
Child Process

Package source references child process execution.

dist/cli.jsView on unpkg · L199
13import readline from "readline"; L14: var on = process.stdout.isTTY && !process.env.NO_COLOR; L15: var wrap = (code) => (s) => on ? `\x1B[${code}m${s}\x1B[0m` : s; ... L43: }); L44: const ask = (q) => new Promise((resolve4) => { L45: if (q) process.stdout.write(q); L46: if (buffer.length) resolve4(buffer.shift()); ... L53: // src/workspace.ts L54: var GLOBAL_DIR = join(homedir(), ".holt"); L55: var TRUST_PATH = join(GLOBAL_DIR, "trust.json"); ... L66: try { L67: return JSON.parse(readFileSync(TRUST_PATH, "utf8"));
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/cli.jsView on unpkg · L13

Findings

2 Critical2 High4 Medium4 Low
CriticalCommand Output Exfiltrationdist/cli.js
CriticalTrigger Reachable Dangerous Capabilitydist/cli.js
HighChild Processdist/cli.js
HighShell
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/cli.js
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings