Skip to content

Commit b26b0c4

Browse files
authored
docs: updates readme with use instructions and bumps to V0.1.0 (#5)
1 parent 85b10ce commit b26b0c4

File tree

2 files changed

+270
-3
lines changed

2 files changed

+270
-3
lines changed

README.md

Lines changed: 250 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,251 @@
11
# GitOps Secrets
2-
Easily and securely inject environment variable secrets—no matter the size—into any JavaScript runtime. Unlock the ability to bypass AWS Lambda, Vercel, and Netlify's 4KB environment variable limit and run on the edge in environments like Deno, Bun, and others where NodeJS built-in modules are not available.
2+
3+
Easily and securely inject environment variable secrets—no matter the size—into any JavaScript runtime. Bypass the 4KB environment variable limit in AWS Lambda, Vercel, and Netlify, and run on the edge in environments like Deno, Bun, and others where NodeJS built-in modules aren't available.
4+
5+
## Table of Contents
6+
- [Installation](#installation)
7+
- [Usage Options](#usage-options)
8+
- [File System Access Available](#file-system-access-available)
9+
- [No File System Access (Edge Functions)](#no-file-system-access-edge-functions)
10+
- [Secret Storage Formats](#secret-storage-formats)
11+
- [JSON Format](#json-format)
12+
- [JS Module Format](#js-module-format)
13+
- [Providers](#providers)
14+
- [Background](#background)
15+
16+
## Installation
17+
18+
```bash
19+
# npm
20+
npm install @jacobwolf/gitops-secrets
21+
22+
# yarn
23+
yarn add @jacobwolf/gitops-secrets
24+
25+
# pnpm
26+
pnpm add @jacobwolf/gitops-secrets
27+
28+
# bun
29+
bun add @jacobwolf/gitops-secrets
30+
```
31+
32+
## Usage Options
33+
34+
### File System Access Available
35+
36+
#### 1. Build the encryption file at bundle time
37+
38+
Create a script (e.g., `scripts/build-secrets.ts`) to generate your encrypted secrets:
39+
40+
```typescript
41+
import * as gitopsSecrets from '@jacobwolf/gitops-secrets';
42+
43+
// Fetch secrets from provider (e.g., Doppler)
44+
const secretsData = await gitopsSecrets.providers.doppler.fetchSecrets({
45+
dopplerToken: process.env.DOPPLER_TOKEN
46+
});
47+
48+
// Encrypt and store secrets
49+
await gitopsSecrets.build(secretsData, {
50+
// Optional: Custom path (defaults to .secrets/.secrets.enc.js)
51+
path: './config/secrets.enc.js',
52+
// Optional: Only export cipher text without loading logic
53+
cipherTextOnly: false
54+
});
55+
```
56+
57+
Run this script during your build process by adding it to your `package.json`:
58+
59+
```json
60+
{
61+
"scripts": {
62+
"prebuild": "ts-node scripts/build-secrets.ts",
63+
"build": "your-build-command"
64+
}
65+
}
66+
```
67+
68+
This ensures your secrets are encrypted and available before your application builds. Make sure you have `ts-node` installed:
69+
70+
```bash
71+
npm install --save-dev ts-node
72+
# or
73+
yarn add -D ts-node
74+
# or
75+
pnpm add -D ts-node
76+
# or
77+
bun add -D ts-node
78+
```
79+
80+
#### 2. Load secrets at runtime
81+
82+
```typescript
83+
import * as gitopsSecrets from '@jacobwolf/gitops-secrets';
84+
85+
// Method 1: Default path (.secrets/.secrets.enc.js)
86+
await gitopsSecrets.loadSecrets();
87+
88+
// Method 2: Custom module path
89+
const secretsModule = require('./config/secrets.enc.js');
90+
await secretsModule.loadSecrets();
91+
92+
// Method 3: From JSON file
93+
const decryptedSecrets = await gitopsSecrets.decryptFromFile('./path/to/secrets.enc.json');
94+
decryptedSecrets.mergeSecrets();
95+
96+
// Now process.env has all your secrets
97+
console.log(process.env.API_KEY); // "your-secret-api-key"
98+
```
99+
100+
### No File System Access (Edge Functions)
101+
102+
For environments without file system access (Vercel Edge, Cloudflare Workers, browsers):
103+
104+
#### 1. Import the no-fs version
105+
106+
```typescript
107+
// Import the edge-compatible version
108+
import * as gitopsSecrets from '@jacobwolf/gitops-secrets/no-fs';
109+
// Or import specific functions
110+
import { providers, encrypt, decrypt } from '@jacobwolf/gitops-secrets/no-fs';
111+
```
112+
113+
#### 2. Handle encryption/decryption directly
114+
115+
```typescript
116+
// Encrypt secrets to string
117+
// Uses GITOPS_SECRETS_MASTER_KEY environment variable
118+
const encryptedSecrets = await gitopsSecrets.encrypt(JSON.stringify(secretsData));
119+
120+
// Later, decrypt and use
121+
const decryptedJson = await gitopsSecrets.decrypt(encryptedSecrets);
122+
const secrets = JSON.parse(decryptedJson);
123+
124+
// Or load directly into environment
125+
await gitopsSecrets.loadSecrets(encryptedSecrets);
126+
```
127+
128+
#### 3. Recommended pattern for edge functions
129+
130+
```typescript
131+
// During build time (build script)
132+
import { providers, encrypt } from '@jacobwolf/gitops-secrets';
133+
134+
const secretsData = await providers.doppler.fetchSecrets({
135+
dopplerToken: process.env.DOPPLER_TOKEN
136+
});
137+
const encryptedText = await encrypt(JSON.stringify(secretsData));
138+
139+
// Add to your edge code as a constant
140+
console.log(`const ENCRYPTED_SECRETS = "${encryptedText}";`);
141+
142+
// In your edge function:
143+
import { decrypt } from '@jacobwolf/gitops-secrets/no-fs';
144+
145+
export default async function handler(request) {
146+
const decryptedJson = await decrypt(ENCRYPTED_SECRETS);
147+
const secrets = JSON.parse(decryptedJson);
148+
149+
// Use your secrets
150+
const apiKey = secrets.API_KEY;
151+
// ...your edge function logic
152+
}
153+
```
154+
155+
## Secret Storage Formats
156+
157+
There are two file formats for bundling encrypted secrets:
158+
159+
### JSON Format
160+
161+
Stores encrypted data in a JSON file.
162+
163+
```typescript
164+
import * as gitopsSecrets from '@jacobwolf/gitops-secrets';
165+
166+
// Encrypt to JSON file
167+
async function encryptToJSON() {
168+
const payload = await gitopsSecrets.providers.doppler.fetchSecrets({
169+
dopplerToken: process.env.DOPPLER_TOKEN
170+
});
171+
172+
// Default path (.secrets/.secrets.enc.json)
173+
await gitopsSecrets.encryptToFile(payload);
174+
175+
// Or custom path
176+
await gitopsSecrets.encryptToFile(payload, {
177+
path: "./custom/path/secrets.enc.json"
178+
});
179+
}
180+
181+
// Decrypt from JSON file
182+
async function decryptFromJSON() {
183+
// Default path
184+
const secrets = await gitopsSecrets.decryptFromFile();
185+
186+
// Or custom path
187+
const customSecrets = await gitopsSecrets.decryptFromFile('./custom/path/secrets.enc.json');
188+
189+
// Merge into environment
190+
secrets.mergeSecrets();
191+
}
192+
```
193+
194+
### JS Module Format
195+
196+
Ideal for restricted environments like Vercel where file access is problematic.
197+
198+
```typescript
199+
import * as gitopsSecrets from '@jacobwolf/gitops-secrets';
200+
201+
// Encrypt to JS module
202+
async function buildJSModule() {
203+
const payload = await gitopsSecrets.providers.doppler.fetchSecrets({
204+
dopplerToken: process.env.DOPPLER_TOKEN
205+
});
206+
207+
// Default path (.secrets/.secrets.enc.js)
208+
await gitopsSecrets.build(payload);
209+
210+
// Custom path
211+
await gitopsSecrets.build(payload, {
212+
path: "lib/secrets.js"
213+
});
214+
215+
// Only export cipher text
216+
await gitopsSecrets.build(payload, {
217+
path: "lib/secrets.js",
218+
cipherTextOnly: true
219+
});
220+
}
221+
222+
// Load from default path
223+
async function loadFromDefaultPath() {
224+
import { loadSecrets } from '@jacobwolf/gitops-secrets';
225+
await loadSecrets();
226+
}
227+
228+
// Load from custom module
229+
async function loadFromCustomModule() {
230+
// CommonJS
231+
const { loadSecrets } = require("./lib/secrets");
232+
await loadSecrets();
233+
234+
// ES modules
235+
import { loadSecrets } from "./lib/secrets";
236+
await loadSecrets();
237+
}
238+
```
239+
240+
## Providers
241+
242+
Currently supported remote secrets providers:
243+
- [Doppler](https://www.doppler.com/)
244+
245+
More providers will be added in future releases.
246+
247+
## Background
248+
249+
Serverless platforms like Vercel, Netlify, and AWS Lambda limit environment variables to 4KB, which complex applications can quickly exceed.
250+
251+
This package was inspired by [Doppler's GitOps Secrets package](https://github.com/DopplerHQ/gitops-secrets-nodejs/), but it uses the Web Crypto API instead of `node:crypto` for broader compatibility with modern web environments like edge functions.

package.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jacobwolf/gitops-secrets",
3-
"version": "0.0.2",
3+
"version": "0.1.0",
44
"description": "Easily and securely inject environment variable secrets—no matter the size—into any JavaScript runtime.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -28,7 +28,25 @@
2828
"type": "git",
2929
"url": "https://github.com/JacobNWolf/gitops-secrets"
3030
},
31-
"keywords": [],
31+
"keywords": [
32+
"secrets",
33+
"environment-variables",
34+
"encryption",
35+
"security",
36+
"serverless",
37+
"edge-functions",
38+
"vercel",
39+
"netlify",
40+
"lambda",
41+
"doppler",
42+
"gitops",
43+
"web-crypto",
44+
"environment",
45+
"env",
46+
"config",
47+
"configuration",
48+
"edge-runtime"
49+
],
3250
"author": "Jacob Wolf",
3351
"license": "MIT",
3452
"packageManager": "pnpm@10.6.5",

0 commit comments

Comments
 (0)