Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Concepts

This page lists what Model Gateway enforces today. Where something is missing or partial, it says “Not yet”.

Whose records

Every record belongs to one person, identified by owner_uid. That is the person’s Granite id, taken from the Granite grant on the request (see Authentication). The same person has the same owner_uid in every app that uses Granite.

A caller acting for a person sees and changes all of that person’s Model Gateway records, including ones another caller created. Another person’s records read as 404, the same as records that don’t exist.

Provider credentials

A provider credential holds a person’s API key for one provider.

  • provider names where calls go. These names are built in, and calls go to that provider’s public API:

    providerAPI style
    openai, openrouter, groq, together, deepseek, mistral, xaiOpenAI chat completions
    anthropicAnthropic messages
    googleGemini

    Any other name must be one of the person’s custom adapters: the credential copies that adapter’s dialect, base_url and auth_style as its destination when it is created, and its calls always go there. Otherwise the credential is refused with 400. fake is refused.

  • The key is never returned. Responses carry key_hint: ... and the key’s last four characters.

  • Deleting a credential stops every spend grant that names it. Calls on those grants then fail with 404.

Custom adapters

A custom adapter lets a credential point at a provider that isn’t built in. It is configuration only: Model Gateway sends the person’s key and the request to its base_url.

  • dialect is the API style: openai_chat, anthropic or gemini.
  • auth_style decides which header carries the key, whatever the dialect: bearer (Authorization: Bearer <key>), x_api_key (x-api-key) or goog_key (x-goog-api-key). The anthropic dialect also sends anthropic-version.
  • base_url must be https:// and must resolve only to public addresses. This is checked when the adapter is created and again before every call.
  • The name may hold only ASCII letters, digits, -, _ and ., must be unique for the person, and may not be a built-in provider name.
  • Calls to a custom adapter time out after 30 seconds, and responses larger than 10 MiB are refused.
  • An adapter is read only when a credential is created from it. Deleting or recreating it doesn’t change where existing credentials send their key; to stop a credential, delete the credential. A custom-provider credential created before credentials carried a destination (2026-11-14) has none, and calls on it fail with 400 until it is deleted and added again.

Spend grants

A spend grant is the person’s consent, in Granite, for one agent to make model calls with one of their provider credentials. Granite holds the grant and its limit; Model Gateway keeps only a count of the units used.

  • Creating one. The person approves a Granite request with request_type capability_grant, requested_resource model-gateway:credential:{credential_id} (exactly one credential), requested_scopes ["model.gateway.spend"], the agent’s ChirpAuth subject in requester_chirp_sub, and proposed_limits {"limit_units": N} with N greater than zero.
  • Using one. Every model call names a spend grant. Model Gateway asks Granite whether it is approved for the calling agent, and refuses the call if not (403). The call uses the credential of the person who approved the grant. A grant covers every model of its credential’s provider.
  • Units. Each model call Model Gateway makes counts one unit, whatever its size or what the provider charges for it. A grant does not limit what the provider bills per call.
  • limit_units is the grant’s total. The count only grows, never resets, and never exceeds limit_units. Once it reaches limit_units, Model Gateway refuses further calls on the grant (409). For more, the person approves a new grant.
  • Revoking. The person revokes the grant in Granite, and the next call on it is refused (403).

Model Gateway’s own spend-grant endpoints were removed in November 2026. Grants made through them no longer fund calls; the person approves a Granite grant instead.

Usage records

Each call counted against a grant writes one usage record: which grant (its Granite id), which resource, how many units, and when. Usage records can’t be changed or deleted.

Production and test

A Model Gateway deployment accepts credentials from one ChirpAuth issuer, so production and test never share a deployment. The production service refuses a test credential (401), and a grant created in one can’t be used from the other.