registry  /  paqad-ai  /  1.35.0

paqad-ai@1.35.0

Spec-driven development framework — AI agents that think before they type

AI Security Review

scanned 4h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. Package is an AI agent framework that can install project agent entry files, hooks, MCP configs, skills, and background update hooks after explicit onboarding. The remaining risk is platform extension lifecycle behavior, especially auto-update from a registered agent SessionStart hook, not confirmed malware.

Static reason
One or more suspicious static signals were detected.
Trigger
npm install postinstall for chmod; user-invoked paqad-ai onboard/update for agent integration; later agent session for silent-update hook
Impact
Can modify project .paqad state and agent config files, and can later update the global paqad-ai install when its hook is active.
Mechanism
first-party agent extension setup with background self-update hook
Policy narrative
On install, the lifecycle script only restores execute bits on shipped runtime scripts. When a user runs onboarding/update, paqad-ai writes first-party project governance files and adapter configs for AI tools, including executable hooks and MCP config files. One registered hook can later run a silent background self-update via npm and resync project artifacts. This is agent-extension lifecycle risk, but the source does not show unconsented install-time mutation of foreign agent surfaces, credential exfiltration, or destructive behavior.
Rationale
The package has powerful AI-agent integration and auto-update behavior, but the blockable foreign control-surface writes are user-invoked rather than postinstall-delivered. Treat as warn-only agent extension lifecycle risk rather than malicious.
Evidence
package.jsonruntime/scripts/postinstall.mjsruntime/hooks/silent-update.mjsdist/cli/index.jsdist/index.jsruntime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdruntime/hooksruntime/scripts.paqad/framework-version.txt.paqad/logs/auto-update.log~/.paqad-ai/current.claude/settings.json.codex/hooks.json.claude/settings.mcp.json.codex/mcp.json.paqad/secrets.env
Network endpoints4
api.cohere.com/v1/rerankapi.osv.dev/v1/querybatchnpm view paqad-ai versionnpm install -g paqad-ai@latest

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • package.json defines postinstall: node runtime/scripts/postinstall.mjs
  • runtime/hooks/silent-update.mjs runs npm view and may spawn npm install -g paqad-ai@latest && paqad-ai update --silent
  • dist/cli/index.js generates agent hooks/configs for .claude/settings.json and .codex/hooks.json during onboard/update
  • dist/cli/index.js writes provider MCP configs under .claude/.codex/.cursor/.vscode etc.
  • dist/cli/index.js stores local RAG secrets in .paqad/secrets.env and chmods 0600
Evidence against
  • postinstall only chmods shipped runtime .sh/.mjs files under runtime/hooks and runtime/scripts
  • Agent config and hook registration are exposed through explicit paqad-ai onboard/update CLI flows, not package install
  • No install-time credential harvesting, broad filesystem scan, or exfiltration found
  • Remote AI/RAG calls use user-configured API keys and package-aligned providers
  • Scanner secret hit is a documentation pattern file, not a committed credential
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 37 file(s), 3.98 MB of source, external domains: 127.0.0.1, api.cohere.com, api.osv.dev, in-toto.io, paqad.ai, react.dev, www.w3.org

Source & flagged code

13 flagged · loading source
package.jsonView file
scripts.postinstall = node runtime/scripts/postinstall.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node runtime/scripts/postinstall.mjs
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdView file
13patternName = private_key_ec severity = critical line = 13 matchedText = -----BEG...----
Critical
Critical Secret

Package contains a critical-looking secret pattern.

runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdView on unpkg · L13
11patternName = private_key_rsa severity = critical line = 11 matchedText = -----BEG...----
Critical
Secret Pattern

RSA private key in runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md

runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdView on unpkg · L11
12patternName = private_key_rsa severity = critical line = 12 matchedText = -----BEG...----
Critical
Secret Pattern

RSA private key in runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md

runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdView on unpkg · L12
13patternName = private_key_ec severity = critical line = 13 matchedText = -----BEG...----
Critical
Secret Pattern

EC private key in runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md

runtime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.mdView on unpkg · L13
dist/rule-scripts/index.jsView file
503// src/rule-scripts/execute.ts L504: import { spawnSync } from "child_process"; L505: import { accessSync, constants, statSync } from "fs";
High
Child Process

Package source references child process execution.

dist/rule-scripts/index.jsView on unpkg · L503
1366import { join as join9 } from "path"; L1367: import { execa } from "execa"; L1368: async function loadChangeEvidence(projectRoot) {
High
Shell

Package source references shell execution.

dist/rule-scripts/index.jsView on unpkg · L1366
runtime/graph-ui/assets/index-B7e9pFJw.jsView file
218`;v(ke),Q(pt=>pt+1),le.file.exists&&!le.placeholder&&m(!0)}).catch(le=>n(le instanceof Error?le.message:String(le))),Pi().then(le=>{s(le.projectName),c(le.frameworkVersion)}).catch... L219: `),Q(Fe=>Fe+1),te()},se=_.useCallback(le=>{P||!p||(R(!0),W(null),G(null),ee(null),oR({content:O,baseHash:le!==void 0?le:x}).then(ke=>{if(ke.status==="ok"){S(ke.result.hash),e(Fe=>F... L220: In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Wl(i,e){return DB(i)||zB(i,e)||ZA(i,e)||XB()}var uO={black:"#000000",silver:"#C0C0C0",...
Medium
Dynamic Require

Package source references dynamic require/import behavior.

runtime/graph-ui/assets/index-B7e9pFJw.jsView on unpkg · L218
dist/index.jsView file
523} L524: function layeredConfigMap(projectRoot, env = process.env) { L525: const merged = /* @__PURE__ */ new Map(); ... L1944: try { L1945: const parsed = JSON.parse(trimmed); L1946: if (typeof parsed === "object" && parsed !== null && (parsed.type === "sk[redacted]" || parsed.type === "sk[redacted]")) { ... L2910: }, L2911: frozenMetadata: { L2912: type: "object", ... L4026: default_command: { type: "string" }, L4027: output_source: { type: "string", enum: ["stdout", "file"] }, L4028: output_path_pattern: { type: "string" }
High
Cloud Metadata Access

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

dist/index.jsView on unpkg · L523
523} L524: function layeredConfigMap(projectRoot, env = process.env) { L525: const merged = /* @__PURE__ */ new Map(); ... L1944: try { L1945: const parsed = JSON.parse(trimmed); L1946: if (typeof parsed === "object" && parsed !== null && (parsed.type === "sk[redacted]" || parsed.type === "sk[redacted]")) { ... L2910: }, L2911: frozenMetadata: { L2912: type: "object", ... L4026: default_command: { type: "string" }, L4027: output_source: { type: "string", enum: ["stdout", "file"] }, L4028: output_path_pattern: { type: "string" }
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/index.jsView on unpkg · L523
runtime/hooks/silent-update.mjsView file
347const out = openSync(logPath, 'a'); L348: const child = spawn('npm install -g paqad-ai@latest && paqad-ai update --silent', { L349: shell: true,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

runtime/hooks/silent-update.mjsView on unpkg · L347
runtime/capabilities/security/skills/auth-mechanism-review/scripts/scan-auth-smells.shView file
path = [redacted]-mechanism-review/scripts/scan-auth-smells.sh kind = build_helper sizeBytes = 1583 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

runtime/capabilities/security/skills/auth-mechanism-review/scripts/scan-auth-smells.shView on unpkg

Findings

4 Critical5 High6 Medium6 Low
CriticalCritical Secretruntime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md
CriticalSecret Patternruntime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md
CriticalSecret Patternruntime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md
CriticalSecret Patternruntime/capabilities/security/skills/cryptographic-review/references/crypto-weakness-patterns.md
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/rule-scripts/index.js
HighShelldist/rule-scripts/index.js
HighCloud Metadata Accessdist/index.js
HighRuntime Package Installruntime/hooks/silent-update.mjs
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requireruntime/graph-ui/assets/index-B7e9pFJw.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperruntime/capabilities/security/skills/auth-mechanism-review/scripts/scan-auth-smells.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptodist/index.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings