Skip to content

Instantly share code, notes, and snippets.

@wyozi
Created August 17, 2023 08:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wyozi/3f51420413d7faa2cb92fe7d15ee5bd5 to your computer and use it in GitHub Desktop.
Save wyozi/3f51420413d7faa2cb92fe7d15ee5bd5 to your computer and use it in GitHub Desktop.
inngest encrypted step.run return value
import crypto from "crypto";
import { StepOpts } from "inngest/types";
const CRYPTO_KEY = process.env.BACKGROUND_VAR_CRYPTO_KEY;
export type Encrypted<T> = {
iv: string;
ciphertext: string;
};
export async function encryptVars<T>(input: T): Promise<Encrypted<T>> {
const key = CRYPTO_KEY!;
if (!key) {
throw new Error("failed to import key");
}
const plaintext = JSON.stringify(input);
const iv = crypto.randomBytes(16).toString("hex");
const cipher = crypto.createCipheriv(
"aes-256-cbc",
Buffer.from(key, "hex"),
Buffer.from(iv, "hex")
);
const ciphertext = `${cipher.update(
plaintext,
"utf8",
"base64"
)}${cipher.final("base64")}`;
return {
iv,
ciphertext,
};
}
export async function decryptVars<T>(encrypted: Encrypted<T>): Promise<T> {
const key = CRYPTO_KEY!;
if (!key) {
throw new Error("failed to import key");
}
const decipher = crypto.createDecipheriv(
"aes-256-cbc",
Buffer.from(key, "hex"),
Buffer.from(encrypted.iv, "hex")
);
const decrypted = `${decipher.update(
encrypted.ciphertext,
"base64",
"utf8"
)}${decipher.final("utf8")}`;
return JSON.parse(decrypted);
}
export async function stepRunWithEncryption<
Step extends {
run: <T extends () => unknown>(
name: string,
fn: T,
opts?: StepOpts | undefined
) => Promise<any>;
},
T extends () => unknown
>(step: Step, name: string, fn: T, opts?: StepOpts | undefined) {
return decryptVars(
await step.run(
name,
async () => {
const vals = await fn();
return encryptVars(vals);
},
opts
)
) as ReturnType<T>;
}
/* Usage:
1. generate symmetric crypto key with e.g. `node -e 'console.log(require(`crypto`).randomBytes(32).toString(`hex`))'` and store in ENV (BACKGROUND_VAR_CRYPTO_KEY)
2. use stepRunWithEncryption for steps that return data that should be encrypted
const { foo } = await stepRunWithEncryption(step, "Do something", async () => {
return { foo: "this is a secret value" }
})
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment