Platform
Providers and BYOK
Bring your own provider keys (OpenAI, Anthropic, etc.) and link them per environment with a checklist.
Providers and BYOK
Platos runs on your provider keys. There is no managed inference, no platform spend, no rebill. You bring an OpenAI key, an Anthropic key, an embedding key; Platos links them per environment and routes turns through them. Keys are encrypted at rest, scoped to the environment, and rotatable without touching agent configs.
What it is
Two layers:
- Provider manifests under
apps/agent/src/providers/manifests/. Each manifest declares the provider'sslug, the env vars it needs (OPENAI_API_KEY,OPENAI_API_BASE, etc.), the auth shape, the model class, and any default model list. PlatosProviderKeyrows keyed on(scope, providerSlug, name). PIFSP-14 lets you have N keys per provider in the same environment; each agent can pin a specific key viaproviderKeyIdor fall back to the scope default.
ScopedEnvService reads the linked keys at runtime and assembles the env bag the LLM client uses. ProviderRegistryService enumerates available providers; ProviderHealthService runs cheap health pings (model list / hello call) and surfaces status on the providers page.
The model picker (loadActiveProviders(scope)) filters the model catalog by which providers have a linked key in the current environment. Hide a provider, hide its models.
Why it matters
A managed-inference platform locks you into someone else's pricing curve and rate limits. BYOK lets you negotiate your own rates, run on a private deployment (Azure OpenAI, Bedrock, on-prem), and rotate keys when the provider asks. The cost is some onboarding friction; Platos minimises that with a one-page checklist and the model picker that hides what you have not linked yet.
The multi-key support (PIFSP-14) is for teams that need separate keys per project, per region, or per team. A single Anthropic provider can hold three keys: prod-us, prod-eu, dev. Each agent pins the key it should spend against; rotation hits one key without invalidating the rest.
How to use it
Add a key
Provider keys live in environment variables. The Providers page shows you which providers have a key wired and runs health checks against them; it is a read-and-link surface, not a create-a-secret form.
For self-hosted Platos, edit your .env file and set the variable for the provider you want:
# LLM providers — at least one needed to run a turn
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
GOOGLE_GENERATIVE_AI_API_KEY=...
# Embedding provider — REQUIRED for memory + RAG
PLATOS_EMBEDDING_PROVIDER=voyage # or `openai`
VOYAGE_API_KEY=pa-... # required when provider=voyage
The embedding key is its own track — without one of VOYAGE_API_KEY or OPENAI_API_KEY (with PLATOS_EMBEDDING_PROVIDER=openai), the hourly memory-extraction cron and every remember call throw at write time. Multi-turn agents will look stateless. The agent emits a loud boot-time warning when neither is set; see Memory § Setup.
The exact variable name per provider lives in .env.example; the Providers page also shows the expected name for each provider. Restart the stack so the new env propagates:
docker compose -f docker-compose.platos.yml up -d
For managed deployments, use the dashboard Environment Variables page (Sidebar to Environment Variables) instead of editing a file. The agent picks up changes on the next request, no restart needed. Either path stores the secret in trigger.dev's Environment Variables table; the PlatosProviderKey row carries metadata only (label, last-used, status), not the secret.
Multiple keys per provider
Set numbered variants for additional keys: ANTHROPIC_API_KEY_2, ANTHROPIC_API_KEY_3, and so on. The Providers page lists every variant. Useful for splitting cost centers, separating regions, or rate-limit isolation.
Pin per agent
The agent's general tab has a "Provider key" field. Pick a specific named variant or "scope default" (the first variant linked for the provider). New agents inherit the scope default.
Rotate
Edit the env var with the new value. Self-host: restart the stack. Managed: save on the Environment Variables page. Turns in flight finish on the old credential; new turns use the new one. No agent-config edits required.
Health
The health badge per provider runs a cheap "list models" call every 5 minutes. Red badges mean the key is invalid or revoked; investigate before agents break.
Common pitfalls
- The model picker is empty when no provider has a linked env var. The most common "I cannot pick a model" cause is "the env var is not set in this scope yet".
- Provider env vars are scoped to
(organizationId, projectId, environmentId). A var indevdoes not auto-apply toprod. Set per environment. - Wrong variable name.
OPENAI_KEYis wrong; it has to beOPENAI_API_KEY. Check.env.exampleor the Providers page hint for each provider's expected name. - The encryption tail relies on
ENCRYPTION_KEYbeing a 32-byte ASCII string. A wrong-length key breaks both reads and writes; see Encryption and secrets for the trap. - A pinned
providerKeyIdthat no longer exists falls back to scope default. The agent does not error; it spends against a different key. If you want hard pinning, configure budget caps so the wrong key blows the cap loud.
Related
- Models: the catalog the picker reads from.
- Encryption and secrets: where the keys are encrypted and the rotation guarantees.
- Environments: the scope dimension that owns key bindings.
