opmsec 0.1.3 → 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.
- package/.env.example +1 -0
- package/.husky/pre-commit +1 -0
- package/README.md +71 -275
- package/bun.lock +5 -5
- package/docs/architecture/agents.mdx +11 -59
- package/docs/architecture/benchmarks.mdx +20 -46
- package/docs/architecture/overview.mdx +31 -38
- package/docs/architecture/scanner.mdx +11 -37
- package/docs/cli/audit.mdx +9 -12
- package/docs/cli/check.mdx +12 -26
- package/docs/cli/fix.mdx +10 -30
- package/docs/cli/info.mdx +12 -19
- package/docs/cli/install.mdx +27 -39
- package/docs/cli/push.mdx +40 -57
- package/docs/cli/register-agent.mdx +21 -53
- package/docs/cli/view.mdx +12 -29
- package/docs/concepts/ens-records.mdx +44 -0
- package/docs/concepts/multi-agent-consensus.mdx +18 -36
- package/docs/concepts/on-chain-registry.mdx +22 -49
- package/docs/concepts/security-model.mdx +20 -52
- package/docs/concepts/zk-agent-verification.mdx +26 -64
- package/docs/contract/events.mdx +13 -74
- package/docs/contract/functions.mdx +40 -126
- package/docs/contract/overview.mdx +17 -36
- package/docs/introduction.mdx +22 -25
- package/docs/mint.json +3 -2
- package/docs/quickstart.mdx +34 -70
- package/docs/system-design.png +0 -0
- package/package.json +7 -6
- package/packages/cli/src/commands/author-view.tsx +87 -2
- package/packages/cli/src/commands/check.tsx +18 -5
- package/packages/cli/src/commands/fix.tsx +25 -12
- package/packages/cli/src/commands/info.tsx +92 -4
- package/packages/cli/src/commands/install.tsx +327 -23
- package/packages/cli/src/commands/push.tsx +112 -0
- package/packages/cli/src/commands/register-agent.tsx +72 -31
- package/packages/cli/src/index.tsx +7 -5
- package/packages/cli/src/services/ens-records.ts +525 -0
- package/packages/cli/src/services/version.ts +156 -5
- package/packages/core/src/benchmarks.ts +116 -0
- package/packages/core/src/constants.ts +18 -6
- package/packages/core/src/model-rankings.ts +40 -15
- package/packages/core/src/types.ts +10 -0
- package/packages/core/src/utils.ts +136 -1
- package/packages/scanner/src/index.ts +2 -1
- package/packages/scanner/src/queue/memory-queue.ts +7 -2
- package/packages/scanner/src/services/benchmark-runner.ts +86 -1
- package/packages/scanner/src/services/fileverse.ts +61 -12
- package/packages/scanner/src/services/openrouter.ts +18 -7
- package/packages/web/.next/BUILD_ID +1 -0
- package/packages/web/.next/app-path-routes-manifest.json +4 -0
- package/packages/web/.next/diagnostics/build-diagnostics.json +6 -0
- package/packages/web/.next/diagnostics/framework.json +1 -0
- package/packages/web/.next/export-marker.json +6 -0
- package/packages/web/.next/images-manifest.json +58 -0
- package/packages/web/.next/next-minimal-server.js.nft.json +1 -0
- package/packages/web/.next/next-server.js.nft.json +1 -0
- package/packages/web/.next/prerender-manifest.json +54 -4
- package/packages/web/.next/required-server-files.json +320 -0
- package/packages/web/.next/routes-manifest.json +53 -1
- package/packages/web/.next/server/app/_not-found/page.js +2 -0
- package/packages/web/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/packages/web/.next/server/app/_not-found.html +1 -0
- package/packages/web/.next/server/app/_not-found.meta +8 -0
- package/packages/web/.next/server/app/_not-found.rsc +18 -0
- package/packages/web/.next/server/app/index.html +6 -0
- package/packages/web/.next/server/app/index.meta +7 -0
- package/packages/web/.next/server/app/index.rsc +22 -0
- package/packages/web/.next/server/app/page.js +24 -24
- package/packages/web/.next/server/app/page.js.nft.json +1 -0
- package/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/packages/web/.next/server/chunks/611.js +6 -0
- package/packages/web/.next/server/chunks/778.js +30 -0
- package/packages/web/.next/server/functions-config-manifest.json +4 -0
- package/packages/web/.next/server/interception-route-rewrite-manifest.js +1 -1
- package/packages/web/.next/server/next-font-manifest.js +1 -1
- package/packages/web/.next/server/next-font-manifest.json +1 -1
- package/packages/web/.next/server/pages/404.html +1 -0
- package/packages/web/.next/server/pages/500.html +1 -0
- package/packages/web/.next/server/pages/_app.js +1 -0
- package/packages/web/.next/server/pages/_app.js.nft.json +1 -0
- package/packages/web/.next/server/pages/_document.js +1 -0
- package/packages/web/.next/server/pages/_document.js.nft.json +1 -0
- package/packages/web/.next/server/pages/_error.js +19 -0
- package/packages/web/.next/server/pages/_error.js.nft.json +1 -0
- package/packages/web/.next/server/webpack-runtime.js +2 -2
- package/packages/web/.next/static/0esGzFBCzREfVwijEGDfL/_buildManifest.js +1 -0
- package/packages/web/.next/static/0esGzFBCzREfVwijEGDfL/_ssgManifest.js +1 -0
- package/packages/web/.next/static/chunks/174-5b5efcb3b8efcc01.js +1 -0
- package/packages/web/.next/static/chunks/255-0dc49b7a6e8e5c05.js +1 -0
- package/packages/web/.next/static/chunks/4bd1b696-382748cc942d8a14.js +1 -0
- package/packages/web/.next/static/chunks/app/_not-found/page-0da542be7eb33a64.js +1 -0
- package/packages/web/.next/static/chunks/app/layout-de8e841104500505.js +1 -0
- package/packages/web/.next/static/chunks/app/layout.js +37 -7
- package/packages/web/.next/static/chunks/app/page-7e086379698b9fb0.js +1 -0
- package/packages/web/.next/static/chunks/app/page.js +297 -1
- package/packages/web/.next/static/chunks/framework-ac73abd125e371fe.js +1 -0
- package/packages/web/.next/static/chunks/main-4e8d71b5ef7ee7e3.js +1 -0
- package/packages/web/.next/static/chunks/main-app-dd261207182e5a23.js +1 -0
- package/packages/web/.next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
- package/packages/web/.next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
- package/packages/web/.next/static/chunks/webpack-0dcd67569eb46132.js +1 -0
- package/packages/web/.next/static/chunks/webpack.js +2 -2
- package/packages/web/.next/static/css/102562cf2d0ae9b0.css +3 -0
- package/packages/web/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/packages/web/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/packages/web/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/packages/web/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/packages/web/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/packages/web/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- package/packages/web/.next/static/webpack/16f18baa938a434c.webpack.hot-update.json +1 -0
- package/packages/web/.next/static/webpack/5fe9fe8578f9c3d2.webpack.hot-update.json +1 -0
- package/packages/web/.next/static/webpack/73c7d02260cc80e4.webpack.hot-update.json +1 -0
- package/packages/web/.next/static/webpack/a2d85d19aa028de1.webpack.hot-update.json +1 -0
- package/packages/web/.next/static/webpack/app/{layout.73e341375c8d429e.hot-update.js → layout.16f18baa938a434c.hot-update.js} +1 -1
- package/packages/web/.next/static/webpack/app/{layout.6fee6306e0f98869.hot-update.js → layout.5fe9fe8578f9c3d2.hot-update.js} +1 -1
- package/packages/web/.next/static/webpack/app/layout.653e365406c0d9ac.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/layout.6800169a899e3a8b.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/layout.73c7d02260cc80e4.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/layout.a2d85d19aa028de1.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/page.653e365406c0d9ac.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/page.6800169a899e3a8b.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/page.73c7d02260cc80e4.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/app/page.a2d85d19aa028de1.hot-update.js +22 -0
- package/packages/web/.next/static/webpack/{webpack.6fee6306e0f98869.hot-update.js → webpack.16f18baa938a434c.hot-update.js} +2 -2
- package/packages/web/.next/static/webpack/{webpack.73e341375c8d429e.hot-update.js → webpack.5fe9fe8578f9c3d2.hot-update.js} +2 -2
- package/packages/web/.next/static/webpack/webpack.653e365406c0d9ac.hot-update.js +12 -0
- package/packages/web/.next/static/webpack/webpack.6800169a899e3a8b.hot-update.js +12 -0
- package/packages/web/.next/static/webpack/webpack.73c7d02260cc80e4.hot-update.js +12 -0
- package/packages/web/.next/static/webpack/webpack.a2d85d19aa028de1.hot-update.js +12 -0
- package/packages/web/.next/trace +2 -5
- package/packages/web/app/globals.css +197 -51
- package/packages/web/app/layout.tsx +6 -3
- package/packages/web/app/page.tsx +791 -309
- package/packages/web/bun.lock +66 -105
- package/packages/web/next.config.ts +8 -1
- package/packages/web/package.json +5 -2
- package/packages/web/postcss.config.mjs +2 -2
- package/packages/web/public/apple-icon.png +1 -0
- package/packages/web/public/dependency-bottleneck.png +0 -0
- package/packages/web/public/icon-dark-32x32.png +1 -0
- package/packages/web/public/icon-light-32x32.png +1 -0
- package/packages/web/public/icon.svg +1 -0
- package/packages/web/public/nextjs-cve-announcement.png +0 -0
- package/packages/web/public/phantomraven-npm-attack.png +0 -0
- package/packages/web/public/placeholder-logo.png +1 -0
- package/packages/web/public/placeholder-logo.svg +1 -0
- package/packages/web/public/placeholder-user.jpg +1 -0
- package/packages/web/public/placeholder.jpg +1 -0
- package/packages/web/public/placeholder.svg +1 -0
- package/packages/web/public/react-cve-meme.png +0 -0
- package/packages/web/public/wallet-drain-exploit.png +0 -0
- package/packages/web/styles/globals.css +125 -0
- package/packages/web/.next/server/vendor-chunks/@swc.js +0 -55
- package/packages/web/.next/server/vendor-chunks/next.js +0 -3010
- package/packages/web/.next/static/chunks/app-pages-internals.js +0 -182
- package/packages/web/.next/static/chunks/main-app.js +0 -1882
- package/packages/web/.next/static/css/app/layout.css +0 -1237
- package/packages/web/.next/static/webpack/633457081244afec._.hot-update.json +0 -1
- package/packages/web/.next/static/webpack/app/page.6fee6306e0f98869.hot-update.js +0 -22
- package/packages/web/.next/static/webpack/app/page.73e341375c8d429e.hot-update.js +0 -22
- package/packages/web/tailwind.config.ts +0 -48
- /package/packages/web/.next/static/chunks/{polyfills.js → polyfills-42372ed130431b0a.js} +0 -0
- /package/packages/web/.next/static/webpack/{6fee6306e0f98869.webpack.hot-update.json → 653e365406c0d9ac.webpack.hot-update.json} +0 -0
- /package/packages/web/.next/static/webpack/{73e341375c8d429e.webpack.hot-update.json → 6800169a899e3a8b.webpack.hot-update.json} +0 -0
|
@@ -1,82 +1,44 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'ZK Agent Verification'
|
|
3
|
-
description: 'Permissionless agent registration
|
|
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
|
-
|
|
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
|
-
|
|
12
|
+
10 labeled test cases covering:
|
|
13
13
|
|
|
14
|
-
| Category |
|
|
15
|
-
|
|
16
|
-
| Clean packages |
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
| Dependency confusion |
|
|
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
|
-
|
|
24
|
+
## How It Works
|
|
25
25
|
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
36
|
+
`AccuracyVerifier(10)` in `packages/contracts/circuits/accuracy_verifier.circom`:
|
|
37
37
|
|
|
38
|
-
- **Private inputs**: `expected[
|
|
39
|
-
- **Public input**: `commitmentHash` (Poseidon hash of
|
|
40
|
-
- **Public outputs**: `passed` (1 if all match
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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>
|
package/docs/contract/events.mdx
CHANGED
|
@@ -1,115 +1,54 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Contract Events'
|
|
3
|
-
description: '
|
|
3
|
+
description: 'OPMRegistry events reference.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Contract Events
|
|
7
7
|
|
|
8
|
-
## PackageRegistration
|
|
9
|
-
|
|
10
8
|
### PackageRegistered
|
|
11
9
|
|
|
12
10
|
```solidity
|
|
13
|
-
event PackageRegistered(string name, string version, address author, string ensName)
|
|
11
|
+
event PackageRegistered(string name, string version, address author, string ensName)
|
|
14
12
|
```
|
|
15
13
|
|
|
16
|
-
Emitted
|
|
17
|
-
|
|
18
|
-
| Parameter | Type | Description |
|
|
19
|
-
|-----------|------|-------------|
|
|
20
|
-
| name | string | Package name |
|
|
21
|
-
| version | string | Semantic version |
|
|
22
|
-
| author | address | Author wallet address |
|
|
23
|
-
| ensName | string | Author ENS name |
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Score Submission
|
|
14
|
+
Emitted on `registerPackage()`.
|
|
28
15
|
|
|
29
16
|
### ScoreSubmitted
|
|
30
17
|
|
|
31
18
|
```solidity
|
|
32
|
-
event ScoreSubmitted(string name, string version, address agent, uint8 riskScore, string reasoning)
|
|
19
|
+
event ScoreSubmitted(string name, string version, address agent, uint8 riskScore, string reasoning)
|
|
33
20
|
```
|
|
34
21
|
|
|
35
|
-
Emitted
|
|
36
|
-
|
|
37
|
-
| Parameter | Type | Description |
|
|
38
|
-
|-----------|------|-------------|
|
|
39
|
-
| name | string | Package name |
|
|
40
|
-
| version | string | Semantic version |
|
|
41
|
-
| agent | address | Agent wallet address |
|
|
42
|
-
| riskScore | uint8 | Risk score 0–100 |
|
|
43
|
-
| reasoning | string | Agent reasoning |
|
|
22
|
+
Emitted on `submitScore()`.
|
|
44
23
|
|
|
45
24
|
### ReportURISet
|
|
46
25
|
|
|
47
26
|
```solidity
|
|
48
|
-
event ReportURISet(string name, string version, string uri)
|
|
27
|
+
event ReportURISet(string name, string version, string uri)
|
|
49
28
|
```
|
|
50
29
|
|
|
51
|
-
Emitted
|
|
52
|
-
|
|
53
|
-
| Parameter | Type | Description |
|
|
54
|
-
|-----------|------|-------------|
|
|
55
|
-
| name | string | Package name |
|
|
56
|
-
| version | string | Semantic version |
|
|
57
|
-
| uri | string | Fileverse/IPFS report URI |
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Author
|
|
30
|
+
Emitted on `setReportURI()`.
|
|
62
31
|
|
|
63
32
|
### AuthorRegistered
|
|
64
33
|
|
|
65
34
|
```solidity
|
|
66
|
-
event AuthorRegistered(address addr, string ensName)
|
|
35
|
+
event AuthorRegistered(address addr, string ensName)
|
|
67
36
|
```
|
|
68
37
|
|
|
69
|
-
Emitted
|
|
70
|
-
|
|
71
|
-
| Parameter | Type | Description |
|
|
72
|
-
|-----------|------|-------------|
|
|
73
|
-
| addr | address | Author wallet address |
|
|
74
|
-
| ensName | string | Author ENS name |
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Agent Management
|
|
38
|
+
Emitted on first `registerPackage()` call by an author.
|
|
79
39
|
|
|
80
40
|
### AgentAuthorized
|
|
81
41
|
|
|
82
42
|
```solidity
|
|
83
|
-
event AgentAuthorized(address agent, bool status)
|
|
43
|
+
event AgentAuthorized(address agent, bool status)
|
|
84
44
|
```
|
|
85
45
|
|
|
86
|
-
Emitted
|
|
87
|
-
|
|
88
|
-
| Parameter | Type | Description |
|
|
89
|
-
|-----------|------|-------------|
|
|
90
|
-
| agent | address | Agent wallet address |
|
|
91
|
-
| status | bool | true = authorized, false = deauthorized |
|
|
46
|
+
Emitted on `setAgent()`, `revokeAgent()`, or `registerAgent()`.
|
|
92
47
|
|
|
93
48
|
### AgentRegistered
|
|
94
49
|
|
|
95
50
|
```solidity
|
|
96
|
-
event AgentRegistered(
|
|
97
|
-
address indexed agent,
|
|
98
|
-
string name,
|
|
99
|
-
string model,
|
|
100
|
-
bytes32 systemPromptHash,
|
|
101
|
-
bytes32 proofHash,
|
|
102
|
-
uint256 timestamp
|
|
103
|
-
);
|
|
51
|
+
event AgentRegistered(address indexed agent, string name, string model, bytes32 systemPromptHash, bytes32 proofHash, uint256 timestamp)
|
|
104
52
|
```
|
|
105
53
|
|
|
106
|
-
Emitted
|
|
107
|
-
|
|
108
|
-
| Parameter | Type | Description |
|
|
109
|
-
|-----------|------|-------------|
|
|
110
|
-
| agent | address | Agent wallet address (indexed) |
|
|
111
|
-
| name | string | Agent identifier |
|
|
112
|
-
| model | string | LLM model |
|
|
113
|
-
| systemPromptHash | bytes32 | Keccak256 of system prompt |
|
|
114
|
-
| proofHash | bytes32 | Keccak256 of ZK proof |
|
|
115
|
-
| timestamp | uint256 | Block timestamp |
|
|
54
|
+
Emitted on permissionless `registerAgent()`.
|
|
@@ -1,122 +1,59 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Contract Functions'
|
|
3
|
-
description: '
|
|
3
|
+
description: 'OPMRegistry function reference.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Contract Functions
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Write Functions
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### registerPackage
|
|
11
11
|
|
|
12
12
|
```solidity
|
|
13
|
-
function
|
|
13
|
+
function registerPackage(string name, string version, bytes32 checksum, bytes sig, string ensName) external
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Register a package version. Sender becomes the author. Reverts if version already registered.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|-----------|------|-------------|
|
|
20
|
-
| agent | address | Agent wallet address |
|
|
21
|
-
| status | bool | true = authorized, false = deauthorized |
|
|
22
|
-
|
|
23
|
-
### revokeAgent
|
|
18
|
+
### submitScore
|
|
24
19
|
|
|
25
20
|
```solidity
|
|
26
|
-
function
|
|
21
|
+
function submitScore(string name, string version, uint8 riskScore, string reasoning) external onlyAgent
|
|
27
22
|
```
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Package Registration (Public)
|
|
24
|
+
Submit risk score (0-100) with reasoning. Each agent may score a version once.
|
|
34
25
|
|
|
35
|
-
###
|
|
26
|
+
### setReportURI
|
|
36
27
|
|
|
37
28
|
```solidity
|
|
38
|
-
function
|
|
39
|
-
string calldata name,
|
|
40
|
-
string calldata version,
|
|
41
|
-
bytes32 checksum,
|
|
42
|
-
bytes calldata sig,
|
|
43
|
-
string calldata ensName
|
|
44
|
-
) external
|
|
29
|
+
function setReportURI(string name, string version, string uri) external onlyAgent
|
|
45
30
|
```
|
|
46
31
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| Parameter | Type | Description |
|
|
50
|
-
|-----------|------|-------------|
|
|
51
|
-
| name | string | Package name |
|
|
52
|
-
| version | string | Semantic version |
|
|
53
|
-
| checksum | bytes32 | SHA-256 of tarball |
|
|
54
|
-
| sig | bytes | ECDSA signature of checksum |
|
|
55
|
-
| ensName | string | Author ENS name (e.g. vitalik.eth) |
|
|
56
|
-
|
|
57
|
-
Reverts if the version is already registered.
|
|
32
|
+
Attach a Fileverse/IPFS report URI to a package version.
|
|
58
33
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
## Agent-Only (Authorized Agents)
|
|
62
|
-
|
|
63
|
-
### submitScore
|
|
34
|
+
### registerAgent
|
|
64
35
|
|
|
65
36
|
```solidity
|
|
66
|
-
function
|
|
67
|
-
string calldata name,
|
|
68
|
-
string calldata version,
|
|
69
|
-
uint8 riskScore,
|
|
70
|
-
string calldata reasoning
|
|
71
|
-
) external onlyAgent
|
|
37
|
+
function registerAgent(string name, string model, bytes32 systemPromptHash, bytes32 proofHash) external
|
|
72
38
|
```
|
|
73
39
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
| Parameter | Type | Description |
|
|
77
|
-
|-----------|------|-------------|
|
|
78
|
-
| name | string | Package name |
|
|
79
|
-
| version | string | Semantic version |
|
|
80
|
-
| riskScore | uint8 | Risk score 0–100 |
|
|
81
|
-
| reasoning | string | Agent reasoning |
|
|
40
|
+
Permissionless agent registration. Requires non-zero `proofHash`. Reverts if sender already authorized or registered.
|
|
82
41
|
|
|
83
|
-
###
|
|
42
|
+
### setAgent
|
|
84
43
|
|
|
85
44
|
```solidity
|
|
86
|
-
function
|
|
87
|
-
string calldata name,
|
|
88
|
-
string calldata version,
|
|
89
|
-
string calldata uri
|
|
90
|
-
) external onlyAgent
|
|
45
|
+
function setAgent(address agent, bool status) external onlyOwner
|
|
91
46
|
```
|
|
92
47
|
|
|
93
|
-
|
|
48
|
+
Owner-only: authorize or deauthorize an agent.
|
|
94
49
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
## Permissionless Agent Registration
|
|
98
|
-
|
|
99
|
-
### registerAgent
|
|
50
|
+
### revokeAgent
|
|
100
51
|
|
|
101
52
|
```solidity
|
|
102
|
-
function
|
|
103
|
-
string calldata name,
|
|
104
|
-
string calldata model,
|
|
105
|
-
bytes32 systemPromptHash,
|
|
106
|
-
bytes32 proofHash
|
|
107
|
-
) external
|
|
53
|
+
function revokeAgent(address agent) external onlyOwner
|
|
108
54
|
```
|
|
109
55
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| Parameter | Type | Description |
|
|
113
|
-
|-----------|------|-------------|
|
|
114
|
-
| name | string | Agent identifier |
|
|
115
|
-
| model | string | LLM model (e.g. anthropic/claude-sonnet-4) |
|
|
116
|
-
| systemPromptHash | bytes32 | Keccak256 of system prompt |
|
|
117
|
-
| proofHash | bytes32 | Keccak256 of ZK proof |
|
|
118
|
-
|
|
119
|
-
Reverts if the sender is already authorized or registered, or if <code>proofHash</code> is zero.
|
|
56
|
+
Owner-only: deactivate a registered agent.
|
|
120
57
|
|
|
121
58
|
---
|
|
122
59
|
|
|
@@ -125,91 +62,68 @@ Reverts if the sender is already authorized or registered, or if <code>proofHash
|
|
|
125
62
|
### getPackageInfo
|
|
126
63
|
|
|
127
64
|
```solidity
|
|
128
|
-
function getPackageInfo(string
|
|
129
|
-
external view returns (
|
|
130
|
-
address author,
|
|
131
|
-
bytes32 checksum,
|
|
132
|
-
bytes memory sig,
|
|
133
|
-
string memory ensName,
|
|
134
|
-
string memory reportURI,
|
|
135
|
-
uint8 aggregateScore,
|
|
136
|
-
bool exists
|
|
137
|
-
)
|
|
65
|
+
function getPackageInfo(string name, string version)
|
|
66
|
+
external view returns (address author, bytes32 checksum, bytes sig, string ensName, string reportURI, uint8 aggregateScore, bool exists)
|
|
138
67
|
```
|
|
139
68
|
|
|
140
|
-
|
|
69
|
+
Full metadata + aggregate score for a version.
|
|
141
70
|
|
|
142
71
|
### getScores
|
|
143
72
|
|
|
144
73
|
```solidity
|
|
145
|
-
function getScores(string
|
|
146
|
-
external view returns (AgentScore[] memory)
|
|
74
|
+
function getScores(string name, string version) external view returns (AgentScore[] memory)
|
|
147
75
|
```
|
|
148
76
|
|
|
149
|
-
|
|
77
|
+
All agent scores for a version. Each has `agent`, `riskScore`, `reasoning`.
|
|
150
78
|
|
|
151
79
|
### getAggregateScore
|
|
152
80
|
|
|
153
81
|
```solidity
|
|
154
|
-
function getAggregateScore(string
|
|
155
|
-
external view returns (uint8)
|
|
82
|
+
function getAggregateScore(string name, string version) external view returns (uint8)
|
|
156
83
|
```
|
|
157
84
|
|
|
158
|
-
|
|
85
|
+
Mean risk score across all agents (0 if no scores).
|
|
159
86
|
|
|
160
87
|
### getSafestVersion
|
|
161
88
|
|
|
162
89
|
```solidity
|
|
163
|
-
function getSafestVersion(string
|
|
164
|
-
external view returns (string memory)
|
|
90
|
+
function getSafestVersion(string name, uint8 lookback) external view returns (string memory)
|
|
165
91
|
```
|
|
166
92
|
|
|
167
|
-
|
|
93
|
+
Lowest-risk version in the last `lookback` versions.
|
|
168
94
|
|
|
169
95
|
### getVersions
|
|
170
96
|
|
|
171
97
|
```solidity
|
|
172
|
-
function getVersions(string
|
|
173
|
-
external view returns (string[] memory)
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Returns all registered versions for a package.
|
|
177
|
-
|
|
178
|
-
### getAuthorByAddress
|
|
179
|
-
|
|
180
|
-
```solidity
|
|
181
|
-
function getAuthorByAddress(address addr)
|
|
182
|
-
external view returns (AuthorProfile memory)
|
|
98
|
+
function getVersions(string name) external view returns (string[] memory)
|
|
183
99
|
```
|
|
184
100
|
|
|
185
|
-
|
|
101
|
+
All registered versions of a package.
|
|
186
102
|
|
|
187
|
-
### getAuthorByENS
|
|
103
|
+
### getAuthorByAddress / getAuthorByENS
|
|
188
104
|
|
|
189
105
|
```solidity
|
|
190
|
-
function
|
|
191
|
-
|
|
106
|
+
function getAuthorByAddress(address addr) external view returns (AuthorProfile memory)
|
|
107
|
+
function getAuthorByENS(string ensName) external view returns (AuthorProfile memory)
|
|
192
108
|
```
|
|
193
109
|
|
|
194
|
-
|
|
110
|
+
Author profile: `addr`, `ensName`, `reputationTotal`, `reputationCount`, `packagesPublished`.
|
|
195
111
|
|
|
196
112
|
### getAuthorReputation
|
|
197
113
|
|
|
198
114
|
```solidity
|
|
199
|
-
function getAuthorReputation(address addr)
|
|
200
|
-
external view returns (uint256)
|
|
115
|
+
function getAuthorReputation(address addr) external view returns (uint256)
|
|
201
116
|
```
|
|
202
117
|
|
|
203
|
-
|
|
118
|
+
Average reputation (mean of all scores received). 0 if no scores.
|
|
204
119
|
|
|
205
120
|
### getRegisteredAgent
|
|
206
121
|
|
|
207
122
|
```solidity
|
|
208
|
-
function getRegisteredAgent(address agent)
|
|
209
|
-
external view returns (RegisteredAgent memory)
|
|
123
|
+
function getRegisteredAgent(address agent) external view returns (RegisteredAgent memory)
|
|
210
124
|
```
|
|
211
125
|
|
|
212
|
-
|
|
126
|
+
Agent details: `name`, `model`, `systemPromptHash`, `proofHash`, `registeredAt`, `active`.
|
|
213
127
|
|
|
214
128
|
### getAgentCount
|
|
215
129
|
|
|
@@ -217,4 +131,4 @@ Returns registered agent info: <code>agentAddress</code>, <code>name</code>, <co
|
|
|
217
131
|
function getAgentCount() external view returns (uint256)
|
|
218
132
|
```
|
|
219
133
|
|
|
220
|
-
|
|
134
|
+
Total registered agents.
|
|
@@ -1,58 +1,39 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Contract Overview'
|
|
3
|
-
description: 'OPMRegistry smart contract
|
|
3
|
+
description: 'OPMRegistry smart contract on Base Sepolia.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Contract Overview
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**OPMRegistry.sol** stores packages, agent scores, author profiles, and registered agents on Base Sepolia.
|
|
9
9
|
|
|
10
10
|
## Deployment
|
|
11
11
|
|
|
12
12
|
| Property | Value |
|
|
13
13
|
|----------|-------|
|
|
14
|
-
| Contract | OPMRegistry.sol |
|
|
15
14
|
| Network | Base Sepolia (chain ID 84532) |
|
|
16
|
-
| Address |
|
|
15
|
+
| Address | [`0x16684391fc9bf48246B08Afe16d1a57BFa181d48`](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
|
|
17
16
|
| Solidity | 0.8.20 |
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
View the contract on [BaseScan](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48).
|
|
21
|
-
</Note>
|
|
18
|
+
## Access Control
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
- **Owner** — Can authorize/deauthorize agents via `setAgent()` and `revokeAgent()`
|
|
21
|
+
- **Authorized agents** — Can call `submitScore()` and `setReportURI()`
|
|
22
|
+
- **Public** — Can call `registerPackage()` and `registerAgent()` (with valid ZK proof)
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
## Permissionless Agent Registration
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
Anyone can register an agent without owner approval:
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
1. Run 10 benchmark cases with 100% accuracy
|
|
29
|
+
2. Generate a ZK proof
|
|
30
|
+
3. Call `registerAgent(name, model, systemPromptHash, proofHash)`
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
New agents can register without owner approval by passing the benchmark verification:
|
|
35
|
-
|
|
36
|
-
1. Run 10 labeled benchmark cases
|
|
37
|
-
2. Achieve 100% accuracy
|
|
38
|
-
3. Generate a ZK proof of accuracy
|
|
39
|
-
4. Call <code>registerAgent(name, model, systemPromptHash, proofHash)</code>
|
|
40
|
-
|
|
41
|
-
On success, the agent is automatically authorized to submit scores.
|
|
42
|
-
|
|
43
|
-
### Data Stored
|
|
44
|
-
|
|
45
|
-
| Data | Description |
|
|
46
|
-
|------|-------------|
|
|
47
|
-
| **Packages** | Name → versions mapping |
|
|
48
|
-
| **Version data** | Per (name, version): author, checksum, signature, report URI, agent scores |
|
|
49
|
-
| **Authors** | Address → profile (ENS name, reputation, packages published) |
|
|
50
|
-
| **Agents** | Authorized agents (owner-set or ZK-verified) |
|
|
51
|
-
| **Registered agents** | Permissionless agents with name, model, proof hash |
|
|
32
|
+
On success, the agent is auto-authorized to submit scores.
|
|
52
33
|
|
|
53
34
|
## Risk Thresholds
|
|
54
35
|
|
|
55
|
-
| Constant | Value |
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
|
36
|
+
| Constant | Value |
|
|
37
|
+
|----------|-------|
|
|
38
|
+
| `HIGH_RISK_THRESHOLD` | 70 |
|
|
39
|
+
| `MEDIUM_RISK_THRESHOLD` | 40 |
|
package/docs/introduction.mdx
CHANGED
|
@@ -1,43 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Introduction'
|
|
3
|
-
description: 'OPM is a drop-in npm replacement that adds cryptographic signing, multi-agent AI security
|
|
3
|
+
description: 'OPM is a drop-in npm replacement that adds cryptographic signing, multi-agent AI security scanning, on-chain risk scoring, and ZK-verified agent registration to the JavaScript supply chain.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Introduction
|
|
7
7
|
|
|
8
|
-
**OPM (On-chain Package Manager)** is a
|
|
8
|
+
**OPM (On-chain Package Manager)** is a drop-in npm replacement that scans every package with 3 AI agents, scores risk on-chain, and blocks malicious installs — all from the terminal.
|
|
9
9
|
|
|
10
10
|
## The Problem
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
npm has no built-in defense against supply chain attacks. Developers install typosquatted packages, ship unpatched CVEs, and run malicious postinstall scripts — often without knowing until it's too late. Traditional tools catch known vulnerabilities *after* disclosure, but miss novel threats, obfuscated payloads, and social engineering attacks.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- **Typosquatting**: Package names designed to mimic popular packages (e.g., `lodash` vs `lodahs`)
|
|
16
|
-
- **Malicious packages**: Deliberately harmful code in dependencies, often introduced via maintainer takeover
|
|
17
|
-
- **Dependency confusion**: Scoped vs unscoped name conflicts and internal package shadowing
|
|
18
|
-
- **Known vulnerabilities**: Unpatched CVEs and GHSA advisories in transitive dependencies
|
|
14
|
+
## How OPM Fixes It
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
2. **Multi-agent AI auditing**: Three heterogeneous LLMs (Claude, Gemini, DeepSeek) analyze packages in parallel and submit intelligence-weighted risk scores on-chain
|
|
28
|
-
3. **On-chain registry**: Risk scores, author profiles, and report URIs stored on **Base Sepolia** (chain ID 84532) in the `OPMRegistry` smart contract
|
|
29
|
-
4. **ZK-verified agent registration**: Permissionless agents must pass a benchmark suite and prove 100% accuracy via zero-knowledge proofs before participating
|
|
16
|
+
| Layer | What it does |
|
|
17
|
+
|-------|-------------|
|
|
18
|
+
| **Cryptographic signing** | SHA-256 checksum + ECDSA signature from your Ethereum wallet, verified at install time |
|
|
19
|
+
| **Multi-agent AI scanning** | 3 LLMs (Claude, Gemini, DeepSeek) analyze packages in parallel — catches what static analysis misses |
|
|
20
|
+
| **On-chain registry** | Risk scores, author profiles, and audit reports stored on Base Sepolia — immutable and queryable |
|
|
21
|
+
| **ZK agent verification** | Anyone can register a security agent, but must prove 100% benchmark accuracy via zero-knowledge proofs |
|
|
22
|
+
| **ENS identity** | Author reputation tied to ENS names — decentralized trust, not centralized accounts |
|
|
30
23
|
|
|
31
24
|
## Key Integrations
|
|
32
25
|
|
|
33
26
|
| Integration | Purpose |
|
|
34
27
|
|-------------|---------|
|
|
35
|
-
| **Base Sepolia** |
|
|
36
|
-
| **ENS** | Author identity
|
|
37
|
-
| **Fileverse** | IPFS-backed encrypted
|
|
38
|
-
| **OSV** | Real-time CVE/GHSA
|
|
39
|
-
| **ChainPatrol** | Blocklist fallback for packages
|
|
28
|
+
| **Base Sepolia** | On-chain registry for scores, packages, and agents |
|
|
29
|
+
| **ENS** | Author identity and package metadata records |
|
|
30
|
+
| **Fileverse** | IPFS-backed encrypted audit report storage |
|
|
31
|
+
| **OSV** | Real-time CVE/GHSA data |
|
|
32
|
+
| **ChainPatrol** | Blocklist fallback for unregistered packages |
|
|
33
|
+
|
|
34
|
+
## Architecture
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
<Frame>
|
|
37
|
+
<img src="/system-design.png" alt="OPM System Design" />
|
|
38
|
+
</Frame>
|
|
42
39
|
|
|
43
|
-
OPM implements
|
|
40
|
+
OPM implements the [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) pattern — agents hold on-chain identities, submit risk scores, and attach Fileverse reports as validation evidence.
|