@dzhechkov/harness-core 0.3.119 → 0.3.121

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/src/sign.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  * Zero dependencies: `node:crypto`, `node:fs`, `node:path`.
13
13
  */
14
14
 
15
- import { createHash, sign as cryptoSign, verify as cryptoVerify, createPrivateKey, createPublicKey } from 'node:crypto';
15
+ import { createHash, sign as cryptoSign, verify as cryptoVerify, createPrivateKey, createPublicKey, generateKeyPairSync } from 'node:crypto';
16
16
  import { readFileSync, existsSync, readdirSync, openSync, fstatSync, closeSync, constants as fsConstants } from 'node:fs';
17
17
  import { isAbsolute, join, relative, resolve, sep } from 'node:path';
18
18
 
@@ -159,6 +159,27 @@ export function buildManifest(root: string, pack: string, files: readonly string
159
159
  return { version: MANIFEST_VERSION, pack, files: entries };
160
160
  }
161
161
 
162
+ /** A freshly-generated Ed25519 signing keypair as PEM strings (pkcs8 private / spki public). */
163
+ export interface SigningKeypair {
164
+ /** pkcs8 PEM — the PRIVATE key. NEVER commit this; it belongs OUTSIDE the repo (~/.dz/keys/dz.key). */
165
+ readonly privateKey: string;
166
+ /** spki PEM — the PUBLIC key. Commit this as the `keys/dz.pub` trust root. */
167
+ readonly publicKey: string;
168
+ }
169
+
170
+ /**
171
+ * Generate a fresh Ed25519 keypair for `dz sign --init`. The private key is returned for the CLI to write
172
+ * OUTSIDE the repo (the CLI enforces `assertKeyOutsideTree`); the public key is printed for the operator to
173
+ * commit as `keys/dz.pub`. Ed25519 gives tamper-evidence, never truthfulness (the recalled scope lesson).
174
+ */
175
+ export function generateSigningKeypair(): SigningKeypair {
176
+ const { publicKey, privateKey } = generateKeyPairSync('ed25519');
177
+ return {
178
+ privateKey: privateKey.export({ type: 'pkcs8', format: 'pem' }).toString(),
179
+ publicKey: publicKey.export({ type: 'spki', format: 'pem' }).toString(),
180
+ };
181
+ }
182
+
162
183
  export function signManifest(manifest: Manifest, privateKeyPem: string): SignedManifest {
163
184
  // Defence in depth (round-2 review): `pack` is interpolated into a newline-delimited signed header.
164
185
  // `verifyManifest` already refuses an unsafe pack name, so an ambiguous header could never verify —