LLM Providers
Forginate runs LLM work (factory runs, QA, chat-editor) against Anthropic and OpenAI. Keys live in the database, not in pod env — no Helm change is needed to add or rotate them.
Two kinds of keys
| Kind | Owned by | Set where | Billed at |
|---|---|---|---|
Platform keys (platform-anthropic, platform-openai) | you, the operator | Admin → Platform Keys (/admin/platform-keys, founder-only) | plan markup |
| BYO keys (per-org) | each tenant organization | the org's provider settings in the app | the plan's BYO rate |
Key resolution at run time:
- The org's own default provider, if attached (BYO)
- Any other provider on the org
- The default platform key
- Any other platform key
No key, no runs
An organization with no BYO key and no platform key configured fails every run at the manifest fetch. Add at least one platform key immediately after install so new signups work out of the box.
The credential vault
All provider keys (platform and BYO) are encrypted at rest with AES-256-GCM using the forginate-credential-key secret (FORGINATE_CREDENTIAL_KEY env, a base64 32-byte key — generate with openssl rand -base64 32).
Losing the vault key is unrecoverable
If forginate-credential-key is lost, every stored provider credential becomes unreadable and every tenant must re-enter their keys. Include it in your secret export ritual — see Backups.
How keys reach the workloads
- Factory-runner / qa-runner pods never mount a static key. The orchestrator builds a run manifest; the runner fetches it (and the resolved provider credential) from the gateway's internal listener using a short-lived, run-scoped agent token.
- chat-editor resolves per-org keys through the gateway's internal
/__internal/providers/:orgIdendpoint, authenticated byINTERNAL_API_TOKEN. - Model/tier selection is data-driven via the admin Tiers screen (the
model_tierstable). Each tier maps to a concrete model, a price (costPerMillion), and an auth reference (e.g.env:ANTHROPIC_API_KEYresolved to the run's provider credential). The runner carries no price table — it reports exact tokens and the gateway reprices server-side from the admin tier prices times the org markup.
Optional orchestrator-level keys
Two env-level keys exist on the orchestrator, both optional and off by default:
ANTHROPIC_API_KEY— only consumed by the (default-disabled,BRAIN_ENABLED=false) autonomous "brain" loop. Leave unset unless you know you want it.ANTHROPIC_ADMIN_API_KEY+COST_RECONCILE_ENABLED=true— nightly reconciliation of Anthropic's Admin usage/cost API against Forginate's internal usage ledger, surfacing untracked spend. Purely an audit backstop.
Neither has a chart values key; wire them by adding env entries to the orchestrator Deployment if needed.
Egress: which provider hosts runners may reach
Runner pods sit behind a default-deny NetworkPolicy that opens public 443/80, and the runner additionally enforces a hostname allowlist from the orchestrator's RUNNER_EGRESS_ALLOWLIST env (comma-separated). The default:
api.anthropic.com, api.openai.com, api.x.ai, api.groq.com,
api.github.com, github.com, codeload.github.com,
objects.githubusercontent.com, uploads.github.com,
registry.npmjs.org, pypi.org, files.pythonhosted.orgIf you point a tier at a different provider endpoint (or a proxy), add its hostname to the allowlist or runs will fail on egress.
Cost controls
- Per-run dollar cap:
orchestrator.defaultMaxDollars(chart value →DEFAULT_MAX_DOLLARS). The runner meters tokens against tier prices in-pod and stops at the cap. Ship default is"0.5"— raise it for real workloads. - Per-run wall clock:
orchestrator.defaultRunTimeoutSeconds(default"3300"). - Provider walls: on
429/529/credit-exhaustion the runner does not die — it retries the same call every 15 minutes for up to 24 hours in place, preserving its conversation so no spend is repeated (PROVIDER_WALL_RETRY_INTERVAL_MS,PROVIDER_WALL_MAX_MS; the Job's wall ceilingRUNNER_MAX_WALL_Sdefaults to 25 h so Kubernetes doesn't kill a patiently waiting pod). The UI shows a "delayed" badge. An operator halt switch (provider_haltsite setting) aborts waiting runs. - Chat concurrency:
chatEditor.orgConcurrency(default 3) caps concurrent SSE streams per org — tighten it if you see provider 429s.
Rotation
Platform keys: add the new key in Admin → Platform Keys, mark it default, delete the old row. BYO keys: tenants rotate their own in the org settings. No pod restarts are required — keys are read from the database per run.
Verify after adding a key
Kick off a small factory run from a non-founder test org. If it passes the manifest fetch and starts streaming events, resolution and the vault key are both working.