0 - Comfy Credential
The one node in Old-Time Radio that ever sees your Comfy API key
- credential
It's labelled 0 - Comfy Credential and it sits above the Workflow Validator in every shipped Old-Time Radio workflow. It has no widgets, you never type anything into it, and on a fully local run it does nothing at all. Its whole job is to be the one place your Comfy API key is allowed to exist.
What it is, and why you'd care
Old-Time Radio writes, casts, voices, scores and cuts a radio drama into an .mp4, mostly on your own machine. The default run costs nothing and needs no account. But the pack has lanes that do spend: a hosted writer through Comfy Credits, and the cloud_* image, video and music rows that run on Comfy's infrastructure.
Those read your key from a hidden input ComfyUI injects at execution time (api_key_comfy_org) - the key you use with the API-key option on ComfyUI's sign-in dialog. This node receives it, stashes it against the prompt that's currently running, and every spending node reads it from there. No key, and the cloud lanes refuse instead of quietly doing something else.
That's plumbing, and it would be unremarkable - except for where the key used to end up.
Why this node exists
A V1 ComfyUI node that declares that hidden input gets its input values formatted into the error record ComfyUI writes to /history, /api/jobs and the websocket error event. So a node holding your key that raises on purpose publishes your key. Several Old-Time Radio nodes refuse deliberately - the validator's wallet and asset gates - and nine of them used to declare the key. On a pod bound to 0.0.0.0, that's your credential served up to anyone the proxy admits. The KB says the same thing from the other end: custom nodes are unsandboxed Python, and a node built to phone home with a key is exactly the shape of the thing that got weaponized in the ComfyUI_LLMVISION case (comfyui-ecosystem.md § The Security Incident).
Now exactly one node declares it, and it cannot raise - everything sits inside one try/except, and a failed bind reports absent rather than claiming a credential the spend paths don't have.
The output
One output: credential, a STRING that reads comfy_key:present or comfy_key:absent, never the key itself.
Wire it into the Workflow Validator's credential input. That's the only link in the shipped workflows, and it's the whole ordering trick: the validator is the root of every graph, so anything wired off it descends from the credential node and therefore runs after the key is bound. The validator then measures its balance preflight against this queue's key, so it checks the wallet the run will actually spend from.
Two things before you rewire anything. The binding is tied to the prompt id: an empty queue clears the previous queue's key rather than reusing it, and a key bound to a finished prompt is refused (that's why IS_CHANGED returns NaN - it re-runs every queue). And if binding fails, the console gets a WARNING naming the exception's type only.
Installing it
It ships with the pack. ComfyUI Manager → search old time radio (registry id comfyui-old-time-radio), or:
cd ComfyUI/custom_nodes
git clone https://github.com/jbrick2070/ComfyUI-OldTimeRadio
python -m pip install -r ComfyUI-OldTimeRadio/requirements.txt
Use ComfyUI's own Python for that pip - it's the most common way a pack like this fails, and it fails late, as nodes that quietly don't load. Restart, then confirm this one registered:
curl -s http://127.0.0.1:8188/object_info/OTR_ComfyCredential | head -c 300
To turn the lane on: create a Comfy API key, sign in with the API-key option (email or Google sign-in injects no key), then on 1 - Story Writer pick a hosted slug in comfy_slot_a_model and set creative_writing_model to comfy:slot-a - same trick with the _b pair for the technical slot. Headless boxes differ: OTR_COMFY_API_KEY goes in the environment of the machine that submits (the server never reads it), and you submit through scripts/otr_api.py, which sends it as extra_data.api_key_comfy_org.
Where people get burned
"I'm signed in and it still refuses." You signed in with email or Google. The pack reads one thing, the API-key hidden input, and that sign-in doesn't provide it.
comfy_key:absent on a local run. Correct, and nothing is broken. It only matters the moment a cloud row is selected.
Looking for a key box. There isn't one, and you don't want one: a key saved into a widget travels with the workflow you share, every queue entry, and the metadata of everything you generate (external-api-nodes.md § Security).
Deleting it, or wiring it downstream. Sever the link and the cloud lanes fail closed with a named error instead of spending, so leave node 0 above the validator. And queue one episode at a time - the pack keeps its episode ledger in process memory.
More on the lanes, and what the cloud rows cost: apple/CLOUD.md and apple/comfy-credits-setup.md in the pack folder.
Inputs (0)
No inputs
Outputs (1)
| Name | Type | Description |
|---|---|---|
| credential | STRING | comfy_key:present or comfy_key:absent -- never the key itself. Wire it into the Workflow Validator's credential input so this node runs first. |