AI Security Review
scanned 22h ago · by lpm-firewall-aiNo confirmed malicious attack surface was found. The package is an Agent Gateway CLI that can explicitly wire a project to Bitagent Gateway and store local target/session configuration.
Static reason
One or more suspicious static signals were detected.
Trigger
User runs agw commands such as agw init, login, target, key, or completion.
Impact
Explicit commands may write project Claude settings and AGW config or call configured gateway APIs; no install-time persistence, credential harvesting, or hidden agent control hijack was found.
Mechanism
user-invoked gateway CLI configuration and API client
Rationale
Static inspection shows a documented CLI for configuring Bitagent Gateway, including explicit Claude project wiring, but no lifecycle execution or unconsented mutation of foreign agent surfaces. The scanner hits map to package-aligned network/config/token handling and user-facing completion text rather than malicious behavior.
Evidence
package.jsondist/main.jsREADME.md~/.agw/config.json~/.agw/auth-token~/.agw/sessions/*~/.agw/caps/*.json~/.claude-gateway/config.json.claude/settings.local.json.agw.json
Network endpoints3
gateway.bitagent.devcompat.bitagent.devregistry.npmjs.org/-/package/bitspark-agw/dist-tags
Decision evidence
public snapshotAI called this Clean at 90.0% confidence as Benign with low false-positive risk.
Evidence for block
Evidence against
- package.json has no npm lifecycle hooks; only bin agw -> dist/main.js.
- dist/main.js runs as a CLI entrypoint and dispatches commands from process.argv, not install-time code.
- agw init writes .claude/settings.local.json and .agw.json only after explicit CLI invocation, with documented dry-run support.
- Network calls are package-aligned gateway/admin APIs plus npm dist-tag latest check.
- Credential reads/writes are local AGW config/session/project credentials, not broad harvesting or exfiltration.
- Shell profile references are printed completion instructions, not automatic profile mutation.
Behavioral surface
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
HighEntropyStringsUrlStrings
NoLicense
Source & flagged code
2 flagged · loading sourcedist/main.jsView file
22142patternName = generic_password
severity = medium
line = 22142
matchedText = if (!fro...t) {
Medium
70const here = dirname(fileURLToPath(import.meta.url));
L71: return JSON.parse(readFileSync(join(here, "..", "..", "package.json"), "utf-8")).version ?? "0.0.0";
L72: } catch {
...
L386: function defaultTarget(host, port) {
L387: return { adminUrl: `http://${host}:${port}`, compatUrl: `http://${host}:${port - 1}` };
L388: }
...
L457: ensureLegacyMigration();
L458: const hostOverride = strFlag(args.flags["host"]) ?? process.env["AGW_HOST"];
L459: const portOverride = strFlag(args.flags["port"]) ?? process.env["AGW_PORT"];
...
L470: flagTarget: strFlag(args.flags["target"]),
L471: cwd: process.cwd(),
L472: defaultHost: host,
Medium
Install Persistence
Source writes installer persistence such as shell profile or service configuration.
dist/main.jsView on unpkg · L70Findings
4 Medium5 Low
MediumSecret Patterndist/main.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/main.js
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License