registry  /  @hiperplano/aluy-cli  /  1.0.0-rc.63

@hiperplano/aluy-cli@1.0.0-rc.63

Aluy CLI — TUI (Ink) + binário `aluy` + wiring. Consome @hiperplano/aluy-cli-core (engine portável). Credenciais só no keychain do SO.

AI Security Review

scanned 9d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The risky primitives are expected for a user-invoked AI terminal agent and are guarded by permission and anti-SSRF controls.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs the aluy CLI or onboard/bootstrap commands.
Impact
Can edit files, run commands, call configured model providers, and manage local ~/.aluy state when invoked by the user.
Mechanism
User-directed AI agent tooling with permission gates
Rationale
Static inspection shows a legitimate AI CLI with dangerous but declared and user-invoked capabilities, no install-time execution, no hidden credential harvesting, and no concrete exfiltration behavior. Scanner hits on metadata, env, network, and child_process map to anti-SSRF checks, provider/auth plumbing, permission-gated tools, and local sidecars.
Evidence
package.jsonREADME.mddist-bundle/bin/aluy.jsdist-bundle/index.jsassets/mem0/aluy-mem0-server.py~/.aluy/config.json~/.aluy/providers.json~/.aluy/mcp.json~/.aluy/audit.jsonl~/.aluy/logs/*.log~/.aluy/memory~/.mem0/history.db
Network endpoints11
api.anthropic.comapi.openai.com/v1openrouter.ai/api/v1generativelanguage.googleapis.com/v1betaapi.deepseek.comapi.groq.com/openai/v1api.mistral.ai/v1api.x.ai/v1api.telegram.org127.0.0.1:11434127.0.0.1:11435

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • dist-bundle/bin/aluy.js is an agent CLI with user-invoked command execution, file editing, MCP, and sidecar spawning capabilities.
  • dist-bundle/bin/aluy.js can write ~/.aluy config/audit/log files during onboard/bootstrap/runtime actions.
Evidence against
  • package.json has no lifecycle scripts; main/bin are only runtime entrypoints.
  • README.md describes the same AI terminal-agent, BYO provider, keychain, MCP, and optional sidecar behavior seen in code.
  • dist-bundle/bin/aluy.js gates risky tool calls through permission categories for network, destructive commands, secrets, escalation, and package execution.
  • dist-bundle/bin/aluy.js contains anti-SSRF checks that explicitly reject 169.254.169.254/link-local/private IPs for local provider egress.
  • Network calls are package-aligned: broker/provider APIs, Telegram command, local Ollama/mem0/headroom, and README GitHub images.
  • assets/mem0/aluy-mem0-server.py binds to 127.0.0.1 and stores local memory under ~/.aluy/memory; no external exfiltration path found.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNativeBindingsNetwork
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareUrlStrings
Manifest
NoLicense
scanned 2 file(s), 1.83 MB of source, external domains: 127.0.0.1, api.aluy.app, api.anthropic.com, api.deepseek.com, api.groq.com, api.mistral.ai, api.openai.com, api.telegram.org, api.x.ai, auth.openai.com, broker.dev.aluy.example, claude.ai, console.anthropic.com, duckduckgo.com, generativelanguage.googleapis.com, github.com, ollama.com, openrouter.ai, registry.npmjs.org

Source & flagged code

10 flagged · loading source
dist-bundle/bin/aluy.jsView file
8${n}`,display:o}}case"text":return{ok:!0,observation:`O usu\xE1rio respondeu \xE0 pergunta "${t.question}": L9: ${e.text}`,display:o};case"unavailable":return{ok:!1,observation:`N\xE3o foi poss\xEDvel PERGUNTAR ao usu\xE1rio: ${e.reason}. Isto N\xC3O \xE9 um erro t\xE9cnico nem motivo para r... L10: `).map(s=>s.trim()===""?"":` ${s}`).join(` L11: `);return[`<<<DADO_NAO_CONFIAVEL origem=${o}>>>`,r,"<<<FIM_DADO>>>"].join(` L12: `)}var dH,uH,Zg=p(()=>{"use strict";dH="<<<FIM_DADO>>>",uH="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as mH}from"node:crypto";function ty(t,e){let o=[...t,e];return o.length>ey?o... L13: ... L23: L24: `)+q}}}]}var es,dy,jE,wm=p(()=>{"use strict";ry();Dl();cy();es="room_post",dy="room_read",jE=["ask","inform","result","ack"]});function Am(t,e,o){for(let n of t.rules)if(n.tool===e... L25: `);let s=o.indexOf(` ... L30: `)){if(r===""||r.startsWith(":"))continue;let s=r.indexOf(":"),i=s===-1?r:r.slice(0,s),a=s===-1?"":r.slice(s+1);a.startsWith(" ")&&(a=a.slice(1)),i==="event"?(e=a,n=!0):i==="data"&... L31: `)}:null}var Nm=p(()=>{"use strict"});function RT(t=globalThis.process?.env??{}){let e=AT(t[TT]),o=AT(t[CT]);return{maxConsecutiveLineRepeats:e!==void 0
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

dist-bundle/bin/aluy.jsView on unpkg · L8
129${n.snippet}`.trimEnd());return[`Resultados de busca para "${t}" (DuckDuckGo):`,...o,"","(As URLs acima N\xC3O foram buscadas. Para abrir uma, use web_fetch \u2014 ela passar\xE1 n... L130: `)}var nG,rG,vO,sG,kO,Of,SO=p(()=>{"use strict";Ar();Rf();ek();nG=8;rG=Object.freeze({type:"object",properties:{url:{type:"string",description:"OBRIGAT\xD3RIO. A URL http(s) a busc... L131: ... L135: ${t.trim()}`}}function MO(t,e,o=Jc){let{older:n,recent:r}=If(t,o);if(n.length===0)return{history:t,stats:{turnsBefore:t.length,turnsAfter:t.length,summarizedTurns:0}};let s=[OO(e,n... L136: `),Jc=4,Lf=1500,Pf=.4,Mf=48e3;fi=class extends Error{constructor(){super("hist\xF3rico curto demais \u2014 nada a compactar."),this.name="NothingToCompactError"}},Xc=class{model;ke... L137: `;case"t":return" ";case"r":return"\r";case'"':return'"';case"\\":return"\\";default:throw new pe(`config.toml:${e}: escape n\xE3o suportado "\\${i}".`)}})}function TG(t,e,o){let n... ... L141: `)}function KG(t,e){return t.length<=e?t:t.slice(0,e-1).trimEnd()+"\u2026"}var S0=p(()=>{"use strict"});var w0=p(()=>{"use strict";Yf();n0();r0();s0();i0();l0();m0();pm();b0();S0()... L142: `,r;try{r=mz(o,Xk.O_CREAT|Xk.O_EXCL|Xk.
Critical
Command Output Exfiltration

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

dist-bundle/bin/aluy.jsView on unpkg · L129
88L89: `):void 0}function X_(t,e,o){if(o===void 0)return e;let n=uv(t.model);return n===void 0?e:o(n)}var q_,W_,G_,ii,gv,z_,K_,a2,yv,Cc,bv=p(()=>{"use strict";Hb();mv();fv();Ks();cv();yf(... L90:
High
Child Process

Package source references child process execution.

dist-bundle/bin/aluy.jsView on unpkg · L88
135${t.trim()}`}}function MO(t,e,o=Jc){let{older:n,recent:r}=If(t,o);if(n.length===0)return{history:t,stats:{turnsBefore:t.length,turnsAfter:t.length,summarizedTurns:0}};let s=[OO(e,n... L136: `),Jc=4,Lf=1500,Pf=.4,Mf=48e3;fi=class extends Error{constructor(){super("hist\xF3rico curto demais \u2014 nada a compactar."),this.name="NothingToCompactError"}},Xc=class{model;ke... L137: `;case"t":return" ";case"r":return"\r";case'"':return'"';case"\\":return"\\";default:throw new pe(`config.toml:${e}: escape n\xE3o suportado "\\${i}".`)}})}function TG(t,e,o){let n... ... L141: `)}function KG(t,e){return t.length<=e?t:t.slice(0,e-1).trimEnd()+"\u2026"}var S0=p(()=>{"use strict"});var w0=p(()=>{"use strict";Yf();n0();r0();s0();i0();l0();m0();pm();b0();S0()... L142: `,r;try{r=mz(o,Xk.O_CREAT|Xk.O_EXCL|Xk.O_WRONLY,vz),fz(r,n),K0(r),r=void 0,gz(o,this.file)}catch(s){if(r!==void 0)try{K0(r)}catch{}try{yz(o)}catch{}throw s}}}});function ex(t){let ... L143: `}`)}}else process.stderr.write(`${l?"\r":""} baixando ${e}... ${m} MB${l?"":`
High
Same File Env Network Execution

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

dist-bundle/bin/aluy.jsView on unpkg · L135
8${n}`,display:o}}case"text":return{ok:!0,observation:`O usu\xE1rio respondeu \xE0 pergunta "${t.question}": L9: ${e.text}`,display:o};case"unavailable":return{ok:!1,observation:`N\xE3o foi poss\xEDvel PERGUNTAR ao usu\xE1rio: ${e.reason}. Isto N\xC3O \xE9 um erro t\xE9cnico nem motivo para r... L10: `).map(s=>s.trim()===""?"":` ${s}`).join(` L11: `);return[`<<<DADO_NAO_CONFIAVEL origem=${o}>>>`,r,"<<<FIM_DADO>>>"].join(` L12: `)}var dH,uH,Zg=p(()=>{"use strict";dH="<<<FIM_DADO>>>",uH="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as mH}from"node:crypto";function ty(t,e){let o=[...t,e];return o.length>ey?o... L13: ... L23: L24: `)+q}}}]}var es,dy,jE,wm=p(()=>{"use strict";ry();Dl();cy();es="room_post",dy="room_read",jE=["ask","inform","result","ack"]});function Am(t,e,o){for(let n of t.rules)if(n.tool===e... L25: `);let s=o.indexOf(` ... L30: `)){if(r===""||r.startsWith(":"))continue;let s=r.indexOf(":"),i=s===-1?r:r.slice(0,s),a=s===-1?"":r.slice(s+1);a.startsWith(" ")&&(a=a.slice(1)),i==="event"?(e=a,n=!0):i==="data"&... L31: `)}:null}var Nm=p(()=>{"use strict"});function RT(t=globalThis.process?.env??{}){let e=AT(t[TT]),o=AT(t[CT]);return{maxConsecutiveLineRepeats:e!==void 0
High
Sandbox Evasion Gated Capability

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

dist-bundle/bin/aluy.jsView on unpkg · L8
8${n}`,display:o}}case"text":return{ok:!0,observation:`O usu\xE1rio respondeu \xE0 pergunta "${t.question}": L9: ${e.text}`,display:o};case"unavailable":return{ok:!1,observation:`N\xE3o foi poss\xEDvel PERGUNTAR ao usu\xE1rio: ${e.reason}. Isto N\xC3O \xE9 um erro t\xE9cnico nem motivo para r... L10: `).map(s=>s.trim()===""?"":` ${s}`).join(` L11: `);return[`<<<DADO_NAO_CONFIAVEL origem=${o}>>>`,r,"<<<FIM_DADO>>>"].join(` L12: `)}var dH,uH,Zg=p(()=>{"use strict";dH="<<<FIM_DADO>>>",uH="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as mH}from"node:crypto";function ty(t,e){let o=[...t,e];return o.length>ey?o... L13: ... L23: L24: `)+q}}}]}var es,dy,jE,wm=p(()=>{"use strict";ry();Dl();cy();es="room_post",dy="room_read",jE=["ask","inform","result","ack"]});function Am(t,e,o){for(let n of t.rules)if(n.tool===e... L25: `);let s=o.indexOf(` ... L30: `)){if(r===""||r.startsWith(":"))continue;let s=r.indexOf(":"),i=s===-1?r:r.slice(0,s),a=s===-1?"":r.slice(s+1);a.startsWith(" ")&&(a=a.slice(1)),i==="event"?(e=a,n=!0):i==="data"&... L31: `)}:null}var Nm=p(()=>{"use strict"});function RT(t=globalThis.process?.env??{}){let e=AT(t[TT]),o=AT(t[CT]);return{maxConsecutiveLineRepeats:e!==void 0
High
Cloud Metadata Access

Source reaches cloud instance metadata or link-local credential endpoints.

dist-bundle/bin/aluy.jsView on unpkg · L8
8Cross-file remote execution chain: dist-bundle/bin/aluy.js spawns dist-bundle/index.js; helper contains network access plus dynamic code execution. L8: ${n}`,display:o}}case"text":return{ok:!0,observation:`O usu\xE1rio respondeu \xE0 pergunta "${t.question}": L9: ${e.text}`,display:o};case"unavailable":return{ok:!1,observation:`N\xE3o foi poss\xEDvel PERGUNTAR ao usu\xE1rio: ${e.reason}. Isto N\xC3O \xE9 um erro t\xE9cnico nem motivo para r... L10: `).map(s=>s.trim()===""?"":` ${s}`).join(` L11: `);return[`<<<DADO_NAO_CONFIAVEL origem=${o}>>>`,r,"<<<FIM_DADO>>>"].join(` L12: `)}var dH,uH,Zg=p(()=>{"use strict";dH="<<<FIM_DADO>>>",uH="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as mH}from"node:crypto";function ty(t,e){let o=[...t,e];return o.length>ey?o... L13: ... L23: L24: `)+q}}}]}var es,dy,jE,wm=p(()=>{"use strict";ry();Dl();cy();es="room_post",dy="room_read",jE=["ask","inform","result","ack"]});function Am(t,e,o){for(let n of t.rules)if(n.tool===e... L25: `);let s=o.indexOf(` ... L30: `)){if(r===""||r.startsWith(":"))continue;let s=r.indexOf(":"),i=s===-1?r:r.slice(0,s),a=s===-1?"":r.slice(s+1);a.startsWith(" ")&&(a=a.slice(1)),i==="event"?(e=a,n=!0):i==="data"&... L31: `)}…
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist-bundle/bin/aluy.jsView on unpkg · L8
8${n}`,display:o}}case"text":return{ok:!0,observation:`O usu\xE1rio respondeu \xE0 pergunta "${t.question}": L9: ${e.text}`,display:o};case"unavailable":return{ok:!1,observation:`N\xE3o foi poss\xEDvel PERGUNTAR ao usu\xE1rio: ${e.reason}. Isto N\xC3O \xE9 um erro t\xE9cnico nem motivo para r... L10: `).map(s=>s.trim()===""?"":` ${s}`).join(` L11: `);return[`<<<DADO_NAO_CONFIAVEL origem=${o}>>>`,r,"<<<FIM_DADO>>>"].join(` L12: `)}var dH,uH,Zg=p(()=>{"use strict";dH="<<<FIM_DADO>>>",uH="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as mH}from"node:crypto";function ty(t,e){let o=[...t,e];return o.length>ey?o... L13: ... L23: L24: `)+q}}}]}var es,dy,jE,wm=p(()=>{"use strict";ry();Dl();cy();es="room_post",dy="room_read",jE=["ask","inform","result","ack"]});function Am(t,e,o){for(let n of t.rules)if(n.tool===e... L25: `);let s=o.indexOf(` ... L30: `)){if(r===""||r.startsWith(":"))continue;let s=r.indexOf(":"),i=s===-1?r:r.slice(0,s),a=s===-1?"":r.slice(s+1);a.startsWith(" ")&&(a=a.slice(1)),i==="event"?(e=a,n=!0):i==="data"&... L31: `)}:null}var Nm=p(()=>{"use strict"});function RT(t=globalThis.process?.env??{}){let e=AT(t[TT]),o=AT(t[CT]);return{maxConsecutiveLineRepeats:e!==void 0
Medium
Install Persistence

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

dist-bundle/bin/aluy.jsView on unpkg · L8
dist-bundle/index.jsView file
425Trigger-reachable chain: manifest.main -> dist-bundle/index.js L425: - Credencial S\xD3 no keychain do SO \u2014 nunca em texto em claro. L426: - Loop de agente + ferramentas nativas + controle de permiss\xE3o integrados.`;function ze(t,e,o={}){let n=`--${e}=`;for(let r=0;r<t.length;r++){let s=t[r];if(s===`--${e}`){let i=t... L427: \u2026[truncado: corpo maior que ${e.maxBytes} bytes]`),f({status:M,body:Y,...H?{contentType:H}:{}})}),C.on("close",()=>{if(l)return;let Y=Buffer.concat(I).toString("utf8")+(W?` ... L429: \u2026[truncado: corpo maior que ${e.maxBytes} bytes]`;f({status:M,body:oe,...H?{contentType:H}:{}});return}u(Y)})}),w=()=>{h.destroy(),u(new Error("cancelado"))},E=setTimeout(()=>... L430: ${Vo(w)}`}}catch(g){let y=d?`o proxy n\xE3o respondeu em ${f}ms (timeout)`:g instanceof Error?g.message:String(g);return{ok:!1,display:c,observation:`headroom_retrieve: falha ao fa... L431: [arquivo truncado: lidos ${this.maxReadBytes} de ${s} bytes]`:n}async readFileMeta(e){let o=this.workspace.resolveInside(e),{content:n,truncated:r,binary:s}=await Ii(o,this.maxRead...
Critical
Trigger Reachable Dangerous Capability

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

dist-bundle/index.jsView on unpkg · L425
assets/mem0/aluy-mem0-server.pyView file
path = assets/mem0/aluy-mem0-server.py kind = build_helper sizeBytes = 20729 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

assets/mem0/aluy-mem0-server.pyView on unpkg

Findings

3 Critical5 High6 Medium5 Low
CriticalCredential Exfiltrationdist-bundle/bin/aluy.js
CriticalCommand Output Exfiltrationdist-bundle/bin/aluy.js
CriticalTrigger Reachable Dangerous Capabilitydist-bundle/index.js
HighChild Processdist-bundle/bin/aluy.js
HighSame File Env Network Executiondist-bundle/bin/aluy.js
HighSandbox Evasion Gated Capabilitydist-bundle/bin/aluy.js
HighCloud Metadata Accessdist-bundle/bin/aluy.js
HighCross File Remote Execution Contextdist-bundle/bin/aluy.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist-bundle/bin/aluy.js
MediumProtestware
MediumShips Build Helperassets/mem0/aluy-mem0-server.py
MediumStructural Risk Force Deep Review
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings
LowNo License