registry  /  relay-agent-studio  /  0.1.0-alpha.6

relay-agent-studio@0.1.0-alpha.6

Relay — an AI software studio that runs on your machine. Describe an app; a team of AI agents plans, builds, tests, and fixes it.

AI Security Review

scanned 3h 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.; previous stored version diff introduced dangerous source
Trigger
User runs relay-studio/npx relay-agent-studio, then invokes setup or agent-run actions in the local UI/API.
Impact
Can install global AI CLIs/Ollama, store encrypted provider credentials, send prompts/files to configured providers, and run agent-driven workspace changes subject to app review/guards.
Mechanism
explicit user-command AI agent setup and workspace automation
Rationale
Source inspection supports a warning for dangerous but package-aligned, user-invoked agent automation rather than a publish block. The scanner's exfiltration/secret labels appear explained by normal provider API calls, consent-gated telemetry, and a public Supabase anon key.
Evidence
package.jsonbin/relay-studio.mjselectron/main.cjsserver/routes.mjsserver/cliSetup.mjsserver/localSetup.mjsserver/providers.mjsserver/crypto.mjsserver/telemetry.mjsserver/commands.mjsrelay.app.jsonserver/index.mjsserver/credentials.mjs
Network endpoints10
127.0.0.1:4317127.0.0.1:11434api.openai.com/v1api.anthropic.com/v1/messagesgenerativelanguage.googleapis.com/v1betaopenrouter.ai/api/v1oesjigbitekybqbdcnyg.supabase.coregistry.npmjs.org/relay-agent-studio/latestgithub.com/RelayStudioDev/relay-releases/releases/latest/download/Relay-Setup.exeantigravity.google/cli/install.ps1

Decision evidence

public snapshot
AI called this Suspicious at 82.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • server/cliSetup.mjs can install/run Claude Code, Codex, and Antigravity after /api/cli/setup user request.
  • server/providers.mjs runs CLI agents against the user's workspace, including agy with --dangerously-skip-permissions, then snapshots/restores changes for review.
  • server/localSetup.mjs can install Ollama via winget and pull local models after /api/local-ai/setup user request.
  • server/providers.mjs sends prompts/images to configured AI providers using saved API keys.
Evidence against
  • package.json has no preinstall/install/postinstall hook; only prepublishOnly build script.
  • bin/relay-studio.mjs only starts local server and opens http://127.0.0.1 UI when user runs the bin.
  • CLI/local setup routes in server/routes.mjs are explicit API actions, not install-time or import-time mutations.
  • server/crypto.mjs stores provider keys encrypted under RELAY_HOME data; telemetry code says/counts-only and gates on consent/sign-in.
  • server/commands.mjs uses an allowlist and blocks shell metacharacters/destructive commands for agent-requested shell execution.
  • relay.app.json Supabase anon key is public client config, not a service-role secret.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedUrlStrings
Manifest
NoLicense
scanned 36 file(s), 1.12 MB of source, external domains: 127.0.0.1, antigravity.google, api.anthropic.com, api.deepseek.com, api.groq.com, api.mistral.ai, api.openai.com, api.perplexity.ai, api.together.xyz, api.x.ai, generativelanguage.googleapis.com, github.com, integrate.api.nvidia.com, nodejs.org, ollama.com, openrouter.ai, reactjs.org, registry.npmjs.org, relay.local, www.w3.org, xxxxx.supabase.co, your-api.example

Source & flagged code

9 flagged · loading source
relay.app.jsonView file
4patternName = supabase_service_key severity = critical line = 4 matchedText = "supabas...xM",
Critical
Critical Secret

Package contains a critical-looking secret pattern.

relay.app.jsonView on unpkg · L4
4patternName = supabase_service_key severity = critical line = 4 matchedText = "supabas...xM",
Critical
Secret Pattern

Supabase service role key (JWT) in relay.app.json

relay.app.jsonView on unpkg · L4
server/agentLoop.mjsView file
1344} else { L1345: try { new Function(content); results.push(`JS ${path}: syntax OK`); } L1346: catch (e) { hasError = true; results.push(`JS ${path}: SYNTAX ERROR — ${e.message}`); }
High
Eval

Package source references dynamic code evaluation.

server/agentLoop.mjsView on unpkg · L1344
server/providers.mjsView file
4import { join, basename } from "node:path"; L5: import { spawnSync, spawn } from "node:child_process"; L6: import { loadSecrets, saveSecrets, encryptSecret } from "./crypto.mjs"; ... L43: const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "webp" ? "image/webp" : "image/png"; L44: images.push({ dataUrl: `data:${mime};base64,${buf.toString("base64")}` }); L45: } catch { /* skip unreadable image */ } ... L53: try { L54: const extensionsDir = join(process.env.USERPROFILE || "", ".vscode", "extensions"); L55: if (!extensionsDir || !existsSync(extensionsDir)) return undefined; ... L110: }; L111: const discovered = result.status === 0 ? result.stdout.split(/\r?\n/).find(Boolean)?.trim() : undefined; L112: const path = discovered || knownPaths[command]?.find((candidate) => candidate && existsSync(candidate));
Critical
Credential Exfiltration

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

server/providers.mjsView on unpkg · L4
4Trigger-reachable chain: manifest.bin -> bin/relay-studio.mjs -> server/index.mjs -> server/providers.mjs L4: import { join, basename } from "node:path"; L5: import { spawnSync, spawn } from "node:child_process"; L6: import { loadSecrets, saveSecrets, encryptSecret } from "./crypto.mjs"; ... L43: const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "webp" ? "image/webp" : "image/png"; L44: images.push({ dataUrl: `data:${mime};base64,${buf.toString("base64")}` }); L45: } catch { /* skip unreadable image */ } ... L53: try { L54: const extensionsDir = join(process.env.USERPROFILE || "", ".vscode", "extensions"); L55: if (!extensionsDir || !existsSync(extensionsDir)) return undefined; ... L110: }; L111: const discovered = result.status === 0 ? result.stdout.split(/\r?\n/).find(Boolean)?.trim() : undefined; L112: const path = discovered || knownPaths[command]?.find((candidate) => candidate && existsSync(candidate));
Critical
Trigger Reachable Dangerous Capability

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

server/providers.mjsView on unpkg · L4
4import { join, basename } from "node:path"; L5: import { spawnSync, spawn } from "node:child_process"; L6: import { loadSecrets, saveSecrets, encryptSecret } from "./crypto.mjs"; ... L43: const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "webp" ? "image/webp" : "image/png"; L44: images.push({ dataUrl: `data:${mime};base64,${buf.toString("base64")}` }); L45: } catch { /* skip unreadable image */ } ... L53: try { L54: const extensionsDir = join(process.env.USERPROFILE || "", ".vscode", "extensions"); L55: if (!extensionsDir || !existsSync(extensionsDir)) return undefined; ... L110: }; L111: const discovered = result.status === 0 ? result.stdout.split(/\r?\n/).find(Boolean)?.trim() : undefined; L112: const path = discovered || knownPaths[command]?.find((candidate) => candidate && existsSync(candidate));
Low
Weak Crypto

Package source references weak cryptographic algorithms.

server/providers.mjsView on unpkg · L4
electron/main.cjsView file
matchType = previous_version_dangerous_delta matchedPackage = relay-agent-studio@0.1.0-alpha.3 matchedIdentity = npm:cmVsYXktYWdlbnQtc3R1ZGlv:0.1.0-alpha.3 similarity = 0.588 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.

electron/main.cjsView on unpkg
5Manifest entrypoint (manifest.main) carries capability families absent from dist/build output: environment+network, execution+network L5: // responding", translucent) for seconds at a time. The window is a pure client of L6: // http://127.0.0.1:<port> — same origin the browser and npx flows use, so SSE, the L7: // session token, and the OAuth callback all work as-is. ... L13: L14: const port = Number(process.env.RELAY_PORT || 4317); L15: let relayPort = port; ... L25: // Entry must be CJS (utilityProcess resolves CommonJS); the bootstrap imports the ESM server. L26: serverProc = utilityProcess.fork(join(__dirname, "server-boot.cjs"), [], { L27: stdio: "pipe", ... L30: }); L31: serverProc.stdout?.on("data", (d) => process.stdout.write(d)); L32: serverProc.stderr?.on("data", (d) => process.stderr.write(d));
High
Entrypoint Build Divergence

Manifest entrypoint contains risky behavior absent from dist/build output.

electron/main.cjsView on unpkg · L5
server/localSetup.mjsView file
4// Built for Store-class users: zero accounts, zero API keys, zero instructions. L5: import { spawn, spawnSync } from "node:child_process"; L6: import { existsSync } from "node:fs"; ... L12: L13: const OLLAMA_URL = "http://127.0.0.1:11434"; L14: const CONTEXT_TOKENS = 32768; // every ladder model supports 32k natively ... L34: const r = spawnSync("nvidia-smi", ["--query-gpu=memory.total,name", "--format=csv,noheader,nounits"], { encoding: "utf8", timeout: 8000, windowsHide: true }); L35: for (const line of String(r.stdout || "").trim().split("\n")) { L36: const [mem, ...name] = line.split(","); ... L42: // systems, so treat it as a floor, never as proof of a small GPU. L43: if (!vramMb && process.platform === "win32") { L44: try {
High
Sandbox Evasion Gated Capability

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

server/localSetup.mjsView on unpkg · L4

Findings

5 Critical3 High3 Medium7 Low
CriticalCritical Secretrelay.app.json
CriticalCredential Exfiltrationserver/providers.mjs
CriticalTrigger Reachable Dangerous Capabilityserver/providers.mjs
CriticalPrevious Version Dangerous Deltaelectron/main.cjs
CriticalSecret Patternrelay.app.json
HighEvalserver/agentLoop.mjs
HighEntrypoint Build Divergenceelectron/main.cjs
HighSandbox Evasion Gated Capabilityserver/localSetup.mjs
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowWeak Cryptoserver/providers.mjs
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License