Skip to main content
Version: v5.6.1

Model providers

packs:ai-agents

A model provider is a first-class catalog record — beside identity providers and secrets providers — holding the brokered model credentials AI agents reason with. The custody posture: rather than share API keys with each agent, an agent references a provider by code and the platform's model gateway does the heavy lifting — the gateway resolves the record, injects the stored key server-side and streams the model's answer through, so no model key ever lands on an agent host. A compromised host yields a revocable agent session, not your Anthropic or OpenAI key, and rotation happens here, in one place. The hands-on walkthrough is opschain docs getting-started/12-6-model-providers-and-budgets; the custody modes and the wider AI-agent lane are ai-agents. This page is the component reference.

The kind set​

KindServesDefault endpointCredential injection
anthropicAnthropic-hosted Claude modelshttps://api.anthropic.comx-api-key
openaiOpenAI-hosted modelshttps://api.openai.com/v1Authorization bearer
azure-foundry-anthropicClaude deployed in Azure AI Foundry (the Anthropic wire — agents keep the Claude adapter unchanged)none — the record requires your resource endpointx-api-key
azure-openaiGPT-family models on Azure OpenAI (the chat-completions wire)none — the record requires your deployment URL (an api-version may ride in the endpoint string)api-key
openai-compatibleA model you host yourself speaking the OpenAI wire format (vLLM, Ollama, TGI, llama.cpp server, LiteLLM and similar)none — the record requires your endpoint's base URLAuthorization bearer when a credential is stored; no auth header otherwise

The kind picks the default endpoint, where one exists, and how the gateway injects the stored credential upstream. The Azure kinds address a per-resource (and per-deployment) URL in the customer's own tenancy, so their records cannot resolve anywhere until they carry an endpoint; authentication to them is by API key in this release, with Microsoft Entra ID a planned follow-up. The openai default carries the /v1 segment because an OpenAI-SDK caller's base URL includes it, and the gateway forwards the caller's path remainder verbatim.

Self-hosted models: the openai-compatible kind​

The openai-compatible kind brings a model you host yourself under the same governance as the vendor kinds — the brokered gateway, transcripts, token budgets and the emergency stop all apply unchanged. Three things differ from the hosted kinds:

  • The endpoint is required — there is no platform default for an endpoint only you can reach. Register your serving stack's base URL (include the /v1 segment where your stack serves it there).
  • The credential is optional. Internal endpoints are often unauthenticated or fronted by their own transport auth; with a credential stored the gateway injects it as Authorization: Bearer, without one it injects no auth header at all.
  • TLS trust is configurable per record (ssl_verify, ssl_ca_cert, below) for endpoints behind a private certificate authority.

The gateway stays a faithful byte proxy: requests and responses are forwarded untouched and the wire format is never parsed or translated, so protocol fidelity is the hosting stack's responsibility — a stack that deviates from the OpenAI dialect surfaces its own answers and errors verbatim to the calling SDK. The endpoint is operator configuration, set by an administrator on an admin-gated record, and the data_handling_approved review marker works unchanged — for a self-hosted model the review is your own sign-off on where the content flows.

TLS trust (ssl_verify, ssl_ca_cert)​

Every record carries two TLS trust attributes for its endpoint connection, defaulting to ordinary verification against the system roots:

  • ssl_verify (default true) — set false as an explicit opt-out for a self-signed endpoint; the opt-out is recorded on the entry and audited like any other change.
  • ssl_ca_cert (default empty) — a CA trust anchor: a PEM block inline, or a certificate file path on the server host. A trust anchor that cannot be loaded refuses the call loudly rather than silently falling back to the system roots.

The record, attribute by attribute​

AttributeMeaning
codeThe estate code the provider is addressed by: agent manifests reference it, and the gateway path carries it. Immutable after create.
display_nameThe human name admin surfaces render.
kindThe provider kind (table above). Immutable after create.
endpointEndpoint override; empty means the kind's default where one exists — the Azure kinds and openai-compatible require one.
credential_setWhether a credential is stored — the value itself is write-only: no response, audit row or error ever echoes it. For openai-compatible the credential is optional.
credential_refThe canonical secret-vault:// reference the credential lives at — an address, never a value. Empty on a grandfathered record whose inline encrypted credential predates reference-first custody.
data_handling_approvedThe estate's one-time data-handling review marker (below).
ssl_verifyWhether the endpoint's TLS certificate is verified (default true; the TLS trust section above).
ssl_ca_certA CA trust anchor for the endpoint connection — a PEM block inline or a certificate file path on the server host; empty uses the system roots.
enabledWhether the gateway serves calls for this provider.

Custody is reference-first: --credential-ref pins an existing secret-vault:// reference, resolved at write time (an unresolvable reference refuses by name), while an inline credential is vault-write sugar — the value lands in the platform vault under the reserved model-providers/<code>/credential path and only the resulting reference is stored. Records created before the retrofit keep their inline encrypted key until the next credential write, which moves custody to the vault.

Lifecycle​

  • Create registers a provider (requires packs:ai-agents): code and kind immutable, the API key via environment variable or no-echo prompt (never argv), exactly one of the inline credential or a credential_ref carrying it (openai-compatible alone may carry neither).
  • Update partially updates — a supplied credential rotates the stored key for every agent at once; a supplied credential_ref re-pins the reference. Enabling a disabled provider requires packs:ai-agents, exactly as create does; disabling is never gated.
  • Delete removes a provider, ungated. Agents whose manifest references the deleted code keep their sessions, but every gateway call refuses until the provider is re-created or the agent re-registers without it.

Compositions without the model-provider plane answer not-found, the nil-domain convention, and listings order by code ascending.

Which agents use this provider​

An agent is bound to exactly one provider — the catalog code its manifest names (OPSCHAIN_MODEL_PROVIDER on the agent host) — and the binding is by code, never by kind: two anthropic entries are two different providers, and an agent bound to one never falls back to the other. To see who references an entry, read the fleet: opschain admin agents list carries a PROVIDER column (the code — --filter provider=<code> narrows to its agents), opschain admin agent show renders the MODEL PROVIDER row with the entry's kind and standing (demo-anthropic (anthropic, enabled), … (anthropic, disabled), … (missing from the catalog)), the agent resource carries model_provider_code / model_provider_kind / model_provider_state, and the GUI model-providers page counts the agents referencing each entry. The disclosure an ai-type agent attests (disclosures.model_provider, the MODEL row) is the model vendor, not this code — see resources/agent.

The data-handling-approved marker​

Each catalog entry carries a data-handling-approved marker (data_handling_approved; --data-handling-approved on the create and update verbs, the DATA-HANDLING column in the listing): the record of the estate's one-time review of that provider's data-processing terms — training use, retention, residency, DPA. An administrator sets it after the review; a new entry defaults to unreviewed.

Lanes that send customer-submitted content to a model — such as a support-desk agent's AI lane — refuse to be configured against an unapproved provider. Because the approval is a property of the catalog entry itself, never a hardcoded provider list, a new or custom provider added later inherits the same check: review its terms, mark the entry, and only then can such a lane use it. The marker does not gate ordinary brokered calls over the estate's own content. The marker's place in the wider AI-agent custody story is ai-agents.

How a brokered model call flows​

The gateway's route is /api/model/{provider}/… — the rest of the path and query are forwarded to the provider's endpoint, so an Anthropic-SDK caller sets its base URL to <server>/api/model/<code> and its usual /v1/messages lands on the provider. Per call:

  1. The agent authenticates with its existing session token — the same credential every other agent-plane surface takes, carried as the Authorization bearer or as the x-api-key header value. No new auth mechanism exists for the gateway.
  2. The agent's manifest must reference the addressed provider — an agent calls only the provider it declared at registration; anything else refuses by name.
  3. The provider must be registered, enabled and — except for openai-compatible, whose credential is optional — hold a credential; each miss is its own named refusal.
  4. The grant's token budget, where one is set, is checked before the call forwards — spend over the budget refuses pre-flight until the UTC-day window resets (the caps live on trust grants; see ai-agents).
  5. The gateway injects the stored credential per the kind, strips every inbound credential carriage and hop-by-hop header (the agent's bearer never reaches the provider; no inbound API key is ever forwarded), and streams the provider's answer through untouched — payloads are never parsed or transformed, and the upstream connection carries no overall timeout, as a streamed response holds it for its whole generation.
  6. Token usage is read off the response as it streams — Anthropic streaming usage blocks and chat-completions usage alike — and stamped onto the call's audit event.

Every refusal is loud JSON in the provider error shape, so the calling model SDK surfaces it verbatim. Registration is guarded at the other end too: an agent manifest naming a provider the catalog does not hold refuses at enrolment, so a typo fails loudly before the first model call.

Settings and configuration​

No config.yaml key tunes this component: the catalog is database-backed and administered entirely through the service. On the agent host, the manifest's provider reference is set from OPSCHAIN_MODEL_PROVIDER; the adapter environment and custody modes are ai-agents territory.

Governance and audit​

Every catalog verb sits behind the /admin updatable determination (permission denied on deny), over the v2 user-token lane — the caller's own opschain login session, with the admin-token fallbacks the CLI manual records.

Entitlement: create and enable gate on packs:ai-agents — the same pack an ai-type agent enrols under, with the typed refusal naming it. The lapse posture is polite: stored providers keep resolving and serving existing agents, only new registrations (the create/enable writes) refuse, and delete stays open — a lapse never bricks a running fleet. See entitlements.

Events:

  • api:model_providers:create / update / destroy — catalog lifecycle; record facts only (code, kind, endpoint, the reference, the marker, the TLS trust facts — ssl_verify and whether a trust anchor is set — and enabled), never a credential, a rotation carrying credential_rotated.
  • info:agent:model_call — every served gateway call: the provider, the sniffed model name, method, path, upstream status and the observed input_tokens/output_tokens.
  • warn:agent:model_call_refused — a gateway refusal, with the provider and the named reason.
  • warn:agent:model_provider_refused — a registration named a provider the catalog does not hold.

The token-budget refusal and the trust-review spend aggregation (tokens_by_provider, cost attribution) are the trust-grant story — ai-agents carries them in full.

  • opschain docs cli/admin-model-providers — the command family (list, show, create, update, delete), verb by verb.
  • opschain docs getting-started/12-6-model-providers-and-budgets — the hands-on guide: custody, the catalog, token budgets.
  • opschain docs ai-agents — the custody modes, the adapters, the transcripts and the caps.
  • opschain docs entitlements — packs:ai-agents and the lapse posture.
  • The API service is the v2 ModelProviderService (opschain docs api-v2); the gateway route is /api/model/{provider}/…, agent- authenticated and deliberately not part of the admin service.