@parmanasystems/verifier-cli 1.0.19
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/README.md +107 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +200 -0
- package/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @parmanasystems/verifier-cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for offline parmanasystems attestation verification.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@parmanasystems/verifier-cli)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`@parmanasystems/verifier-cli` is a standalone CLI tool for verifying governance artifacts outside the production runtime. It reads a public key from `./dev-keys/bundle_signing_key.pub` and performs cryptographic verification of attestations, release manifests, and runtime manifests.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @parmanasystems/verifier-cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or run without installing via:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @parmanasystems/verifier-cli <command> <file>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
|
|
31
|
+
The CLI reads the signing public key from:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
./dev-keys/bundle_signing_key.pub
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This path is relative to your current working directory. Generate or copy your public key there before running verification commands.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Commands
|
|
42
|
+
|
|
43
|
+
### `verify-attestation <file>`
|
|
44
|
+
|
|
45
|
+
Verifies the cryptographic signature of a governance attestation.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
parmanasystems-verifier-cli verify-attestation ./attestation.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The attestation file must contain `decision`, `policyVersion`, `timestamp`, and `signature` fields.
|
|
52
|
+
|
|
53
|
+
### `verify-release <file>`
|
|
54
|
+
|
|
55
|
+
Verifies the cryptographic signature of a release manifest.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
parmanasystems-verifier-cli verify-release ./release-manifest.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The release manifest must contain `version`, `artifacts`, and `signature` fields.
|
|
62
|
+
|
|
63
|
+
### `verify-runtime <file>`
|
|
64
|
+
|
|
65
|
+
Verifies the cryptographic signature of a runtime manifest.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
parmanasystems-verifier-cli verify-runtime ./runtime-manifest.json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The runtime manifest must contain `runtime`, `version`, `compatibility`, and `signature` fields.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Unknown commands
|
|
76
|
+
|
|
77
|
+
Passing an unrecognised command name logs `"Unknown command."` and exits. There is no built-in help flag — refer to this README for the full command list.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Exit codes
|
|
82
|
+
|
|
83
|
+
| Code | Meaning |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `0` | Verification succeeded |
|
|
86
|
+
| `1` | Verification failed, file not found, or malformed input |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Example
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
$ parmanasystems-verifier-cli verify-attestation ./governance/attestation.json
|
|
94
|
+
|
|
95
|
+
parmanasystems Verifier CLI
|
|
96
|
+
|
|
97
|
+
ATTESTATION:
|
|
98
|
+
{ decision: 'approve', policyVersion: 'v1', timestamp: '...', signature: '...' }
|
|
99
|
+
|
|
100
|
+
Cryptographic attestation verification succeeded.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
Apache-2.0
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import {
|
|
6
|
+
LocalVerifier,
|
|
7
|
+
canonicalize
|
|
8
|
+
} from "@parmanasystems/core";
|
|
9
|
+
async function main() {
|
|
10
|
+
console.log("");
|
|
11
|
+
console.log("parmanasystems Verifier CLI");
|
|
12
|
+
console.log("");
|
|
13
|
+
const publicKey = fs.readFileSync(
|
|
14
|
+
"./dev-keys/bundle_signing_key.pub",
|
|
15
|
+
"utf8"
|
|
16
|
+
);
|
|
17
|
+
const verifier = new LocalVerifier(publicKey);
|
|
18
|
+
const command = process.argv[2];
|
|
19
|
+
switch (command) {
|
|
20
|
+
case "verify-attestation": {
|
|
21
|
+
const file = process.argv[3];
|
|
22
|
+
if (!file) {
|
|
23
|
+
console.log(
|
|
24
|
+
"Usage: parmanasystems-verifier verify-attestation <file>"
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
if (!fs.existsSync(file)) {
|
|
29
|
+
console.log("Attestation file not found.");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const content = fs.readFileSync(file, "utf8");
|
|
34
|
+
const parsed = JSON.parse(content);
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log("ATTESTATION:");
|
|
37
|
+
console.log(parsed);
|
|
38
|
+
if (!parsed.decision || !parsed.policyVersion || !parsed.signature) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"Invalid attestation structure."
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
if (typeof parsed.signature !== "string") {
|
|
44
|
+
throw new Error(
|
|
45
|
+
"Invalid attestation signature."
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const payload = {
|
|
49
|
+
decision: parsed.decision,
|
|
50
|
+
policyVersion: parsed.policyVersion,
|
|
51
|
+
timestamp: parsed.timestamp
|
|
52
|
+
};
|
|
53
|
+
const verified = await verifier.verify(
|
|
54
|
+
canonicalize(payload),
|
|
55
|
+
parsed.signature
|
|
56
|
+
);
|
|
57
|
+
if (!verified) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
"Cryptographic signature verification failed."
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
console.log("");
|
|
63
|
+
console.log(
|
|
64
|
+
"Cryptographic attestation verification succeeded."
|
|
65
|
+
);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.log("");
|
|
68
|
+
console.log(
|
|
69
|
+
"Attestation verification failed."
|
|
70
|
+
);
|
|
71
|
+
console.log(
|
|
72
|
+
err instanceof Error ? err.message : String(err)
|
|
73
|
+
);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case "verify-release": {
|
|
79
|
+
const file = process.argv[3];
|
|
80
|
+
if (!file) {
|
|
81
|
+
console.log(
|
|
82
|
+
"Usage: parmanasystems-verifier verify-release <file>"
|
|
83
|
+
);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
if (!fs.existsSync(file)) {
|
|
87
|
+
console.log("Release manifest file not found.");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const content = fs.readFileSync(file, "utf8");
|
|
92
|
+
const parsed = JSON.parse(content);
|
|
93
|
+
console.log("");
|
|
94
|
+
console.log("RELEASE:");
|
|
95
|
+
console.log(parsed);
|
|
96
|
+
if (!parsed.version || !parsed.artifacts || !parsed.signature) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
"Invalid release manifest."
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
if (typeof parsed.signature !== "string") {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"Invalid release signature."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
const payload = {
|
|
107
|
+
version: parsed.version,
|
|
108
|
+
artifacts: parsed.artifacts
|
|
109
|
+
};
|
|
110
|
+
const verified = await verifier.verify(
|
|
111
|
+
canonicalize(payload),
|
|
112
|
+
parsed.signature
|
|
113
|
+
);
|
|
114
|
+
if (!verified) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
"Cryptographic release verification failed."
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
console.log("");
|
|
120
|
+
console.log(
|
|
121
|
+
"Cryptographic release verification succeeded."
|
|
122
|
+
);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.log("");
|
|
125
|
+
console.log(
|
|
126
|
+
"Release verification failed."
|
|
127
|
+
);
|
|
128
|
+
console.log(
|
|
129
|
+
err instanceof Error ? err.message : String(err)
|
|
130
|
+
);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "verify-runtime": {
|
|
136
|
+
const file = process.argv[3];
|
|
137
|
+
if (!file) {
|
|
138
|
+
console.log(
|
|
139
|
+
"Usage: parmanasystems-verifier verify-runtime <file>"
|
|
140
|
+
);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
if (!fs.existsSync(file)) {
|
|
144
|
+
console.log("Runtime manifest file not found.");
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const content = fs.readFileSync(file, "utf8");
|
|
149
|
+
const parsed = JSON.parse(content);
|
|
150
|
+
console.log("");
|
|
151
|
+
console.log("RUNTIME:");
|
|
152
|
+
console.log(parsed);
|
|
153
|
+
if (!parsed.runtime || !parsed.version || !parsed.compatibility || !parsed.signature) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
"Invalid runtime manifest."
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (typeof parsed.signature !== "string") {
|
|
159
|
+
throw new Error(
|
|
160
|
+
"Invalid runtime signature."
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
const payload = {
|
|
164
|
+
runtime: parsed.runtime,
|
|
165
|
+
version: parsed.version,
|
|
166
|
+
compatibility: parsed.compatibility
|
|
167
|
+
};
|
|
168
|
+
const verified = await verifier.verify(
|
|
169
|
+
canonicalize(payload),
|
|
170
|
+
parsed.signature
|
|
171
|
+
);
|
|
172
|
+
if (!verified) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
"Cryptographic runtime verification failed."
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
console.log("");
|
|
178
|
+
console.log(
|
|
179
|
+
"Cryptographic runtime verification succeeded."
|
|
180
|
+
);
|
|
181
|
+
} catch (err) {
|
|
182
|
+
console.log("");
|
|
183
|
+
console.log(
|
|
184
|
+
"Runtime verification failed."
|
|
185
|
+
);
|
|
186
|
+
console.log(
|
|
187
|
+
err instanceof Error ? err.message : String(err)
|
|
188
|
+
);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
default:
|
|
194
|
+
console.log("Unknown command.");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
main().catch((err) => {
|
|
198
|
+
console.error(err);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@parmanasystems/verifier-cli",
|
|
3
|
+
"version": "1.0.19",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"parmanasystems-verifier-cli": "./dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup src/index.ts --format esm --dts"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@parmanasystems/core": "^1.0.19"
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|