@gbuerk/gcrypt 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gavin Buerk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # @gbuerk/gcrypt
2
+
3
+ Store encrypted, signed `.env` and JSON configuration in Git. `gcrypt` uses
4
+ [age](https://age-encryption.org/) encryption and Node.js cryptography, so it
5
+ does not require an installed `age` binary.
6
+
7
+ Each team member has a decryption key and a signing key. A listed maintainer
8
+ must sign every version before `gcrypt` will decrypt or change it.
9
+
10
+ ## Requirements
11
+
12
+ - Node.js 22.13 or later (Node 23 requires 23.5 or later)
13
+ - A Git repository for the encrypted configuration file
14
+
15
+ ## Install
16
+
17
+ Install `gcrypt` in the project that owns the configuration:
18
+
19
+ ```bash
20
+ npm install --save-dev @gbuerk/gcrypt
21
+ npx gcrypt init
22
+ ```
23
+
24
+ `init` creates `.env.dev.enc`, adds helper scripts to `package.json`, and
25
+ wraps the existing `dev` script. It asks before replacing any existing scripts.
26
+ It also creates an empty `.env.example` when one does not exist.
27
+
28
+ The private keys are stored locally at:
29
+
30
+ ```text
31
+ ~/.config/gcrypt/keys/default.txt
32
+ ~/.config/gcrypt/signing/default.txt
33
+ ```
34
+
35
+ Never commit, share, or copy these private keys. Add the generated
36
+ `.env.dev.enc` to Git; it contains encrypted values and public team metadata.
37
+
38
+ ## Team workflow
39
+
40
+ ### 1. Set up a new member
41
+
42
+ Each developer runs this once from the project:
43
+
44
+ ```bash
45
+ npm run dev:setup
46
+ ```
47
+
48
+ The command prints a versioned member setup code. Send that code and a stable,
49
+ human-readable member ID, such as `alice-smith`, to a maintainer. The setup
50
+ code contains only public keys.
51
+
52
+ ### 2. Grant access
53
+
54
+ A maintainer grants the new member access, then commits the changed encrypted
55
+ file:
56
+
57
+ ```bash
58
+ npm run secrets:grant -- .env.dev.enc
59
+ ```
60
+
61
+ ### 3. Edit configuration
62
+
63
+ Listed maintainers edit a file using the editor named by `VISUAL` or `EDITOR`:
64
+
65
+ ```bash
66
+ export EDITOR=vim
67
+ npm run secrets -- .env.dev.enc
68
+ ```
69
+
70
+ `gcrypt` verifies maintainer approval before it writes a temporary plaintext
71
+ file. It re-encrypts all values and signs the updated document after editing.
72
+
73
+ ### 4. Run the application
74
+
75
+ After `gcrypt init`, use the normal development command:
76
+
77
+ ```bash
78
+ npm run dev
79
+ ```
80
+
81
+ The decrypted dotenv values exist only in the environment of the application
82
+ child process.
83
+
84
+ ## Access management
85
+
86
+ Remove a member's full access and re-encrypt every value for the remaining
87
+ members:
88
+
89
+ ```bash
90
+ npm run secrets:revoke -- .env.dev.enc
91
+ ```
92
+
93
+ To retain decryption access but remove approval rights, demote the member:
94
+
95
+ ```bash
96
+ npm run secrets:maintainer:revoke -- .env.dev.enc
97
+ ```
98
+
99
+ Promote an existing member to maintainer:
100
+
101
+ ```bash
102
+ npm run secrets:maintainer:grant -- .env.dev.enc
103
+ ```
104
+
105
+ Verify signatures and metadata without decrypting:
106
+
107
+ ```bash
108
+ npm run secrets:verify -- .env.dev.enc
109
+ ```
110
+
111
+ Removing a recipient protects future versions only. Rotate any credentials the
112
+ former member may already know.
113
+
114
+ ## JSON files
115
+
116
+ Create a JSON configuration file by using a `.json.enc` name:
117
+
118
+ ```bash
119
+ npx gcrypt secrets init config.json.enc
120
+ ```
121
+
122
+ JSON documents support top-level scalar values: strings, numbers, booleans,
123
+ and `null`. Nested objects and arrays are not supported.
124
+
125
+ ## Commands
126
+
127
+ ```text
128
+ gcrypt init [file] Initialize a project and encrypted dotenv file
129
+ gcrypt setup Create or show the local member setup code
130
+ gcrypt grant [file] Add a member from their setup code
131
+ gcrypt revoke [file] Remove a member's access
132
+ gcrypt maintainer grant [file] Give an existing member approval rights
133
+ gcrypt maintainer revoke [file] Remove an existing member's approval rights
134
+ gcrypt verify [file] Verify without decrypting
135
+ gcrypt decrypt [file] Print plaintext to standard output
136
+ gcrypt edit [file] Edit and re-encrypt a file
137
+ gcrypt exec <file> -- <command> Run a command with decrypted dotenv values
138
+ gcrypt secrets init [file] Create an encrypted dotenv or JSON file
139
+ ```
140
+
141
+ When the file argument is omitted in an interactive terminal, `gcrypt` offers
142
+ encrypted files found below the current directory.
143
+
144
+ ## Security model
145
+
146
+ - Values are encrypted independently for all current recipients using age
147
+ X25519 recipients.
148
+ - Document metadata and encrypted values are signed with Ed25519 keys.
149
+ - Any listed maintainer may approve a version; at least one valid maintainer
150
+ signature is required.
151
+ - Public member IDs, recipients, signing keys, and roles are stored in the
152
+ encrypted file's metadata so the team can review access changes in Git.
153
+
154
+ `gcrypt` does not protect secrets that have already been decrypted, copied, or
155
+ committed in prior Git history. Use normal credential rotation and access
156
+ controls alongside this tool.
157
+
158
+ ## Publishing
159
+
160
+ This repository does not commit `dist/`. `npm pack` and `npm publish` run the
161
+ TypeScript build through the `prepack` lifecycle script, and the package ships
162
+ only the generated `dist/` directory plus standard npm files such as this
163
+ README and the license.
164
+
165
+ ## License
166
+
167
+ [MIT](LICENSE)
@@ -0,0 +1,49 @@
1
+ import { type DocumentMember } from './document.js';
2
+ export declare const managedFileWarning = "Do not manually edit this file. Use gcrypt instead.";
3
+ export interface ChangePrompt {
4
+ memberId?: () => Promise<string>;
5
+ memberSetupCode?: () => Promise<string>;
6
+ }
7
+ export interface CommandOptions {
8
+ homeDirectory?: string;
9
+ prompt: ChangePrompt;
10
+ }
11
+ export interface SetupOptions {
12
+ homeDirectory?: string;
13
+ /** @deprecated Identities are now created automatically. */
14
+ prompt?: {
15
+ confirm(): Promise<boolean>;
16
+ };
17
+ }
18
+ export interface SetupResult {
19
+ age: AgeSetupResult;
20
+ signing: SigningSetupResult;
21
+ memberSetupCode: string;
22
+ }
23
+ export interface AgeSetupResult {
24
+ created: boolean;
25
+ path: string;
26
+ recipient: string;
27
+ }
28
+ export interface SigningSetupResult {
29
+ created: boolean;
30
+ path: string;
31
+ publicKey: string;
32
+ }
33
+ export interface InitialDocumentOptions {
34
+ homeDirectory?: string;
35
+ members?: DocumentMember[];
36
+ memberId?: string;
37
+ }
38
+ export declare function maintainerSetup({ homeDirectory }?: SetupOptions): Promise<SigningSetupResult>;
39
+ export declare function setup(options?: SetupOptions): Promise<SetupResult>;
40
+ export declare function grantRecipient(filePath: string, options: CommandOptions): Promise<void>;
41
+ export declare function revokeRecipient(filePath: string, options: CommandOptions): Promise<void>;
42
+ export declare function grantMaintainer(filePath: string, options: CommandOptions): Promise<void>;
43
+ export declare function revokeMaintainer(filePath: string, options: CommandOptions): Promise<void>;
44
+ /** Create a new signed encrypted dotenv or JSON document from plaintext input. */
45
+ export declare function createEncryptedDocument(filePath: string, plaintext: string, options?: InitialDocumentOptions): Promise<void>;
46
+ export declare function verifyEncryptedDocument(filePath: string): Promise<void>;
47
+ export declare function decryptEncryptedDocument(filePath: string, homeDirectory?: string): Promise<string>;
48
+ export declare function editEncryptedDocument(filePath: string, editor: string, homeDirectory?: string): Promise<void>;
49
+ export declare function executeDotenv(filePath: string, command: string[], homeDirectory?: string): Promise<number>;
@@ -0,0 +1,333 @@
1
+ import { mkdtemp, readFile, rename, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { basename, dirname, join } from 'node:path';
4
+ import { spawn } from 'node:child_process';
5
+ import { parse as parseDotenv } from 'dotenv';
6
+ import { ageRecipientForIdentity, decryptValue, encryptValue, generateAgeIdentity, generateSigningIdentity, signDocument, signingPublicKeyForIdentity, validateSigningPublicKey, verifyDocument, } from './crypto.js';
7
+ import { canonicalSigningData, parseEncryptedDocument, renderEncryptedDocument, } from './document.js';
8
+ import { defaultAgeIdentityPath, defaultSigningIdentityPath, readDefaultAgeIdentity, readDefaultSigningIdentity, writeDefaultAgeIdentity, writeDefaultSigningIdentity, } from './key-storage.js';
9
+ import { decodeMemberSetupCode, encodeMemberSetupCode } from './member-setup-code.js';
10
+ export const managedFileWarning = 'Do not manually edit this file. Use gcrypt instead.';
11
+ async function ageSetup({ homeDirectory } = {}) {
12
+ try {
13
+ const identity = await readDefaultAgeIdentity(homeDirectory);
14
+ return { created: false, path: defaultAgeIdentityPath(homeDirectory), recipient: await ageRecipientForIdentity(identity) };
15
+ }
16
+ catch (error) {
17
+ if (!isMissingFile(error))
18
+ throw error;
19
+ }
20
+ const identity = await generateAgeIdentity();
21
+ return { created: true, path: await writeDefaultAgeIdentity(identity.identity, homeDirectory), recipient: identity.recipient };
22
+ }
23
+ export async function maintainerSetup({ homeDirectory } = {}) {
24
+ try {
25
+ const privateKey = await readDefaultSigningIdentity(homeDirectory);
26
+ return { created: false, path: defaultSigningIdentityPath(homeDirectory), publicKey: signingPublicKeyForIdentity(privateKey) };
27
+ }
28
+ catch (error) {
29
+ if (!isMissingFile(error))
30
+ throw error;
31
+ }
32
+ const identity = generateSigningIdentity();
33
+ return { created: true, path: await writeDefaultSigningIdentity(identity.privateKey, homeDirectory), publicKey: identity.publicKey };
34
+ }
35
+ export async function setup(options = {}) {
36
+ const [age, signing] = await Promise.all([ageSetup(options), maintainerSetup(options)]);
37
+ return { age, signing, memberSetupCode: encodeMemberSetupCode({ recipient: age.recipient, signingKey: signing.publicKey }) };
38
+ }
39
+ export async function grantRecipient(filePath, options) {
40
+ const memberId = await requested(options.prompt.memberId, 'member ID');
41
+ validateMemberId(memberId);
42
+ const { recipient, signingKey } = decodeMemberSetupCode(await requested(options.prompt.memberSetupCode, 'member setup code'));
43
+ await changeMembers(filePath, options, (members) => {
44
+ if (members.some((member) => member.id === memberId))
45
+ throw new Error('Member ID is already listed');
46
+ if (members.some((member) => member.recipient === recipient))
47
+ throw new Error('This access key is already assigned to a member');
48
+ if (members.some((member) => member.signingKey === signingKey))
49
+ throw new Error('Signing key is already listed');
50
+ return [...members, { id: memberId, recipient, signingKey, isMaintainer: false }];
51
+ });
52
+ }
53
+ export async function revokeRecipient(filePath, options) {
54
+ const memberId = await requested(options.prompt.memberId, 'member ID');
55
+ await changeMembers(filePath, options, (members) => {
56
+ const member = members.find((candidate) => candidate.id === memberId);
57
+ if (!member)
58
+ throw new Error('Member ID is not listed');
59
+ if (members.length === 1)
60
+ throw new Error('Cannot remove the final recipient');
61
+ if (member.isMaintainer && members.filter((candidate) => candidate.isMaintainer).length === 1)
62
+ throw new Error('Cannot remove the final maintainer');
63
+ return members.filter((candidate) => candidate.id !== memberId);
64
+ });
65
+ }
66
+ export async function grantMaintainer(filePath, options) {
67
+ const memberId = await requested(options.prompt.memberId, 'member ID');
68
+ await changeMembers(filePath, options, (members) => {
69
+ const member = members.find((candidate) => candidate.id === memberId);
70
+ if (!member)
71
+ throw new Error('Member ID is not listed');
72
+ if (member.isMaintainer)
73
+ throw new Error('Member is already a maintainer');
74
+ return members.map((candidate) => candidate.id === memberId ? { ...candidate, isMaintainer: true } : candidate);
75
+ });
76
+ }
77
+ export async function revokeMaintainer(filePath, options) {
78
+ const memberId = await requested(options.prompt.memberId, 'member ID');
79
+ await changeMembers(filePath, options, (members) => {
80
+ const member = members.find((candidate) => candidate.id === memberId);
81
+ if (!member)
82
+ throw new Error('Member ID is not listed');
83
+ if (!member.isMaintainer)
84
+ throw new Error('Member is not a maintainer');
85
+ if (members.filter((member) => member.isMaintainer).length === 1)
86
+ throw new Error('Cannot remove the final maintainer');
87
+ return members.map((candidate) => candidate.id === memberId ? { ...candidate, isMaintainer: false } : candidate);
88
+ });
89
+ }
90
+ /** Create a new signed encrypted dotenv or JSON document from plaintext input. */
91
+ export async function createEncryptedDocument(filePath, plaintext, options = {}) {
92
+ const identity = await readDefaultAgeIdentity(options.homeDirectory);
93
+ const privateKey = await readDefaultSigningIdentity(options.homeDirectory);
94
+ const publicKey = signingPublicKeyForIdentity(privateKey);
95
+ const members = options.members ?? [{ id: options.memberId ?? 'local', recipient: await ageRecipientForIdentity(identity), signingKey: publicKey, isMaintainer: true }];
96
+ const metadata = metadataForMembers(members);
97
+ const format = filePath.endsWith('.json.enc') || filePath.endsWith('.json') ? 'json' : 'dotenv';
98
+ const source = format === 'json'
99
+ ? await encryptJson(plaintext, metadata)
100
+ : await encryptDotenv(plaintext, metadata);
101
+ const document = parseEncryptedDocument(source, format);
102
+ const signature = signDocument(canonicalSigningData(document), privateKey);
103
+ await atomicWrite(filePath, renderMetadata(source, format, { ...document.metadata, signatures: [`${publicKey}:${signature}`] }));
104
+ }
105
+ export async function verifyEncryptedDocument(filePath) {
106
+ await loadVerifiedDocument(filePath);
107
+ }
108
+ export async function decryptEncryptedDocument(filePath, homeDirectory) {
109
+ const { document } = await loadVerifiedDocument(filePath);
110
+ const identity = await readDefaultAgeIdentity(homeDirectory);
111
+ return decryptParsedDocument(document, identity);
112
+ }
113
+ async function decryptParsedDocument(document, identity) {
114
+ const values = await Promise.all(document.values.map(({ marker }) => decryptValue(marker, identity)));
115
+ if (document.format === 'dotenv')
116
+ return document.values.map(({ key }, index) => `${key}=${values[index]}`).join('\n') + (values.length ? '\n' : '');
117
+ const decrypted = Object.fromEntries(document.values.map(({ key }, index) => [key, parseJsonScalar(values[index])]));
118
+ return `${JSON.stringify(decrypted, undefined, 2)}\n`;
119
+ }
120
+ export async function editEncryptedDocument(filePath, editor, homeDirectory) {
121
+ // Editing must be authorized before a plaintext temporary file is created.
122
+ const authorized = await loadAuthorizedDocument(filePath, homeDirectory);
123
+ const plaintext = await decryptParsedDocument(authorized.document, authorized.identity);
124
+ const directory = await mkdtemp(join(tmpdir(), 'gcrypt-edit-'));
125
+ const temporaryFile = join(directory, basename(filePath).replace(/\.enc$/u, ''));
126
+ try {
127
+ await writeFile(temporaryFile, plaintext, { encoding: 'utf8', mode: 0o600 });
128
+ const [command, ...arguments_] = editor.trim().split(/\s+/u);
129
+ if (!command)
130
+ throw new Error('An editor is required');
131
+ const result = await new Promise((resolve, reject) => {
132
+ const child = spawn(command, [...arguments_, temporaryFile], { stdio: 'inherit' });
133
+ child.once('error', reject);
134
+ child.once('exit', resolve);
135
+ });
136
+ if (result !== 0)
137
+ throw new Error(`Editor exited with status ${result ?? 'unknown'}`);
138
+ const updated = await readFile(temporaryFile, 'utf8');
139
+ await createEncryptedDocument(filePath, updated, {
140
+ homeDirectory,
141
+ members: authorized.document.metadata.members,
142
+ });
143
+ }
144
+ finally {
145
+ await rm(directory, { force: true, recursive: true });
146
+ }
147
+ }
148
+ export async function executeDotenv(filePath, command, homeDirectory) {
149
+ if (command.length === 0)
150
+ throw new Error('A command after -- is required');
151
+ const { document } = await loadVerifiedDocument(filePath);
152
+ if (document.format !== 'dotenv')
153
+ throw new Error('exec supports dotenv files only');
154
+ const identity = await readDefaultAgeIdentity(homeDirectory);
155
+ const environment = parseDotenv(await decryptParsedDocument(document, identity));
156
+ return new Promise((resolve, reject) => {
157
+ const child = spawn(command[0], command.slice(1), { stdio: 'inherit', env: { ...process.env, ...environment } });
158
+ child.once('error', reject);
159
+ child.once('exit', (code) => resolve(code ?? 1));
160
+ });
161
+ }
162
+ async function changeMembers(filePath, options, update) {
163
+ const { source, document, format, identity, privateKey, publicKey } = await loadAuthorizedDocument(filePath, options.homeDirectory);
164
+ const metadata = metadataForMembers(update(document.metadata.members));
165
+ const plaintextValues = await Promise.all(document.values.map(({ marker }) => decryptValue(marker, identity)));
166
+ const markers = await Promise.all(plaintextValues.map((value) => encryptValue(value, metadata.recipients)));
167
+ await writeSignedDocument(filePath, source, document, format, { ...metadata, signatures: document.metadata.signatures }, markers, privateKey, publicKey);
168
+ }
169
+ async function loadAuthorizedDocument(filePath, homeDirectory) {
170
+ const { source, format, document } = await loadVerifiedDocument(filePath);
171
+ const identity = await readDefaultAgeIdentity(homeDirectory);
172
+ const privateKey = await readDefaultSigningIdentity(homeDirectory);
173
+ const publicKey = signingPublicKeyForIdentity(privateKey);
174
+ if (!document.metadata.maintainers.includes(publicKey))
175
+ throw new Error('Local signing identity is not a listed maintainer');
176
+ return { source, document, format, identity, privateKey, publicKey };
177
+ }
178
+ async function writeSignedDocument(filePath, source, document, format, metadata, markers, privateKey, publicKey) {
179
+ const updated = { ...document, metadata, values: document.values.map((value, index) => ({ ...value, marker: markers[index] })) };
180
+ const signature = signDocument(canonicalSigningData(updated), privateKey);
181
+ const signedMetadata = { ...metadata, signatures: [`${publicKey}:${signature}`] };
182
+ const renderedValues = renderEncryptedDocument(document, markers);
183
+ await atomicWrite(filePath, renderMetadata(renderedValues, format, signedMetadata));
184
+ }
185
+ async function loadDocument(filePath) {
186
+ const source = await readFile(filePath, 'utf8');
187
+ const format = source.trimStart().startsWith('{') ? 'json' : 'dotenv';
188
+ return { source, format, document: parseEncryptedDocument(source, format) };
189
+ }
190
+ async function loadVerifiedDocument(filePath) {
191
+ const loaded = await loadDocument(filePath);
192
+ validateMaintainers(loaded.document);
193
+ if (!hasValidSignature(loaded.document))
194
+ throw new Error('Document does not have a valid maintainer signature');
195
+ return loaded;
196
+ }
197
+ async function encryptDotenv(plaintext, metadata) {
198
+ const values = parseDotenv(plaintext);
199
+ const lines = await Promise.all(Object.entries(values).map(async ([key, value]) => `${key}=${await encryptValue(value, metadata.recipients)}`));
200
+ return `# WARNING: ${managedFileWarning}\n# gcrypt: 2\n# gcrypt-recipients: ${metadata.recipients.join(',')}\n# gcrypt-maintainers: ${metadata.maintainers.join(',')}\n${metadata.members.map(renderDotenvMember).join('\n')}\n# gcrypt-signature: pending\n\n${lines.join('\n')}\n`;
201
+ }
202
+ async function encryptJson(plaintext, metadata) {
203
+ let values;
204
+ try {
205
+ values = JSON.parse(plaintext);
206
+ }
207
+ catch {
208
+ throw new Error('Invalid JSON document');
209
+ }
210
+ if (typeof values !== 'object' || values === null || Array.isArray(values) || Object.hasOwn(values, '$gcrypt'))
211
+ throw new Error('JSON document must be a top-level object without $gcrypt');
212
+ const encrypted = { $gcrypt: { warning: managedFileWarning, ...metadata, signatures: ['pending'] } };
213
+ for (const [key, value] of Object.entries(values)) {
214
+ if (value !== null && typeof value === 'object')
215
+ throw new Error(`JSON value ${key} must be a scalar`);
216
+ encrypted[key] = await encryptValue(JSON.stringify(value), metadata.recipients);
217
+ }
218
+ return `${JSON.stringify(encrypted, undefined, 2)}\n`;
219
+ }
220
+ function parseJsonScalar(value) {
221
+ try {
222
+ const parsed = JSON.parse(value);
223
+ if (parsed === null || ['string', 'number', 'boolean'].includes(typeof parsed))
224
+ return parsed;
225
+ }
226
+ catch { /* Older documents encrypted string values directly. */ }
227
+ return value;
228
+ }
229
+ async function atomicWrite(filePath, value) {
230
+ const temporary = join(dirname(filePath), `.${basename(filePath)}.${process.pid}.tmp`);
231
+ await writeFile(temporary, value, { encoding: 'utf8', mode: 0o600 });
232
+ await rename(temporary, filePath);
233
+ }
234
+ function hasValidSignature(document) {
235
+ const data = canonicalSigningData(document);
236
+ const seenSigners = new Set();
237
+ for (const maintainer of document.metadata.maintainers)
238
+ validateSigningPublicKey(maintainer);
239
+ for (const signature of document.metadata.signatures) {
240
+ const match = /^(ed25519:[A-Za-z0-9_-]+):([A-Za-z0-9_-]+)$/u.exec(signature);
241
+ if (!match || !document.metadata.maintainers.includes(match[1]) || seenSigners.has(match[1])) {
242
+ throw new Error('Document has malformed or duplicate maintainer signatures');
243
+ }
244
+ seenSigners.add(match[1]);
245
+ try {
246
+ if (verifyDocument(data, match[2], match[1]))
247
+ return true;
248
+ }
249
+ catch {
250
+ throw new Error('Document does not have a valid maintainer signature');
251
+ }
252
+ }
253
+ return false;
254
+ }
255
+ function validateMaintainers(document) {
256
+ for (const maintainer of document.metadata.maintainers)
257
+ validateSigningPublicKey(maintainer);
258
+ }
259
+ function renderMetadata(source, format, metadata) {
260
+ if (format === 'json') {
261
+ const parsed = JSON.parse(source);
262
+ parsed.$gcrypt = { warning: managedFileWarning, ...metadata };
263
+ return `${JSON.stringify(parsed, undefined, 2)}\n`;
264
+ }
265
+ const lines = source.split(/(\r\n|\n|\r)/u);
266
+ const replacement = new Map([
267
+ ['version', '# gcrypt: 2'],
268
+ ['recipients', `# gcrypt-recipients: ${metadata.recipients.join(',')}`],
269
+ ['maintainers', `# gcrypt-maintainers: ${metadata.maintainers.join(',')}`],
270
+ ]);
271
+ let wroteSignature = false;
272
+ let memberIndex = 0;
273
+ for (let index = 0; index < lines.length; index += 2) {
274
+ const match = /^\s*#\s*gcrypt(?:-(member|recipients|maintainers|signature))?\s*:/u.exec(lines[index]);
275
+ if (!match)
276
+ continue;
277
+ const name = match[1] ?? 'version';
278
+ if (name === 'member') {
279
+ const member = metadata.members[memberIndex];
280
+ lines[index] = member ? renderDotenvMember(member) : '';
281
+ memberIndex += 1;
282
+ }
283
+ else if (name === 'signature') {
284
+ if (wroteSignature)
285
+ lines[index] = '';
286
+ else {
287
+ lines[index] = `# gcrypt-signature: ${metadata.signatures[0]}`;
288
+ wroteSignature = true;
289
+ }
290
+ }
291
+ else
292
+ lines[index] = replacement.get(name);
293
+ }
294
+ if (!wroteSignature) {
295
+ const maintainerIndex = lines.findIndex((line) => line.startsWith('# gcrypt-maintainers:'));
296
+ lines.splice(maintainerIndex + 2, 0, `# gcrypt-signature: ${metadata.signatures[0]}`, '\n');
297
+ }
298
+ const missingMembers = metadata.members.slice(memberIndex).map(renderDotenvMember);
299
+ if (missingMembers.length > 0) {
300
+ const signatureIndex = lines.findIndex((line) => line.startsWith('# gcrypt-signature:'));
301
+ lines.splice(signatureIndex === -1 ? lines.length : signatureIndex, 0, ...missingMembers.flatMap((line) => [line, '\n']));
302
+ }
303
+ const rendered = lines.join('');
304
+ return rendered.startsWith(`# WARNING: ${managedFileWarning}`) ? rendered : `# WARNING: ${managedFileWarning}\n${rendered}`;
305
+ }
306
+ function metadataForMembers(members) {
307
+ return {
308
+ version: 2,
309
+ members,
310
+ recipients: members.map(({ recipient }) => recipient),
311
+ maintainers: members.flatMap(({ signingKey, isMaintainer }) => isMaintainer ? [signingKey] : []),
312
+ signatures: [],
313
+ };
314
+ }
315
+ function renderDotenvMember({ id, recipient, signingKey, isMaintainer }) {
316
+ return `# gcrypt-member: ${id},${recipient},${signingKey},${isMaintainer}`;
317
+ }
318
+ function validateMemberId(memberId) {
319
+ if (/\s|,/u.test(memberId))
320
+ throw new Error('Member ID must not contain spaces or commas');
321
+ }
322
+ async function requested(request, name) {
323
+ if (!request)
324
+ throw new Error(`A ${name} prompt is required`);
325
+ const value = (await request()).trim();
326
+ if (!value)
327
+ throw new Error(`A ${name} is required`);
328
+ return value;
329
+ }
330
+ function isMissingFile(error) {
331
+ return typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';
332
+ }
333
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface AgeIdentity {
2
+ identity: string;
3
+ recipient: string;
4
+ }
5
+ export interface SigningIdentity {
6
+ privateKey: string;
7
+ publicKey: string;
8
+ }
9
+ export declare function generateAgeIdentity(): Promise<AgeIdentity>;
10
+ export declare function ageRecipientForIdentity(identity: string): Promise<string>;
11
+ export declare function encryptValue(value: string, recipients: string[]): Promise<string>;
12
+ export declare function decryptValue(encryptedValue: string, identity: string): Promise<string>;
13
+ export declare function generateSigningIdentity(): SigningIdentity;
14
+ export declare function signDocument(document: string, privateKey: string): string;
15
+ export declare function verifyDocument(document: string, signature: string, publicKey: string): boolean;
16
+ export declare function signingPublicKeyForIdentity(privateKey: string): string;
17
+ export declare function validateAgeRecipient(recipient: string): void;
18
+ export declare function validateSigningPublicKey(publicKey: string): void;