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
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
// 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));
|
||||
}
|
||||
Reference in New Issue
Block a user