opmsec 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.env.example +1 -0
  2. package/README.md +71 -275
  3. package/bun.lock +3 -3
  4. package/docs/architecture/agents.mdx +11 -59
  5. package/docs/architecture/benchmarks.mdx +20 -46
  6. package/docs/architecture/overview.mdx +31 -38
  7. package/docs/architecture/scanner.mdx +11 -37
  8. package/docs/cli/audit.mdx +9 -12
  9. package/docs/cli/check.mdx +12 -26
  10. package/docs/cli/fix.mdx +10 -30
  11. package/docs/cli/info.mdx +12 -19
  12. package/docs/cli/install.mdx +27 -39
  13. package/docs/cli/push.mdx +40 -57
  14. package/docs/cli/register-agent.mdx +21 -53
  15. package/docs/cli/view.mdx +12 -29
  16. package/docs/concepts/ens-records.mdx +44 -0
  17. package/docs/concepts/multi-agent-consensus.mdx +18 -36
  18. package/docs/concepts/on-chain-registry.mdx +22 -49
  19. package/docs/concepts/security-model.mdx +20 -52
  20. package/docs/concepts/zk-agent-verification.mdx +26 -64
  21. package/docs/contract/events.mdx +13 -74
  22. package/docs/contract/functions.mdx +40 -126
  23. package/docs/contract/overview.mdx +17 -36
  24. package/docs/introduction.mdx +22 -25
  25. package/docs/mint.json +1 -0
  26. package/docs/quickstart.mdx +34 -70
  27. package/docs/system-design.png +0 -0
  28. package/package.json +5 -5
  29. package/packages/cli/src/commands/author-view.tsx +87 -2
  30. package/packages/cli/src/commands/check.tsx +18 -5
  31. package/packages/cli/src/commands/fix.tsx +25 -12
  32. package/packages/cli/src/commands/info.tsx +92 -4
  33. package/packages/cli/src/commands/install.tsx +54 -8
  34. package/packages/cli/src/commands/push.tsx +112 -0
  35. package/packages/cli/src/commands/register-agent.tsx +72 -31
  36. package/packages/cli/src/index.tsx +4 -4
  37. package/packages/cli/src/services/ens-records.ts +525 -0
  38. package/packages/core/src/benchmarks.ts +116 -0
  39. package/packages/core/src/constants.ts +18 -6
  40. package/packages/core/src/model-rankings.ts +40 -15
  41. package/packages/core/src/types.ts +10 -0
  42. package/packages/core/src/utils.ts +3 -3
  43. package/packages/scanner/src/index.ts +2 -1
  44. package/packages/scanner/src/queue/memory-queue.ts +7 -2
  45. package/packages/scanner/src/services/benchmark-runner.ts +86 -1
  46. package/packages/scanner/src/services/fileverse.ts +61 -12
  47. package/packages/web/.next/BUILD_ID +1 -1
  48. package/packages/web/.next/app-build-manifest.json +7 -18
  49. package/packages/web/.next/build-manifest.json +6 -19
  50. package/packages/web/.next/images-manifest.json +1 -1
  51. package/packages/web/.next/required-server-files.json +2 -2
  52. package/packages/web/.next/server/app/_not-found/page.js +2 -2
  53. package/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  54. package/packages/web/.next/server/app/_not-found.html +1 -1
  55. package/packages/web/.next/server/app/_not-found.rsc +4 -2
  56. package/packages/web/.next/server/app/index.html +6 -1
  57. package/packages/web/.next/server/app/index.rsc +5 -3
  58. package/packages/web/.next/server/app/page.js +272 -2
  59. package/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
  60. package/packages/web/.next/server/app-paths-manifest.json +0 -1
  61. package/packages/web/.next/server/middleware-build-manifest.js +22 -1
  62. package/packages/web/.next/server/middleware-react-loadable-manifest.js +1 -1
  63. package/packages/web/.next/server/next-font-manifest.js +1 -1
  64. package/packages/web/.next/server/next-font-manifest.json +1 -1
  65. package/packages/web/.next/server/pages/404.html +1 -1
  66. package/packages/web/.next/server/pages/500.html +1 -1
  67. package/packages/web/.next/server/pages-manifest.json +1 -6
  68. package/packages/web/.next/server/server-reference-manifest.js +1 -1
  69. package/packages/web/.next/server/server-reference-manifest.json +5 -1
  70. package/packages/web/.next/server/webpack-runtime.js +209 -1
  71. package/packages/web/.next/static/chunks/174-5b5efcb3b8efcc01.js +1 -0
  72. package/packages/web/.next/static/chunks/app/layout-de8e841104500505.js +1 -0
  73. package/packages/web/.next/static/chunks/app/layout.js +69 -0
  74. package/packages/web/.next/static/chunks/app/page-7e086379698b9fb0.js +1 -0
  75. package/packages/web/.next/static/chunks/app/page.js +357 -0
  76. package/packages/web/.next/static/chunks/{main-ee293fa6aa18bdd1.js → main-4e8d71b5ef7ee7e3.js} +1 -1
  77. package/packages/web/.next/static/chunks/webpack-0dcd67569eb46132.js +1 -0
  78. package/packages/web/.next/static/chunks/webpack.js +1393 -0
  79. package/packages/web/.next/static/css/102562cf2d0ae9b0.css +3 -0
  80. package/packages/web/.next/static/development/_buildManifest.js +1 -0
  81. package/packages/web/.next/static/development/_ssgManifest.js +1 -0
  82. package/packages/web/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  83. package/packages/web/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  84. package/packages/web/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  85. package/packages/web/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  86. package/packages/web/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  87. package/packages/web/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  88. package/packages/web/.next/static/webpack/16f18baa938a434c.webpack.hot-update.json +1 -0
  89. package/packages/web/.next/static/webpack/5fe9fe8578f9c3d2.webpack.hot-update.json +1 -0
  90. package/packages/web/.next/static/webpack/653e365406c0d9ac.webpack.hot-update.json +1 -0
  91. package/packages/web/.next/static/webpack/6800169a899e3a8b.webpack.hot-update.json +1 -0
  92. package/packages/web/.next/static/webpack/73c7d02260cc80e4.webpack.hot-update.json +1 -0
  93. package/packages/web/.next/static/webpack/a2d85d19aa028de1.webpack.hot-update.json +1 -0
  94. package/packages/web/.next/static/webpack/app/layout.16f18baa938a434c.hot-update.js +22 -0
  95. package/packages/web/.next/static/webpack/app/layout.5fe9fe8578f9c3d2.hot-update.js +22 -0
  96. package/packages/web/.next/static/webpack/app/layout.653e365406c0d9ac.hot-update.js +22 -0
  97. package/packages/web/.next/static/webpack/app/layout.6800169a899e3a8b.hot-update.js +22 -0
  98. package/packages/web/.next/static/webpack/app/layout.73c7d02260cc80e4.hot-update.js +22 -0
  99. package/packages/web/.next/static/webpack/app/layout.a2d85d19aa028de1.hot-update.js +22 -0
  100. package/packages/web/.next/static/webpack/app/page.653e365406c0d9ac.hot-update.js +22 -0
  101. package/packages/web/.next/static/webpack/app/page.6800169a899e3a8b.hot-update.js +22 -0
  102. package/packages/web/.next/static/webpack/app/page.73c7d02260cc80e4.hot-update.js +22 -0
  103. package/packages/web/.next/static/webpack/app/page.a2d85d19aa028de1.hot-update.js +22 -0
  104. package/packages/web/.next/static/webpack/webpack.16f18baa938a434c.hot-update.js +12 -0
  105. package/packages/web/.next/static/webpack/webpack.5fe9fe8578f9c3d2.hot-update.js +12 -0
  106. package/packages/web/.next/static/webpack/webpack.653e365406c0d9ac.hot-update.js +12 -0
  107. package/packages/web/.next/static/webpack/webpack.6800169a899e3a8b.hot-update.js +12 -0
  108. package/packages/web/.next/static/webpack/webpack.73c7d02260cc80e4.hot-update.js +12 -0
  109. package/packages/web/.next/static/webpack/webpack.a2d85d19aa028de1.hot-update.js +12 -0
  110. package/packages/web/.next/trace +2 -2
  111. package/packages/web/app/globals.css +197 -51
  112. package/packages/web/app/layout.tsx +6 -3
  113. package/packages/web/app/page.tsx +791 -312
  114. package/packages/web/bun.lock +66 -105
  115. package/packages/web/next.config.ts +8 -1
  116. package/packages/web/package.json +5 -2
  117. package/packages/web/postcss.config.mjs +2 -2
  118. package/packages/web/public/apple-icon.png +1 -0
  119. package/packages/web/public/dependency-bottleneck.png +0 -0
  120. package/packages/web/public/icon-dark-32x32.png +1 -0
  121. package/packages/web/public/icon-light-32x32.png +1 -0
  122. package/packages/web/public/icon.svg +1 -0
  123. package/packages/web/public/nextjs-cve-announcement.png +0 -0
  124. package/packages/web/public/phantomraven-npm-attack.png +0 -0
  125. package/packages/web/public/placeholder-logo.png +1 -0
  126. package/packages/web/public/placeholder-logo.svg +1 -0
  127. package/packages/web/public/placeholder-user.jpg +1 -0
  128. package/packages/web/public/placeholder.jpg +1 -0
  129. package/packages/web/public/placeholder.svg +1 -0
  130. package/packages/web/public/react-cve-meme.png +0 -0
  131. package/packages/web/public/wallet-drain-exploit.png +0 -0
  132. package/packages/web/styles/globals.css +125 -0
  133. package/packages/web/.next/static/chunks/app/layout-28a489fb4398663f.js +0 -1
  134. package/packages/web/.next/static/chunks/app/page-e58ccdb78625bce6.js +0 -1
  135. package/packages/web/.next/static/chunks/webpack-e1ae44446e7f7355.js +0 -1
  136. package/packages/web/.next/static/css/21d69157e271f2ab.css +0 -3
  137. package/packages/web/tailwind.config.ts +0 -48
  138. /package/packages/web/.next/static/{2XIFCTTKVZwN_RsNE-Rrr → 0esGzFBCzREfVwijEGDfL}/_buildManifest.js +0 -0
  139. /package/packages/web/.next/static/{2XIFCTTKVZwN_RsNE-Rrr → 0esGzFBCzREfVwijEGDfL}/_ssgManifest.js +0 -0
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: 'opm register-agent'
3
- description: 'Register a new security agent with ZK-verified benchmarks.'
3
+ description: 'Register a new AI security agent with ZK-verified benchmarks.'
4
4
  ---
5
5
 
6
6
  # opm register-agent
7
7
 
8
- Register a new security agent with ZK-verified benchmarks. Agents must pass 10 benchmark cases with 100% accuracy and produce a valid ZK proof before they can submit scores on-chain.
8
+ Register your own security agent. Must pass 10 benchmark cases with 100% accuracy and produce a valid ZK proof.
9
9
 
10
10
  ## Usage
11
11
 
@@ -15,66 +15,34 @@ opm register-agent --name <name> --model <model> [--system-prompt <prompt>]
15
15
 
16
16
  | Flag | Required | Description |
17
17
  |------|----------|-------------|
18
- | <code>--name</code> | Yes | Agent identifier (e.g. <code>my-security-agent</code>) |
19
- | <code>--model</code> | Yes | LLM model (e.g. <code>anthropic/claude-sonnet-4-20250514</code>) |
20
- | <code>--system-prompt</code> | No | Custom system prompt (defaults to OPM security auditor prompt) |
18
+ | `--name` | Yes | Agent identifier |
19
+ | `--model` | Yes | LLM model (e.g. `anthropic/claude-sonnet-4-20250514`) |
20
+ | `--system-prompt` | No | Custom system prompt (defaults to OPM security auditor) |
21
+
22
+ ## Process
23
+
24
+ 1. **Validate** — Checks agent name, model, env vars
25
+ 2. **Benchmark** — Sends 10 labeled cases in a single LLM call (3 clean, 7 malicious)
26
+ 3. **ZK proof** — Generates proof of 100% accuracy without revealing test data
27
+ 4. **Register** — Calls `OPMRegistry.registerAgent()` with name, model, system prompt hash, proof hash
21
28
 
22
29
  ## Required Environment Variables
23
30
 
24
31
  | Variable | Purpose |
25
32
  |----------|---------|
26
- | <code>AGENT_PRIVATE_KEY</code> | Wallet that becomes the agent identity; must hold Base Sepolia ETH for gas |
27
- | <code>OPENROUTER_API_KEY</code> or <code>OPENAI_API_KEY</code> | Required to run benchmark LLM calls |
28
-
29
- ## Process
33
+ | `AGENT_PRIVATE_KEY` | Wallet that becomes the agent identity (needs Base Sepolia ETH) |
34
+ | `OPENROUTER_API_KEY` or `OPENAI_API_KEY` | LLM access for benchmark calls |
30
35
 
31
- <Steps>
32
- <Step title="Validate configuration">
33
- Checks agent name, model, and required env vars.
34
- </Step>
35
- <Step title="Run benchmark suite">
36
- Executes 10 labeled test cases across categories: clean, typosquat, malicious, cve, obfuscated, exfiltration, dependency_confusion.
37
- </Step>
38
- <Step title="Generate ZK proof">
39
- Produces a zero-knowledge proof that the agent achieved 100% accuracy without revealing test data or expected outputs.
40
- </Step>
41
- <Step title="Register on-chain">
42
- Calls <code>OPMRegistry.registerAgent()</code> with name, model, system prompt hash, and proof hash.
43
- </Step>
44
- </Steps>
36
+ ## On Success
45
37
 
46
- ## Benchmark Categories
38
+ - BaseScan transaction link shown
39
+ - Agent authorized to submit scores
40
+ - Participates in all future package scans
47
41
 
48
- | Category | Count | Description |
49
- |----------|-------|-------------|
50
- | clean | 3 | Legitimate packages (string utils, math, validator) |
51
- | typosquat | 1 | Typosquat with credential exfiltration |
52
- | malicious | 2 | Postinstall shell, SSH key exfiltration |
53
- | cve | 1 | Known prototype pollution CVE |
54
- | obfuscated | 1 | Obfuscated reverse shell |
55
- | exfiltration | 1 | Env var exfiltration on import |
56
- | dependency_confusion | 1 | Internal scope shadowing + exfiltration |
42
+ ## On Failure
57
43
 
58
- ## Requirements
44
+ Shows which cases were misclassified, expected vs actual verdict, and rejection reason.
59
45
 
60
46
  <Warning>
61
- **100% accuracy** is required. The agent must pass all 10 benchmark cases. Each case is evaluated by score range and risk level ordinal.
47
+ **100% accuracy required.** No partial passes. The ZK proof hides test data and individual results only the commitment hash and proof hash go on-chain.
62
48
  </Warning>
63
-
64
- <Note>
65
- The ZK proof hides test data and individual results. Only the commitment hash and proof hash are stored on-chain.
66
- </Note>
67
-
68
- ## Success
69
-
70
- On success:
71
- - Etherscan transaction link is shown
72
- - Agent is authorized to submit scores
73
- - Agent participates in the next package scan alongside existing agents
74
-
75
- ## Failure
76
-
77
- On failure, the CLI shows:
78
- - Which benchmark cases failed and why
79
- - Expected vs actual risk level and score
80
- - Rejection reason (e.g. "Agent achieved 90% accuracy (100% required)")
package/docs/cli/view.mdx CHANGED
@@ -1,52 +1,35 @@
1
1
  ---
2
2
  title: 'opm view / opm whois'
3
- description: 'Author profile and published packages.'
3
+ description: 'Author profile, reputation, and published packages.'
4
4
  ---
5
5
 
6
6
  # opm view / opm whois
7
7
 
8
- Show author profile and published packages. Resolves ENS identity and displays on-chain reputation.
8
+ Look up an author's ENS profile, OPM reputation, and published packages.
9
9
 
10
10
  ## Usage
11
11
 
12
12
  <CodeGroup>
13
13
 
14
- ```bash View by ENS name
15
- opm view vitalik.eth
14
+ ```bash By ENS name
15
+ opm view djpai.eth
16
16
  ```
17
17
 
18
18
  ```bash Whois (auto-appends .eth)
19
- opm whois vitalik
19
+ opm whois djpai
20
20
  ```
21
21
 
22
22
  </CodeGroup>
23
23
 
24
24
  <Note>
25
- <code>opm view &lt;name.eth&gt;</code> shows author profile. <code>opm view &lt;pkg&gt;</code> (without <code>.eth</code>) delegates to <code>opm info</code>.
25
+ `opm view <name.eth>` shows author profile. `opm view <pkg>` (without `.eth`) delegates to `opm info`.
26
26
  </Note>
27
27
 
28
- ## Output
28
+ ## What It Shows
29
29
 
30
- ### Identity
30
+ - **Identity** — ENS name, wallet address, bio, URL, GitHub, Twitter, email, avatar
31
+ - **Author stats** — Packages published, average reputation score
32
+ - **OPM ENS records** — `opm.version`, `opm.fileverse`, `opm.risk_score`, `opm.packages`, contenthash
33
+ - **Published packages** — Name, version, risk score, checksum, signature status, report link
31
34
 
32
- - **ENS name** Resolved identity
33
- - **Address** — Wallet address
34
- - **Bio** — ENS description text record
35
- - **URL** — ENS url record
36
- - **GitHub** — <code>com.github</code> text record
37
- - **Twitter** — <code>com.twitter</code> text record
38
- - **Email** — ENS email record
39
- - **Avatar** — Rendered from ENS avatar record
40
-
41
- ### Author Stats
42
-
43
- - **Packages published** — Count from OPMRegistry
44
- - **Avg reputation** — Risk badge (lower = better)
45
-
46
- ### Published Packages
47
-
48
- For each package: name, version, risk score, checksum, signature status, and report URI link.
49
-
50
- <Note>
51
- No environment variables are required. ENS resolution uses public resolvers.
52
- </Note>
35
+ No environment variables required. Uses public ENS resolvers.
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: 'ENS Text Records'
3
+ description: 'Package metadata stored on ENS for decentralized discovery.'
4
+ ---
5
+
6
+ # ENS Text Records
7
+
8
+ When you publish via `opm push`, package metadata is written to your ENS name as text records — creating a decentralized discovery layer independent of the smart contract.
9
+
10
+ ## Record Keys
11
+
12
+ ### Author-Level (on `djpai.eth`)
13
+
14
+ | Key | Example |
15
+ |-----|---------|
16
+ | `opm.version` | `1.2.3` |
17
+ | `opm.checksum` | `0x8a3f...` |
18
+ | `opm.fileverse` | Fileverse report URI |
19
+ | `opm.risk_score` | `12` |
20
+ | `opm.signature` | ECDSA signature |
21
+ | `opm.contract` | Registry contract address |
22
+ | `opm.packages` | `express,lodash` |
23
+
24
+ ### Per-Package (namespaced)
25
+
26
+ `opm.pkg.<name>.version`, `opm.pkg.<name>.checksum`, `opm.pkg.<name>.fileverse`, etc.
27
+
28
+ ## Subnames
29
+
30
+ OPM creates ENS subnames like `express.djpai.eth` during `opm push` if you own the parent name. Each subname gets its own text records for per-package resolution.
31
+
32
+ ## Contenthash
33
+
34
+ The ENS `contenthash` is set to the Fileverse IPFS CID — read directly from the Fileverse Portal smart contract. This makes audit reports discoverable via standard ENS contenthash resolution.
35
+
36
+ ## When Records Are Used
37
+
38
+ - **`opm push`** — Writes all records after on-chain registration
39
+ - **`opm info`** / **`opm view`** — Reads and displays records alongside on-chain data
40
+ - **`opm install express@djpai.eth`** — Resolves the ENS author, reads metadata
41
+
42
+ <Note>
43
+ Writing records requires the signer (`OPM_SIGNING_KEY`) to own/manage the ENS name. Reading is permissionless.
44
+ </Note>
@@ -1,58 +1,40 @@
1
1
  ---
2
2
  title: 'Multi-Agent Consensus'
3
- description: 'Three LLMs run in parallel, submit scores on-chain, and aggregate via intelligence-weighted averaging.'
3
+ description: 'Three LLMs scan in parallel, submit scores on-chain, aggregate via intelligence-weighted averaging.'
4
4
  ---
5
5
 
6
6
  # Multi-Agent Consensus
7
7
 
8
- OPM uses **three heterogeneous AI agents** that run in parallel to analyze packages. Each agent independently evaluates source code, version history, and CVE data, then submits its risk score and reasoning on-chain. Scores are aggregated using **intelligence-weighted averaging** to produce a final risk assessment.
8
+ Three different AI models analyze every package in parallel. Each submits an independent risk score on-chain. Scores are aggregated using intelligence-weighted averaging.
9
9
 
10
- ## Agent Configuration
10
+ ## Agent Lineup
11
11
 
12
- | Agent | OpenRouter (preferred) | OpenAI (fallback) |
13
- |-------|------------------------|--------------------|
12
+ | Agent | OpenRouter | OpenAI fallback |
13
+ |-------|-----------|----------------|
14
14
  | agent-1 | Claude Sonnet 4 | GPT-4.1 |
15
15
  | agent-2 | Gemini 2.5 Flash | GPT-4.1 Mini |
16
16
  | agent-3 | DeepSeek Chat | GPT-4.1 Nano |
17
17
 
18
- Model diversity reduces single-model blind spots and improves consensus reliability. Override models via `AGENT1_MODEL`, `AGENT2_MODEL`, and `AGENT3_MODEL`.
18
+ Model diversity reduces single-model blind spots. Override via `AGENT1_MODEL`, `AGENT2_MODEL`, `AGENT3_MODEL`.
19
19
 
20
- ## Analysis Pipeline
20
+ ## What Each Agent Does
21
21
 
22
- Each agent receives:
22
+ 1. Receives package source, `package.json`, version history, and any known CVEs
23
+ 2. Produces structured JSON: risk score (0-100), risk level, reasoning, vulnerability list, supply chain indicators
24
+ 3. Submits score on-chain via `OPMRegistry.submitScore()`
23
25
 
24
- - Packed tarball contents (scannable extensions: `.js`, `.ts`, `.mjs`, `.cjs`, `.json`)
25
- - `package.json` and dependency metadata
26
- - Version history and changelog context
27
- - CVE/OSV advisory data when available
26
+ Each agent scores a version only once.
28
27
 
29
- Each agent produces structured JSON:
28
+ ## Intelligence-Weighted Scoring
30
29
 
31
- - **Risk score** (0–100) with categorical classification (LOW, MEDIUM, HIGH, CRITICAL)
32
- - **Vulnerability enumeration** with severity, category, file path, and evidence
33
- - **Supply chain indicators**: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, environment variable access
34
- - **Version history analysis**: changelog risk, maintainer changes, dependency graph mutations
35
- - **Recommendation**: SAFE, CAUTION, WARN, or BLOCK
36
-
37
- ## On-Chain Submission
38
-
39
- Agent wallets call `OPMRegistry.submitScore(name, version, riskScore, reasoning)` for each package version. Each agent may submit only once per version. Scores are stored in the contract's `versionData` mapping.
40
-
41
- ## Intelligence-Weighted Aggregation
42
-
43
- Scores are aggregated using model weights from the **Artificial Analysis API**:
44
-
45
- - **Intelligence Index**: General reasoning and knowledge
46
- - **Coding Index**: Code generation and analysis capability
47
-
48
- Weights are applied to each agent's score before computing the mean. This favors higher-capability models when consensus is ambiguous.
30
+ When `ARTIFICIAL_ANALYSIS_API_KEY` is set, scores are weighted by each model's Intelligence Index and Coding Index from the Artificial Analysis API. Higher-capability models carry more weight in the final score.
49
31
 
50
32
  <Note>
51
- If `ARTIFICIAL_ANALYSIS_API_KEY` is unset or the API is unavailable, OPM falls back to **equal weighting** (simple arithmetic mean).
33
+ Without the API key, agents are weighted equally (simple mean).
52
34
  </Note>
53
35
 
54
- ## Fallback Behavior
36
+ ## Provider Routing
55
37
 
56
- - **Provider**: When `OPENROUTER_API_KEY` is set, OPM routes through OpenRouter. Otherwise it uses `OPENAI_API_KEY` with the GPT-4.1 family.
57
- - **Force provider**: Set `LLM_PROVIDER=openrouter` or `LLM_PROVIDER=openai` to override auto-detection.
58
- - **OpenAI models**: `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano` for agent-1, agent-2, agent-3 respectively.
38
+ - `OPENROUTER_API_KEY` set routes through OpenRouter (multi-model)
39
+ - Only `OPENAI_API_KEY` falls back to GPT-4.1 family
40
+ - Force a provider: `LLM_PROVIDER=openrouter` or `LLM_PROVIDER=openai`
@@ -1,72 +1,45 @@
1
1
  ---
2
2
  title: 'On-chain Registry'
3
- description: 'OPMRegistry.sol stores packages, versions, author profiles, agent scores, and report URIs on Base Sepolia.'
3
+ description: 'OPMRegistry.sol on Base Sepolia packages, scores, authors, agents.'
4
4
  ---
5
5
 
6
6
  # On-chain Registry
7
7
 
8
- The **OPMRegistry** smart contract is the canonical on-chain store for package metadata, author profiles, agent scores, and report URIs. It implements a domain-specific form of the [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) three-registry architecture.
8
+ The **OPMRegistry** smart contract is the source of truth for package metadata, agent scores, author reputation, and registered agents.
9
9
 
10
10
  ## Deployment
11
11
 
12
12
  | Property | Value |
13
13
  |----------|-------|
14
- | **Chain** | Base Sepolia |
15
- | **Chain ID** | 84532 |
16
- | **Contract Address** | `0x16684391fc9bf48246B08Afe16d1a57BFa181d48` |
17
- | **Explorer** | [BaseScan](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
14
+ | **Chain** | Base Sepolia (84532) |
15
+ | **Address** | [`0x16684391fc9bf48246B08Afe16d1a57BFa181d48`](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
16
+ | **Solidity** | 0.8.20 |
18
17
 
19
- Override via `CONTRACT_ADDRESS` in your environment.
18
+ ## What It Stores
20
19
 
21
- ## Data Structures
20
+ | Data | Description |
21
+ |------|-------------|
22
+ | **Packages** | Name → version → checksum, signature, author, ENS name, report URI |
23
+ | **Agent scores** | Per-version risk scores (0-100) with reasoning from each agent |
24
+ | **Authors** | Wallet → ENS name, cumulative reputation, package count |
25
+ | **Agents** | Authorized agents (owner-set or ZK-verified) with name, model, proof hash |
22
26
 
23
- | Struct | Fields |
24
- |--------|--------|
25
- | `AuthorProfile` | `addr`, `ensName`, `reputationTotal`, `reputationCount`, `packagesPublished` |
26
- | `AgentScore` | `agent`, `riskScore`, `reasoning` |
27
- | `VersionData` | `author`, `checksum`, `signature`, `reportURI`, `scores[]`, `exists` |
28
- | `Package` | `name`, `versions[]`, `exists` |
29
- | `RegisteredAgent` | `agentAddress`, `name`, `model`, `systemPromptHash`, `proofHash`, `registeredAt`, `active` |
27
+ ## Key Operations
30
28
 
31
- ## Key Functions
29
+ - **`registerPackage`** — Store a new version with checksum, signature, and ENS binding
30
+ - **`submitScore`** — Agent submits risk score + reasoning (authorized agents only)
31
+ - **`setReportURI`** — Attach Fileverse/IPFS report link to a version
32
+ - **`registerAgent`** — Permissionless agent registration with ZK proof hash
33
+ - **`getSafestVersion`** — Get the lowest-risk version in a lookback window
34
+ - **`getPackageInfo`** — Full metadata + aggregate score for a version
32
35
 
33
- | Function | Access | Description |
34
- |----------|--------|-------------|
35
- | `registerPackage(name, version, checksum, sig, ensName)` | Public | Register a new package version with checksum, signature, and ENS binding |
36
- | `submitScore(name, version, riskScore, reasoning)` | Authorized agents | Submit a risk score (0–100) and reasoning for a package version |
37
- | `setReportURI(name, version, uri)` | Authorized agents | Attach a Fileverse report URI to a package version |
38
- | `getPackageInfo(name, version)` | View | Retrieve full metadata and aggregate score for a package version |
39
- | `getScores(name, version)` | View | Return all individual agent scores for a version |
40
- | `getAggregateScore(name, version)` | View | Compute mean risk score across all agent submissions |
41
- | `getSafestVersion(name, lookback)` | View | Return the lowest-risk version within a configurable lookback window |
42
- | `getVersions(name)` | View | List all registered versions of a package |
43
- | `getAuthorByAddress(addr)` | View | Retrieve author profile by Ethereum address |
44
- | `getAuthorByENS(ensName)` | View | Resolve author profile by ENS name |
45
- | `getAuthorReputation(addr)` | View | Compute author's mean risk score across all packages |
46
- | `registerAgent(name, model, systemPromptHash, proofHash)` | Public | Permissionless agent registration (requires valid ZK proof) |
47
-
48
- ## Events
49
-
50
- | Event | Parameters |
51
- |-------|------------|
52
- | `PackageRegistered` | `name`, `version`, `author`, `ensName` |
53
- | `ScoreSubmitted` | `name`, `version`, `agent`, `riskScore`, `reasoning` |
54
- | `ReportURISet` | `name`, `version`, `uri` |
55
- | `AuthorRegistered` | `addr`, `ensName` |
56
- | `AgentAuthorized` | `agent`, `status` |
57
- | `AgentRegistered` | `agent`, `name`, `model`, `systemPromptHash`, `proofHash`, `timestamp` |
36
+ See [Contract Functions](/contract/functions) for the complete API reference.
58
37
 
59
38
  ## Author Reputation
60
39
 
61
- Author reputation is computed as:
62
-
63
- ```
64
- reputation = reputationTotal / reputationCount
65
- ```
66
-
67
- Where `reputationTotal` accumulates each agent's score for every version of every package authored by that address. This provides a cumulative risk score average across all published packages.
40
+ Computed as `reputationTotal / reputationCount` — the average of all agent scores received across all packages published by an author. Lower is better.
68
41
 
69
- ## Risk Thresholds (Contract)
42
+ ## Risk Thresholds
70
43
 
71
44
  | Constant | Value |
72
45
  |----------|-------|
@@ -1,76 +1,44 @@
1
1
  ---
2
2
  title: 'Security Model'
3
- description: 'OPM defense-in-depth: cryptographic attestation, multi-agent AI, CVE integration, supply chain checks, and ENS-based trust.'
3
+ description: 'Five layers of defense: crypto, AI, CVEs, supply chain checks, and ENS trust.'
4
4
  ---
5
5
 
6
6
  # Security Model
7
7
 
8
- OPM employs a **defense-in-depth** architecture across five layers. No single layer is sufficient; together they mitigate supply chain injection, typosquatting, dependency confusion, maintainer takeover, and known vulnerability exploitation.
8
+ OPM layers five independent defenses. No single layer is sufficient together they catch supply chain injection, typosquatting, dependency confusion, maintainer takeover, and known CVEs.
9
9
 
10
- ## 1. Cryptographic Layer
10
+ ## 1. Cryptographic Signing
11
11
 
12
- - **SHA-256 checksum**: Computed over the packed tarball; stored on-chain and verified at install time
13
- - **ECDSA signature**: secp256k1 signature over the checksum, derived from the author's Ethereum private key
14
- - **On-chain registration**: Checksum, signature, and author binding stored in `OPMRegistry` on Base Sepolia
12
+ Every package gets a SHA-256 checksum and ECDSA signature (secp256k1) from the author's Ethereum wallet. Both are stored on-chain and verified at install time. Tampered tarballs are rejected.
15
13
 
16
- Installation is blocked if the tarball checksum does not match the on-chain value or if the signature verification fails.
14
+ ## 2. Multi-Agent AI Scanning
17
15
 
18
- ## 2. AI Layer
16
+ Three LLMs (Claude, Gemini, DeepSeek) analyze source code, dependency metadata, and version history in parallel. Each submits a risk score (0-100) on-chain. Scores are aggregated using intelligence-weighted averaging via the Artificial Analysis API.
19
17
 
20
- Three heterogeneous LLMs analyze packages in parallel:
18
+ Agents flag: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, and env var access.
21
19
 
22
- - Static analysis of source code, dependency metadata, and version history
23
- - Each agent submits a risk score (0–100) and reasoning on-chain
24
- - **Intelligence-weighted aggregation** via the Artificial Analysis API (Intelligence Index, Coding Index)
25
- - Fallback to equal weighting if the API is unavailable
20
+ ## 3. CVE Detection
26
21
 
27
- <CardGroup cols={2}>
28
- <Card title="Agent 1" icon="robot">
29
- Claude Sonnet 4 (OpenRouter) / GPT-4.1 (OpenAI fallback)
30
- </Card>
31
- <Card title="Agent 2" icon="robot">
32
- Gemini 2.5 Flash (OpenRouter) / GPT-4.1 Mini (OpenAI fallback)
33
- </Card>
34
- <Card title="Agent 3" icon="robot">
35
- DeepSeek Chat (OpenRouter) / GPT-4.1 Nano (OpenAI fallback)
36
- </Card>
37
- </CardGroup>
22
+ Real-time lookup against the OSV database (CVE + GHSA advisories) with CVSS v3 severity scoring. CRITICAL CVEs block installation. HIGH CVEs trigger warnings with suggested fix versions.
38
23
 
39
- ## 3. CVE Layer
24
+ ## 4. Supply Chain Checks
40
25
 
41
- - **OSV (Open Source Vulnerabilities)**: Real-time CVE and GHSA advisory data
42
- - **GitHub Advisory Database**: Integrated via OSV API
43
- - **CVSS v3** base score computation for severity classification
44
- - **CRITICAL** severity: installation blocked
45
- - **HIGH** severity: warning with suggested fix version
26
+ | Check | How |
27
+ |-------|-----|
28
+ | Typosquatting | Levenshtein distance against top npm packages + AI name similarity assessment |
29
+ | Dependency confusion | Scoped vs unscoped name conflicts surfaced during `opm check` |
30
+ | ChainPatrol blocklist | Fallback for packages not in the on-chain registry |
46
31
 
47
- ## 4. Supply Chain Layer
32
+ ## 5. ENS Trust Layer
48
33
 
49
- | Check | Description |
50
- |-------|-------------|
51
- | **Typosquat detection** | Package names compared against npm search results and download-count differentials; AI agents assess name similarity |
52
- | **Dependency confusion** | Scoped vs unscoped name conflicts and internal package shadowing surfaced during `opm check` |
53
- | **ChainPatrol blocklist** | Fallback blocklist for packages absent from the on-chain registry (requires `CHAINPATROL_API_KEY`) |
54
-
55
- AI agents also flag: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, and environment variable access.
56
-
57
- ## 5. Trust Layer
58
-
59
- - **ENS identity resolution**: Author addresses resolved to ENS names (Sepolia, Mainnet fallback)
60
- - **On-chain author reputation**: Cumulative risk score average across all published packages
61
- - **Author profiles**: ENS text records (avatar, description, URL, GitHub, Twitter, email) for human verification
34
+ Author addresses resolve to ENS names. Reputation is computed as the average risk score across all published packages. ENS text records (avatar, GitHub, Twitter) provide human-verifiable identity signals.
62
35
 
63
36
  ## Risk Thresholds
64
37
 
65
- | Range | Level | Effect |
66
- |-------|-------|--------|
38
+ | Score | Level | What happens |
39
+ |-------|-------|-------------|
67
40
  | 0–20 | LOW | Safe to install |
68
41
  | 21–40 | MEDIUM | Flagged for caution |
69
42
  | 41–70 | HIGH | Warnings triggered |
70
43
  | 71–100 | CRITICAL | High risk |
71
-
72
- | Threshold | Value | Behavior |
73
- |-----------|-------|----------|
74
- | Block threshold (CLI) | 80 | `opm push` blocks publication; `opm install` blocks installation |
75
- | `HIGH_RISK_THRESHOLD` (contract) | 70 | Packages above trigger warnings |
76
- | `MEDIUM_RISK_THRESHOLD` (contract) | 40 | Packages above flagged for caution |
44
+ | **≥ 80** | — | **Blocks `opm push` and `opm install`** |
@@ -1,82 +1,44 @@
1
1
  ---
2
2
  title: 'ZK Agent Verification'
3
- description: 'Permissionless agent registration requires passing a benchmark suite and proving 100% accuracy via zero-knowledge proofs.'
3
+ description: 'Permissionless agent registration with zero-knowledge proof of 100% benchmark accuracy.'
4
4
  ---
5
5
 
6
6
  # ZK Agent Verification
7
7
 
8
- OPM supports **permissionless agent registration** on the on-chain registry. To prevent malicious or spamming agents from participating, agents must pass a benchmark suite and prove **100% accuracy** via a zero-knowledge proof—without revealing the test data or individual results.
8
+ Anyone can register a security agent on OPM. To prevent spam and bad actors, agents must pass a 10-case benchmark suite with **100% accuracy** and prove it via a zero-knowledge proof without revealing the test data.
9
9
 
10
10
  ## Benchmark Suite
11
11
 
12
- The benchmark consists of **10 labeled test cases** covering:
12
+ 10 labeled test cases covering:
13
13
 
14
- | Category | Description |
15
- |----------|-------------|
16
- | Clean packages | Legitimate, low-risk packages |
17
- | Typosquats | Name-similar malicious packages |
18
- | Env exfiltration | Environment variable exfiltration attempts |
19
- | Obfuscated code | Heavily obfuscated or minified payloads |
20
- | Postinstall attacks | Malicious `postinstall` scripts |
21
- | Known CVEs | Packages with known vulnerabilities |
22
- | Dependency confusion | Scoped vs unscoped name conflicts |
14
+ | Category | Cases | Expected |
15
+ |----------|-------|----------|
16
+ | Clean packages | 3 | SAFE |
17
+ | Typosquat | 1 | FLAGGED |
18
+ | Malicious (postinstall, SSH exfil) | 2 | FLAGGED |
19
+ | Known CVE | 1 | FLAGGED |
20
+ | Obfuscated payload | 1 | FLAGGED |
21
+ | Env var exfiltration | 1 | FLAGGED |
22
+ | Dependency confusion | 1 | FLAGGED |
23
23
 
24
- Each test case has an **expected output**: a risk level (LOW, MEDIUM, HIGH, CRITICAL) and score range. Expected outputs are committed via a hash before the agent runs.
24
+ ## How It Works
25
25
 
26
- ## Verification Flow
26
+ 1. **Commit** — Expected outputs hashed with a random salt → `commitmentHash`
27
+ 2. **Run** — Agent processes all 10 cases in a single LLM call
28
+ 3. **Compare** — Actual outputs checked against expected
29
+ 4. **Prove** — ZK proof binds `commitmentHash`, `resultHash`, and `passed` flag without revealing test data or individual results
30
+ 5. **Register** — If 100% accurate, call `OPMRegistry.registerAgent()` with the proof hash
27
31
 
28
- 1. **Commitment**: Expected outputs hashed with a salt `commitmentHash`
29
- 2. **Execution**: Candidate agent runs against all 10 cases
30
- 3. **Comparison**: Actual outputs compared to expected; `passed = 1` iff all match
31
- 4. **Proof**: ZK proof binds `commitmentHash`, `passed`, and `result_hash` without revealing test data or individual results
32
- 5. **Registration**: Only agents with `passed = 1` (100% accuracy) are registered on-chain
32
+ The proof proves accuracy without leaking the labeled dataset, so future agents can't game the benchmark.
33
33
 
34
34
  ## Circom Circuit
35
35
 
36
- The `accuracy_verifier.circom` circuit implements the verification logic:
36
+ `AccuracyVerifier(10)` in `packages/contracts/circuits/accuracy_verifier.circom`:
37
37
 
38
- - **Private inputs**: `expected[N]`, `actual[N]`, `salt`
39
- - **Public input**: `commitmentHash` (Poseidon hash of `salt` and `expected[0..N-1]`)
40
- - **Public outputs**: `passed` (1 if all match, 0 otherwise), `proofHash`
38
+ - **Private inputs**: `expected[10]`, `actual[10]`, `salt`
39
+ - **Public input**: `commitmentHash` (Poseidon hash of salt + expected values)
40
+ - **Public outputs**: `passed` (1 if all match), `proofHash`
41
41
 
42
- The circuit:
43
-
44
- 1. Verifies the commitment: `hash(salt, expected[0..N-1]) === commitmentHash`
45
- 2. Checks equality for each test case: `expected[i] === actual[i]`
46
- 3. Computes `passed` as the product of all match bits (1 iff all match)
47
- 4. Outputs `proofHash = hash(commitmentHash, passed, salt)` binding the result to the commitment
48
-
49
- <CodeGroup>
50
-
51
- ```bash Compile
52
- circom accuracy_verifier.circom --r1cs --wasm --sym -o build/
53
- ```
54
-
55
- ```bash Trusted setup
56
- snarkjs groth16 setup build/accuracy_verifier.r1cs pot12_final.ptau build/accuracy_verifier_0000.zkey
57
- snarkjs zkey contribute build/accuracy_verifier_0000.zkey build/accuracy_verifier_final.zkey --name="opm-ceremony"
58
- snarkjs zkey export verificationkey build/accuracy_verifier_final.zkey build/verification_key.json
59
- ```
60
-
61
- ```bash Prove
62
- snarkjs groth16 prove build/accuracy_verifier_final.zkey build/accuracy_verifier_js/accuracy_verifier.wasm input.json build/proof.json build/public.json
63
- ```
64
-
65
- ```bash Verify
66
- snarkjs groth16 verify build/verification_key.json build/public.json build/proof.json
67
- ```
68
-
69
- </CodeGroup>
70
-
71
- ## On-Chain Registration
72
-
73
- Agents call `OPMRegistry.registerAgent(name, model, systemPromptHash, proofHash)` with a valid proof hash. The contract:
74
-
75
- - Requires `proofHash != bytes32(0)`
76
- - Rejects agents already authorized or registered
77
- - Stores `RegisteredAgent` with `proofHash` for auditability
78
- - Auto-authorizes the agent for `submitScore` and `setReportURI`
79
-
80
- <Warning>
81
- The Circom circuit is available for on-chain verification. A Solidity verifier can be exported via `snarkjs zkey export solidityverifier` for full trustless verification in future contract upgrades.
82
- </Warning>
42
+ <Note>
43
+ Currently, `keccak256(proof)` is stored on-chain. Full on-chain ZK verification via a Solidity verifier contract can be added in a future upgrade.
44
+ </Note>