Files
jschoubben c454c6a54c openai-consumer: the static-key model-access consumer (ADR 0050)
The consumer half of the OTHER model-access shape. Where anthropic-consumer
receives a refreshed access token, this receives one operator-supplied API key
the mesh sealed to it and the host unsealed at its secret path — no manager, no
refresh, no usage. It writes the key where an OpenAI/Codex client reads it: an
OPENAI_API_KEY env file and the publicly-known Codex auth.json. Pure node, no
SDK import — the simplest a model-access consumer gets.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-07 04:25:26 +02:00

33 lines
1.6 KiB
TypeScript

// Writing the delivered OpenAI API key where an OpenAI/Codex client reads it — the consumer half of
// model-access for a STATIC-KEY vendor (novox/hq ADR 0050). Unlike the refreshable-grant consumer,
// there is nothing to strip: the credential is a single operator-supplied key the mesh sealed to this
// holder and the host unsealed at the module's secret path. This process reads that plaintext and
// writes it, and only it — no manager, no refresh token, no rotation.
//
// It is written two ways, for two clients: an `OPENAI_API_KEY=<key>` env file (what most OpenAI
// tooling and the OpenAI SDK read), and the publicly-known Codex API-key `auth.json`
// (`{ "OPENAI_API_KEY": "<key>" }`). Both are atomic and 0600 — a partial credential must never be
// read as a whole one.
import { writeFileSync, renameSync, mkdirSync } from "node:fs";
import { dirname } from "node:path";
/** Atomic write-then-rename at 0600, creating the parent directory if needed. */
export function atomicWrite(path: string, content: string): void {
mkdirSync(dirname(path), { recursive: true });
const tmp = `${path}.tmp`;
writeFileSync(tmp, content, { mode: 0o600 });
renameSync(tmp, path);
}
/** The Codex API-key auth file shape — the public, documented form of `~/.codex/auth.json`. */
export function authJson(key: string): string {
return JSON.stringify({ OPENAI_API_KEY: key }, null, 2) + "\n";
}
/** Write the delivered key to both an env file and the Codex auth.json. */
export function deliver(envFile: string, authFile: string, key: string): void {
atomicWrite(envFile, `OPENAI_API_KEY=${key}\n`);
atomicWrite(authFile, authJson(key));
}