#!/usr/bin/env bun /** * Put a secret the platform did not generate into the secret store. * * bun run secret:set apns-p8 < AuthKey_ABCD123456.p8 * pbpaste | bun run secret:set fcm-service-account * * ── Why stdin, and no value argument ── * * A secret passed as `argv` is in the shell history, in `ps` output for the life of the process, and in * any audit log that records command lines. Stdin is none of those. There is deliberately no `--value` * flag: offering one would mean the convenient path is the leaky one. * * Multi-line input is kept verbatim, which is what a PEM needs — no escaping, unlike `.env`. */ import { putSecret, getSecret, secretStorePath } from '../src/databases/officer_db/src/secret-store'; const purpose = process.argv[2]; if (!purpose || purpose.startsWith('-')) { console.error('usage: bun run secret:set < file'); console.error(' cat AuthKey_ABCD123456.p8 | bun run secret:set apns-p8'); process.exit(2); } const value = (await Bun.stdin.text()).trim(); if (!value) { console.error(`[secret:set] nothing on stdin — refusing to store an empty secret for '${purpose}'`); console.error(' (did you mean `bun run secret:set < file`?)'); process.exit(1); } const previous = putSecret(purpose, value); // The value itself is never printed, here or anywhere. Enough to confirm the right thing landed: // the length and last four characters identify a paste without reproducing it. const fingerprint = `${value.length} chars, ending …${value.slice(-4)}`; if (previous === null) { console.log(`[secret:set] '${purpose}' stored — ${fingerprint}`); } else if (previous === value) { console.log(`[secret:set] '${purpose}' unchanged — ${fingerprint}`); } else { console.log(`[secret:set] '${purpose}' REPLACED — ${fingerprint}`); console.log(` the previous value is retired, not deleted (retiredKeys('${purpose}') has it)`); } console.log(`[secret:set] store: ${secretStorePath()}`); console.log(`[secret:set] read back: ${getSecret(purpose) === value ? 'ok' : 'MISMATCH — do not restart anything'}`);