AI Security Review
scanned 2h ago · by lpm-firewall-aiNo confirmed malicious attack surface is established. The package is a Linear-to-USRCP capture adapter; risky primitives are limited to install-time native dependency rebuild and user/runtime Linear polling.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install postinstall; user runs usrcp-linear or usrcp-linear --reset-config
Impact
captures configured user's allowlisted Linear issues/comments into local USRCP ledger
Mechanism
package-aligned Linear polling and local ledger append
Rationale
Static source inspection shows package-aligned behavior: Linear API setup/polling, local encrypted config, and ledger writes. The lifecycle hook is unusual but scoped to rebuilding better-sqlite3 and does not plant persistence or mutate AI-agent control surfaces.
Evidence
package.jsondist/index.jsdist/setup.jsdist/config.jsdist/capture.jsREADME.mdnode_modules/better-sqlite3/buildnode_modules/usrcp-core/node_modules/better-sqlite3/buildnode_modules/usrcp-stream/node_modules/better-sqlite3/build~/.usrcp/linear-config.json
Network endpoints1
linear.app/settings/api
Decision evidence
public snapshotAI called this Clean at 91.0% confidence as Benign with low false-positive risk.
Evidence for block
- package.json has a postinstall hook that removes better-sqlite3 build dirs and runs npm rebuild
- dist/index.js imports node:child_process but only uses execSync for explicit --reset-config
- dist/index.js reads USRCP_PASSPHRASE and polls Linear via @linear/sdk
Evidence against
- postinstall is limited to better-sqlite3 native rebuild paths, not agent/control-surface mutation
- Runtime network use is package-aligned Linear API polling with configured API key and team allowlist
- dist/setup.js is user-invoked interactive setup that validates and stores Linear config
- No evidence of credential exfiltration, remote code loading, persistence, destructive broad file access, or AI-agent hijack
Behavioral surface
ChildProcessEnvironmentVars
UrlStrings
Source & flagged code
2 flagged · loading sourcepackage.jsonView file
•scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
Critical
Red Install Lifecycle Script
Install-time lifecycle script matches a deterministic static-gate block pattern.
package.jsonView on unpkg•scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
High
Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.jsonView on unpkgFindings
1 Critical1 High1 Medium2 Low
CriticalRed Install Lifecycle Scriptpackage.json
HighInstall Time Lifecycle Scriptspackage.json
MediumEnvironment Vars
LowScripts Present
LowUrl Strings