spell-runtime 1.1.0 → 1.2.0
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 +11 -2
- package/README.txt +8 -2
- package/dist/cli/index.js +40 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/signature/signing.d.ts +27 -0
- package/dist/signature/signing.js +87 -0
- package/dist/signature/signing.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,6 +47,8 @@ npm run smoke:npx
|
|
|
47
47
|
- `spell list`
|
|
48
48
|
- `spell inspect <id> [--version x.y.z]`
|
|
49
49
|
- `spell cast <id> [--version x.y.z] [-p key=value ...] [--input input.json] [--dry-run] [--yes] [--allow-billing] [--require-signature] [--verbose] [--profile <name>]`
|
|
50
|
+
- `spell sign keygen <publisher> [--key-id default] [--out-dir .spell-keys]`
|
|
51
|
+
- `spell sign bundle <local-path> --private-key <file> [--key-id default] [--publisher <name>]`
|
|
50
52
|
- `spell trust add <publisher> <public-key> [--key-id default]`
|
|
51
53
|
- `spell trust list`
|
|
52
54
|
- `spell trust remove <publisher>`
|
|
@@ -119,13 +121,12 @@ Use these `effect.type` words where possible:
|
|
|
119
121
|
|
|
120
122
|
- name search or ambiguous resolution (id only)
|
|
121
123
|
- registry/marketplace/license verification
|
|
122
|
-
- signature signing UX (keygen/sign commands)
|
|
123
124
|
- real billing execution (Stripe)
|
|
124
125
|
- DAG/parallel/rollback/self-healing
|
|
125
126
|
- advanced templating language (only `{{INPUT.*}}` and `{{ENV.*}}`)
|
|
126
127
|
- docker env passthrough beyond connector tokens
|
|
127
128
|
|
|
128
|
-
## Signature (Verify
|
|
129
|
+
## Signature (Sign + Verify)
|
|
129
130
|
|
|
130
131
|
If a bundle contains `spell.sig.json`, you can require signature verification at execution time:
|
|
131
132
|
|
|
@@ -133,6 +134,14 @@ If a bundle contains `spell.sig.json`, you can require signature verification at
|
|
|
133
134
|
spell cast <id> --require-signature ...
|
|
134
135
|
```
|
|
135
136
|
|
|
137
|
+
Signing flow:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
spell sign keygen samples --key-id default --out-dir .spell-keys
|
|
141
|
+
spell trust add samples <public_key_base64url> --key-id default
|
|
142
|
+
spell sign bundle ./examples/spells/call-webhook --private-key .spell-keys/samples__default.private.pem --key-id default
|
|
143
|
+
```
|
|
144
|
+
|
|
136
145
|
Trust store:
|
|
137
146
|
|
|
138
147
|
- `spell trust add <publisher> <public-key>`
|
package/README.txt
CHANGED
|
@@ -34,6 +34,8 @@ Manual npx (local package):
|
|
|
34
34
|
- spell list
|
|
35
35
|
- spell inspect <id> [--version x.y.z]
|
|
36
36
|
- spell cast <id> [--version x.y.z] [-p key=value ...] [--input input.json] [--dry-run] [--yes] [--allow-billing] [--require-signature] [--verbose] [--profile <name>]
|
|
37
|
+
- spell sign keygen <publisher> [--key-id default] [--out-dir .spell-keys]
|
|
38
|
+
- spell sign bundle <local-path> --private-key <file> [--key-id default] [--publisher <name>]
|
|
37
39
|
- spell trust add <publisher> <public-key> [--key-id default]
|
|
38
40
|
- spell trust list
|
|
39
41
|
- spell trust remove <publisher>
|
|
@@ -94,16 +96,20 @@ Use these effect.type words where possible:
|
|
|
94
96
|
8. v1 limitations (intentionally not implemented)
|
|
95
97
|
- name search or ambiguous resolution (id only)
|
|
96
98
|
- registry/marketplace/license verification
|
|
97
|
-
- signature signing UX (keygen/sign commands)
|
|
98
99
|
- real billing execution (Stripe)
|
|
99
100
|
- DAG/parallel/rollback/self-healing
|
|
100
101
|
- advanced templating language (only {{INPUT.*}} and {{ENV.*}})
|
|
101
102
|
- docker env passthrough beyond connector tokens
|
|
102
103
|
|
|
103
|
-
8.1 Signature (verify
|
|
104
|
+
8.1 Signature (sign + verify)
|
|
104
105
|
If a bundle contains spell.sig.json, you can require signature verification at execution time:
|
|
105
106
|
spell cast <id> --require-signature ...
|
|
106
107
|
|
|
108
|
+
Signing flow:
|
|
109
|
+
spell sign keygen samples --key-id default --out-dir .spell-keys
|
|
110
|
+
spell trust add samples <public_key_base64url> --key-id default
|
|
111
|
+
spell sign bundle ./examples/spells/call-webhook --private-key .spell-keys/samples__default.private.pem --key-id default
|
|
112
|
+
|
|
107
113
|
Trust store:
|
|
108
114
|
- spell trust add <publisher> <public-key>
|
|
109
115
|
- spell trust list
|
package/dist/cli/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
11
11
|
const commander_1 = require("commander");
|
|
12
12
|
const install_1 = require("../bundle/install");
|
|
13
13
|
const store_1 = require("../bundle/store");
|
|
14
|
+
const signing_1 = require("../signature/signing");
|
|
14
15
|
const cast_1 = require("../runner/cast");
|
|
15
16
|
const trustStore_1 = require("../signature/trustStore");
|
|
16
17
|
const errors_1 = require("../util/errors");
|
|
@@ -111,6 +112,45 @@ async function runCli(argv = process.argv) {
|
|
|
111
112
|
process.stdout.write(`execution_id: ${result.executionId}\n`);
|
|
112
113
|
process.stdout.write(`log: ${result.logPath}\n`);
|
|
113
114
|
});
|
|
115
|
+
const signCmd = program.command("sign").description("Create signing keys and sign spell bundles");
|
|
116
|
+
signCmd
|
|
117
|
+
.command("keygen")
|
|
118
|
+
.description("Generate an ed25519 keypair for spell signing")
|
|
119
|
+
.argument("<publisher>", "Publisher (id prefix before first slash)")
|
|
120
|
+
.option("--key-id <id>", "Key id", "default")
|
|
121
|
+
.option("--out-dir <dir>", "Output directory", ".spell-keys")
|
|
122
|
+
.action(async (publisher, options) => {
|
|
123
|
+
const result = await (0, signing_1.generateSigningKeypair)({
|
|
124
|
+
publisher,
|
|
125
|
+
keyId: options.keyId,
|
|
126
|
+
outDir: options.outDir
|
|
127
|
+
});
|
|
128
|
+
process.stdout.write(`publisher: ${result.publisher}\n`);
|
|
129
|
+
process.stdout.write(`key_id: ${result.keyId}\n`);
|
|
130
|
+
process.stdout.write(`private_key: ${result.privateKeyPath}\n`);
|
|
131
|
+
process.stdout.write(`public_key_file: ${result.publicKeyPath}\n`);
|
|
132
|
+
process.stdout.write(`public_key_base64url: ${result.publicKeyBase64Url}\n`);
|
|
133
|
+
process.stdout.write(`trust_add: spell trust add ${result.publisher} ${result.publicKeyBase64Url} --key-id ${result.keyId}\n`);
|
|
134
|
+
});
|
|
135
|
+
signCmd
|
|
136
|
+
.command("bundle")
|
|
137
|
+
.description("Create spell.sig.json for a local spell bundle")
|
|
138
|
+
.argument("<local-path>", "Path to local bundle containing spell.yaml")
|
|
139
|
+
.requiredOption("--private-key <file>", "PKCS#8 private key (PEM)")
|
|
140
|
+
.option("--key-id <id>", "Key id", "default")
|
|
141
|
+
.option("--publisher <name>", "Publisher override (defaults to id prefix)")
|
|
142
|
+
.action(async (localPath, options) => {
|
|
143
|
+
const result = await (0, signing_1.signBundleFromPrivateKey)({
|
|
144
|
+
bundlePath: localPath,
|
|
145
|
+
privateKeyPath: options.privateKey,
|
|
146
|
+
keyId: options.keyId,
|
|
147
|
+
publisher: options.publisher
|
|
148
|
+
});
|
|
149
|
+
process.stdout.write(`signed: ${result.signaturePath}\n`);
|
|
150
|
+
process.stdout.write(`publisher: ${result.publisher}\n`);
|
|
151
|
+
process.stdout.write(`key_id: ${result.keyId}\n`);
|
|
152
|
+
process.stdout.write(`digest: ${result.digestHex}\n`);
|
|
153
|
+
});
|
|
114
154
|
const trust = program.command("trust").description("Manage trusted publisher keys");
|
|
115
155
|
trust
|
|
116
156
|
.command("add")
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface KeygenOptions {
|
|
2
|
+
publisher: string;
|
|
3
|
+
keyId: string;
|
|
4
|
+
outDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface KeygenResult {
|
|
7
|
+
publisher: string;
|
|
8
|
+
keyId: string;
|
|
9
|
+
privateKeyPath: string;
|
|
10
|
+
publicKeyPath: string;
|
|
11
|
+
publicKeyBase64Url: string;
|
|
12
|
+
}
|
|
13
|
+
interface SignBundleOptions {
|
|
14
|
+
bundlePath: string;
|
|
15
|
+
privateKeyPath: string;
|
|
16
|
+
keyId: string;
|
|
17
|
+
publisher?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SignBundleResult {
|
|
20
|
+
signaturePath: string;
|
|
21
|
+
digestHex: string;
|
|
22
|
+
publisher: string;
|
|
23
|
+
keyId: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function generateSigningKeypair(options: KeygenOptions): Promise<KeygenResult>;
|
|
26
|
+
export declare function signBundleFromPrivateKey(options: SignBundleOptions): Promise<SignBundleResult>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateSigningKeypair = generateSigningKeypair;
|
|
7
|
+
exports.signBundleFromPrivateKey = signBundleFromPrivateKey;
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const manifest_1 = require("../bundle/manifest");
|
|
12
|
+
const errors_1 = require("../util/errors");
|
|
13
|
+
const idKey_1 = require("../util/idKey");
|
|
14
|
+
const bundleDigest_1 = require("./bundleDigest");
|
|
15
|
+
const trustStore_1 = require("./trustStore");
|
|
16
|
+
async function generateSigningKeypair(options) {
|
|
17
|
+
validateSimpleToken(options.publisher, "publisher");
|
|
18
|
+
validateSimpleToken(options.keyId, "key id");
|
|
19
|
+
const outDir = node_path_1.default.resolve(options.outDir);
|
|
20
|
+
const safePublisher = (0, idKey_1.sanitizeIdForFilename)(options.publisher);
|
|
21
|
+
const safeKeyId = (0, idKey_1.sanitizeIdForFilename)(options.keyId);
|
|
22
|
+
await (0, promises_1.mkdir)(outDir, { recursive: true });
|
|
23
|
+
const privateKeyPath = node_path_1.default.join(outDir, `${safePublisher}__${safeKeyId}.private.pem`);
|
|
24
|
+
const publicKeyPath = node_path_1.default.join(outDir, `${safePublisher}__${safeKeyId}.public.b64url.txt`);
|
|
25
|
+
const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)("ed25519");
|
|
26
|
+
const publicDer = publicKey.export({ format: "der", type: "spki" });
|
|
27
|
+
const privatePem = privateKey.export({ format: "pem", type: "pkcs8" });
|
|
28
|
+
await (0, promises_1.writeFile)(privateKeyPath, privatePem, { encoding: "utf8", mode: 0o600 });
|
|
29
|
+
await (0, promises_1.writeFile)(publicKeyPath, `${publicDer.toString("base64url")}\n`, "utf8");
|
|
30
|
+
return {
|
|
31
|
+
publisher: options.publisher,
|
|
32
|
+
keyId: options.keyId,
|
|
33
|
+
privateKeyPath,
|
|
34
|
+
publicKeyPath,
|
|
35
|
+
publicKeyBase64Url: publicDer.toString("base64url")
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function signBundleFromPrivateKey(options) {
|
|
39
|
+
validateSimpleToken(options.keyId, "key id");
|
|
40
|
+
const bundlePath = node_path_1.default.resolve(options.bundlePath);
|
|
41
|
+
const { manifest } = await (0, manifest_1.loadManifestFromDir)(bundlePath);
|
|
42
|
+
const derivedPublisher = (0, trustStore_1.publisherFromId)(manifest.id);
|
|
43
|
+
const publisher = options.publisher?.trim() || derivedPublisher;
|
|
44
|
+
if (publisher !== derivedPublisher) {
|
|
45
|
+
throw new errors_1.SpellError(`publisher mismatch: manifest expects '${derivedPublisher}', got '${publisher}'`);
|
|
46
|
+
}
|
|
47
|
+
const privateKeyRaw = await (0, promises_1.readFile)(node_path_1.default.resolve(options.privateKeyPath), "utf8").catch(() => {
|
|
48
|
+
throw new errors_1.SpellError(`private key file not found: ${options.privateKeyPath}`);
|
|
49
|
+
});
|
|
50
|
+
let privateKey;
|
|
51
|
+
try {
|
|
52
|
+
privateKey = (0, node_crypto_1.createPrivateKey)(privateKeyRaw);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new errors_1.SpellError(`failed to parse private key: ${error.message}`);
|
|
56
|
+
}
|
|
57
|
+
const digest = await (0, bundleDigest_1.computeBundleDigest)(bundlePath);
|
|
58
|
+
const signature = (0, node_crypto_1.sign)(null, digest.value, privateKey).toString("base64url");
|
|
59
|
+
const signaturePath = node_path_1.default.join(bundlePath, "spell.sig.json");
|
|
60
|
+
const payload = {
|
|
61
|
+
version: "v1",
|
|
62
|
+
publisher,
|
|
63
|
+
key_id: options.keyId,
|
|
64
|
+
algorithm: "ed25519",
|
|
65
|
+
digest: {
|
|
66
|
+
algorithm: "sha256",
|
|
67
|
+
value: digest.valueHex
|
|
68
|
+
},
|
|
69
|
+
signature
|
|
70
|
+
};
|
|
71
|
+
await (0, promises_1.writeFile)(signaturePath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
72
|
+
return {
|
|
73
|
+
signaturePath,
|
|
74
|
+
digestHex: digest.valueHex,
|
|
75
|
+
publisher,
|
|
76
|
+
keyId: options.keyId
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function validateSimpleToken(value, label) {
|
|
80
|
+
if (!value || !value.trim()) {
|
|
81
|
+
throw new errors_1.SpellError(`${label} must not be empty`);
|
|
82
|
+
}
|
|
83
|
+
if (/[\x00-\x1F\x7F]/.test(value)) {
|
|
84
|
+
throw new errors_1.SpellError(`${label} must not contain control characters`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/signature/signing.ts"],"names":[],"mappings":"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"}
|