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

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

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 8d ago · by lpm-firewall-ai

No confirmed malicious attack surface is established. The package is a local AI-agent CLI with intentional, user-invoked shell/file/network capabilities guarded by permission logic.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs aluy or explicit subcommands such as onboard, login, bootstrap, mcp, or agent tasks.
Impact
Expected ability to edit project files, run approved commands, call configured LLM/provider services, and manage local ~/.aluy state.
Mechanism
User-invoked AI agent tool execution with permission gating and BYO provider networking.
Rationale
Static inspection shows a high-capability AI terminal agent, but the risky primitives are documented, user-invoked, package-aligned, and guarded by permission/sensitive-path checks. I found no lifecycle execution, hidden exfiltration, metadata credential theft, or unconsented AI-agent control-surface mutation.
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/memory~/.mem0/history.db.aluy/
Network endpoints12
api.aluy.app/api/v1broker.dev.aluy.exampleapi.openai.com/v1api.anthropic.comopenrouter.ai/api/v1auth.openai.com/oauth/authorizeauth.openai.com/oauth/tokenclaude.ai/oauth/authorizeconsole.anthropic.com/v1/oauth/tokenduckduckgo.comhtml.duckduckgo.com/html/127.0.0.1:11434

Decision evidence

public snapshot
AI called this Clean at 88.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • dist-bundle/bin/aluy.js includes user-facing agent tools for shell execution, file writes, MCP, web fetch/search, and sidecars.
  • dist-bundle/bin/aluy.js can store tokens/API keys in OS keyring and read ALUY_* provider env vars.
  • assets/mem0/aluy-mem0-server.py may rename/remove local memory stores during explicit mem0 sidecar startup.
Evidence against
  • package.json has no lifecycle scripts; main/bin point only to bundled CLI entrypoints.
  • README.md describes an interactive local AI agent that reads/edits files, runs commands, and uses BYO LLM providers.
  • dist-bundle/bin/aluy.js permission code gates destructive, network, package-exec, escalation, outside-workspace, and sensitive-read actions.
  • Network endpoints are package-aligned: LLM providers, Aluy API/broker, OAuth, MCP registry/search, local loopback sidecars, and Ollama bootstrap.
  • Credential handling uses @napi-rs/keyring/keychain paths and warns against plaintext secret storage.
  • No install-time/import-time exfiltration, cloud metadata access, persistence implant, or hardcoded attacker endpoint confirmed.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNativeBindingsNetwork
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareUrlStrings
Manifest
NoLicense
scanned 2 file(s), 1.90 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

9 flagged · loading source
dist-bundle/bin/aluy.jsView file
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 BW,UW,iR,jW,aR,Kf,cR=p(()=>{"use strict";Pr();zf();Dk();BW=8;UW=Object.freeze({type:"object",properties:{url:{type:"string",description:"OBRIGAT\xD3RIO. A URL http(s) a busc... L131: ... L135: ${t.trim()}`}}function bR(t,e,o=pu){let{older:n,recent:r}=Jf(t,o);if(n.length===0)return{history:t,stats:{turnsBefore:t.length,turnsAfter:t.length,summarizedTurns:0}};let s=[yR(e,n... L136: `),pu=4,Vf=1500,Xf=.4,Yf=48e3;Ai=class extends Error{constructor(){super("hist\xF3rico curto demais \u2014 nada a compactar."),this.name="NothingToCompactError"}},fu=class{model;ke... L137: `;case"t":return" ";case"r":return"\r";case'"':return'"';case"\\":return"\\";default:throw new ye(`config.toml:${e}: escape n\xE3o suportado "\\${i}".`)}})}function l6(t,e,o){let n... ... L141: `)}function _6(t,e){return t.length<=e?t:t.slice(0,e-1).trimEnd()+"\u2026"}var cO=p(()=>{"use strict"});var uO=p(()=>{"use strict";dp();WR();GR();zR();KR();VR();ZR();Mm();sO();cO()... L142: `,r;try{r=Y6(o,Sx.O_CREAT|Sx.O_EXCL|Sx.
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 NT(t,e,o){if(o===void 0)return e;let n=$v(t.model);return n===void 0?e:o(n)}var RT,OT,MT,bi,qv,LT,PT,qq,Wv,qc,Gv=p(()=>{"use strict";hv();Bv();Uv();ii();Iv();Ff(... L90:
High
Child Process

Package source references child process execution.

dist-bundle/bin/aluy.jsView on unpkg · L88
135${t.trim()}`}}function bR(t,e,o=pu){let{older:n,recent:r}=Jf(t,o);if(n.length===0)return{history:t,stats:{turnsBefore:t.length,turnsAfter:t.length,summarizedTurns:0}};let s=[yR(e,n... L136: `),pu=4,Vf=1500,Xf=.4,Yf=48e3;Ai=class extends Error{constructor(){super("hist\xF3rico curto demais \u2014 nada a compactar."),this.name="NothingToCompactError"}},fu=class{model;ke... L137: `;case"t":return" ";case"r":return"\r";case'"':return'"';case"\\":return"\\";default:throw new ye(`config.toml:${e}: escape n\xE3o suportado "\\${i}".`)}})}function l6(t,e,o){let n... ... L141: `)}function _6(t,e){return t.length<=e?t:t.slice(0,e-1).trimEnd()+"\u2026"}var cO=p(()=>{"use strict"});var uO=p(()=>{"use strict";dp();WR();GR();zR();KR();VR();ZR();Mm();sO();cO()... L142: `,r;try{r=Y6(o,Sx.O_CREAT|Sx.O_EXCL|Sx.O_WRONLY,tG),V6(r,n),PO(r),r=void 0,Q6(o,this.file)}catch(s){if(r!==void 0)try{PO(r)}catch{}try{Z6(o)}catch{}throw s}}}});function Cx(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 z8,K8,Cy=p(()=>{"use strict";z8="<<<FIM_DADO>>>",K8="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as Y8}from"node:crypto";function Ty(t,e){let o=[...t,e];return o.length>Dy?o... L13: ... L23: L24: `)+q}}}]}var ds,Ny,DC,jm=p(()=>{"use strict";Oy();Ql();Iy();ds="room_post",Ny="room_read",DC=["ask","inform","result","ack"]});function Hm(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 Zm=p(()=>{"use strict"});function g0(t=globalThis.process?.env??{}){let e=d0(t[f0]),o=d0(t[p0]);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 z8,K8,Cy=p(()=>{"use strict";z8="<<<FIM_DADO>>>",K8="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as Y8}from"node:crypto";function Ty(t,e){let o=[...t,e];return o.length>Dy?o... L13: ... L23: L24: `)+q}}}]}var ds,Ny,DC,jm=p(()=>{"use strict";Oy();Ql();Iy();ds="room_post",Ny="room_read",DC=["ask","inform","result","ack"]});function Hm(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 Zm=p(()=>{"use strict"});function g0(t=globalThis.process?.env??{}){let e=d0(t[f0]),o=d0(t[p0]);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 z8,K8,Cy=p(()=>{"use strict";z8="<<<FIM_DADO>>>",K8="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as Y8}from"node:crypto";function Ty(t,e){let o=[...t,e];return o.length>Dy?o... L13: ... L23: L24: `)+q}}}]}var ds,Ny,DC,jm=p(()=>{"use strict";Oy();Ql();Iy();ds="room_post",Ny="room_read",DC=["ask","inform","result","ack"]});function Hm(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 z8,K8,Cy=p(()=>{"use strict";z8="<<<FIM_DADO>>>",K8="DADO_NAO_CONFIAVEL>>>"});import{randomBytes as Y8}from"node:crypto";function Ty(t,e){let o=[...t,e];return o.length>Dy?o... L13: ... L23: L24: `)+q}}}]}var ds,Ny,DC,jm=p(()=>{"use strict";Oy();Ql();Iy();ds="room_post",Ny="room_read",DC=["ask","inform","result","ack"]});function Hm(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 Zm=p(()=>{"use strict"});function g0(t=globalThis.process?.env??{}){let e=d0(t[f0]),o=d0(t[p0]);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
426Trigger-reachable chain: manifest.main -> dist-bundle/index.js L426: - Credencial S\xD3 no keychain do SO \u2014 nunca em texto em claro. L427: - Loop de agente + ferramentas nativas + controle de permiss\xE3o integrados.`;function Ve(t,e,o={}){let n=`--${e}=`;for(let r=0;r<t.length;r++){let s=t[r];if(s===`--${e}`){let i=t... L428: \u2026[truncado: corpo maior que ${e.maxBytes} bytes]`),f({status:O,body:Y,...j?{contentType:j}:{}})}),D.on("close",()=>{if(c)return;let Y=Buffer.concat(P).toString("utf8")+(W?` ... L430: \u2026[truncado: corpo maior que ${e.maxBytes} bytes]`;f({status:O,body:ne,...j?{contentType:j}:{}});return}d(Y)})}),E=()=>{g.destroy(),d(new Error("cancelado"))},w=setTimeout(()=>... L431: ${Zo(E)}`}}catch(h){let y=u?`o proxy n\xE3o respondeu em ${f}ms (timeout)`:h instanceof Error?h.message:String(h);return{ok:!1,display:l,observation:`headroom_retrieve: falha ao fa... L432: [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 Yi(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 · L426
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

2 Critical5 High6 Medium5 Low
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