Appearance
Configuration Reference
See also: Oceans LLM Gateway, Runtime Bootstrap and Access, Service Accounts, Model Routing and API Behavior, Pricing Catalog and Accounting, OIDC and SSO
This page owns config syntax and parse-time rules. It does not own the full runtime story after a request starts moving.

Source of Truth
- config parsing and validation:
- provider capability defaults:
- checked-in examples:
Top-Level Sections
serverdatabaseauthbudget_alertsrequest_loggingprovidersmodelsteamsusers
Value Sources
The config supports literal values and env references.
Common patterns:
literal.adminenv.OPENAI_API_KEYenv.POSTGRES_URL
The YAML holds structure. Secrets and deploy-specific values usually come from the environment.
Minimal Local Example
yaml
server:
bind: "127.0.0.1:8080"
database:
kind: libsql
path: "./var/oceans.db"
auth:
bootstrap_admin:
email: "admin@local"
password: "literal.admin"
require_password_change: false
providers:
- id: openai
type: openai_compat
base_url: "https://api.openai.com/v1"
pricing_provider_id: openai
auth:
kind: bearer
token: env.OPENAI_API_KEY
models:
- id: gpt-4o-mini
routes:
- provider: openai
upstream_model: gpt-4o-miniProduction-Shaped Example
yaml
server:
bind: "0.0.0.0:8080"
database:
kind: postgres
url: env.POSTGRES_URL
auth:
bootstrap_admin:
email: "admin@local"
password: env.GATEWAY_BOOTSTRAP_ADMIN_PASSWORD
require_password_change: true
providers:
- id: vertex
type: gcp_vertex
project_id: env.GCP_PROJECT_ID
location: global
auth:
mode: service_account
credentials_path: env.GCP_SERVICE_ACCOUNT_JSON
teams:
- key: platform
name: Platform
budget:
cadence: monthly
amount_usd: "500.0000"
hard_limit: true
timezone: UTC
users:
- name: Platform Admin
email: [email protected]
auth_mode: password
global_role: platform_admin
membership:
team: platform
role: admin
budget:
cadence: monthly
amount_usd: "100.0000"
hard_limit: true
timezone: UTC
models:
- id: gemini-2.0-flash
routes:
- provider: vertex
upstream_model: google/gemini-2.0-flashThe checked-in examples are opinionated. They are not the full config space.
Defaults That Matter
Important defaults from config parsing and domain deserialization:
- model
rankdefaults to100 - route
prioritydefaults to100 - route
weightdefaults to1.0 - route
enableddefaults totrue - route capability flags default to all enabled
- Vertex
locationdefaults toglobal - Vertex
api_hostdefaults toaiplatform.googleapis.com request_logging.payloads.capture_modedefaults toredacted_payloadsrequest_logging.payloads.request_max_bytesdefaults to65536request_logging.payloads.response_max_bytesdefaults to65536request_logging.payloads.stream_max_eventsdefaults to128request_logging.purge.enableddefaults tofalserequest_logging.purge.retentiondefaults to7d
The startup meaning of bootstrap-admin lives in runtime-bootstrap-and-access.md. Non-human data-plane access is managed through service accounts, not config-seeded legacy runtime keys.
server
Important fields:
bindlog_formatotel_endpointotel_metrics_endpointotel_export_interval_secs
For collector assumptions and request-log implications, see observability-and-request-logs.md.
request_logging
request_logging.payloads controls chat-completion request-log payload persistence.
yaml
request_logging:
payloads:
capture_mode: redacted_payloads
request_max_bytes: 65536
response_max_bytes: 65536
stream_max_events: 128
redaction_paths: []
purge:
enabled: false
retention: 7d
schedule: "0 0 * * *"Important fields:
capture_modedisabled: skip chat-completion request-log persistencesummary_only: write summary rows withhas_payload=falseand no payload rowredacted_payloads: write summary rows and sanitized payload rows
request_max_bytes: final persisted request payload budgetresponse_max_bytes: final persisted response payload budgetstream_max_events: maximum stored stream events; stream usage and error parsing still sees later framesredaction_paths: additive admin-configured redaction paths anchored from the wrapped payload root
Purge fields:
purge.enabled- defaults to
false - when
true, the gateway starts a recurring request-log purge worker
- defaults to
purge.retention- defaults to
7d - valid values are
1d,3d, and7d
- defaults to
purge.schedule- standard 5-field cron expression for the recurring purge worker
- defaults to
0 0 * * * - must describe a daily or less frequent schedule
Validation rules:
- byte limits must be greater than zero
stream_max_eventsmust be greater than zeroredaction_pathsuse dot-separated object keys plus*as a full-segment wildcard- malformed paths such as
body..messagesor indexed paths such asbody.messages[0]are rejected at config parse time - purge retention windows outside
1d,3d, and7dare rejected - recurring purge schedules more frequent than daily are rejected, and the runtime guard also prevents more than one purge per day
The runtime redaction/truncation policy, purge command, and admin display behavior are owned by observability-and-request-logs.md.
database
The checked-in configs use two runtime shapes:
- local development:
- libsql or SQLite with
path
- libsql or SQLite with
- production-shaped and deploy flows:
- PostgreSQL with
kind: postgresandurl
- PostgreSQL with
Important fields:
kindlibsqlpostgres
path- libsql or SQLite database path
- defaults to
./gateway.db
url- PostgreSQL connection URL
- supports literal and env reference values
max_connections- PostgreSQL pool size
- defaults to
10
If kind is omitted, the gateway infers postgres when url is present and libsql otherwise. database.url is required when kind: postgres.
auth
Important fields:
bootstrap_adminoidc.public_base_urloidc.providersoauth.public_base_urloauth.providers
Important distinctions:
bootstrap_admincreates control-plane accessbootstrap_admin.require_password_changechanges first-login behaviorbootstrap_admin.passwordmust beliteral.*orenv.*
Seeded API keys are gateway caller credentials. They are useful for bootstrap automation and service-account workloads, but they are not upstream cloud provider service-account credentials. Each seeded key creates or reconciles an explicit gateway service account with an owning team and active budget.
Example seeded gateway key:
yaml
auth:
seed_api_keys:
- name: ci-indexer
value: env.CI_INDEXER_GATEWAY_API_KEY
service_account:
key: ci-indexer
name: CI Indexer
team: platform
budget:
cadence: daily
amount_usd: "25.0000"
hard_limit: true
timezone: UTC
allowed_models:
- gpt-4o-mini
- gemini-fastOperational guidance:
- store gateway API-key values in the deployment secret manager, not in YAML
- grant only the gateway models the workload needs
- declare the owning team in
teams - set a service-account budget before activating service-account traffic
- rotate by creating or seeding a replacement key, moving the caller, then revoking or removing the old key
OIDC providers use authorization-code login with provider discovery and ID-token verification:
yaml
auth:
oidc:
public_base_url: env.GATEWAY_PUBLIC_BASE_URL
providers:
- key: authentik
label: Authentik
issuer_url: https://auth.example.com/application/o/oceans-llm/
client_id: oceans-llm
client_secret: env.AUTHENTIK_OCEANS_LLM_CLIENT_SECRET
scopes: [openid, email, profile]
enabled: trueOAuth providers are separate from OIDC providers. GitHub is the first supported direct OAuth provider:
yaml
auth:
oauth:
public_base_url: env.GATEWAY_PUBLIC_BASE_URL
providers:
- key: github
label: GitHub
provider_type: github
client_id: env.GITHUB_OAUTH_CLIENT_ID
client_secret: env.GITHUB_OAUTH_CLIENT_SECRET
scopes: [read:user, user:email]
enabled: true
jit:
enabled: falseFor GitHub setup steps and callback URL rules, see GitHub OAuth SSO Setup for Admins.
For startup behavior and first access after boot, use runtime-bootstrap-and-access.md.
Declarative Teams And Users
teams and users extend the same startup seed path used for providers and models.
Important teams fields:
keynamebudget
Important users fields:
nameemailauth_modeglobal_rolerequest_logging_enabledoidc_provider_keyoauth_provider_keymembership.teammembership.rolebudget
Validation rules that matter:
- team keys must be unique
system-legacyhas no reserved meaning and is not a compatibility owner- user emails are normalized and must be unique
admin@localis reserved for the bootstrap adminusers[*].auth_modesupportspassword,oidc, andoauthoidc_provider_keyis required foroidcusers and rejected forpasswordandoauthusersoauth_provider_keyis required foroauthusers and rejected forpasswordandoidcusers- membership roles can be
adminormember - membership role
owneris rejected - budget amounts must be non-negative
Seed semantics that matter:
- listed teams are upserted by
teams[*].key - listed users are upserted by normalized email
- new config-seeded users are created as
invited - listed membership and active-budget state is reconciled for listed users and teams
- omitting a
budgetblock for a listed user or team deactivates that owner's active budget - unlisted teams and users are left untouched
OIDC and OAuth provider existence is validated at seed time against enabled runtime providers, not YAML parse time.
Service accounts are managed by admins. They are not a replacement spelling for auth.seed_api_keys.
budget_alerts
budget_alerts.email controls the background email dispatcher for threshold alerts created by budget enforcement and budget updates.
yaml
budget_alerts:
email:
from_email: [email protected]
from_name: "Oceans LLM"
poll_interval_secs: 30
batch_size: 25
transport:
kind: sinkImportant fields:
from_email- defaults to
alerts@local - cannot be empty
- defaults to
from_name- optional display name
poll_interval_secs- defaults to
30 - must be greater than zero
- defaults to
batch_size- defaults to
25 - must be greater than zero
- defaults to
transport.kindsink: persist alert delivery rows without sending emailsmtp: send through SMTP
SMTP transport fields:
hostport- defaults to
587
- defaults to
usernamepasswordstarttls- defaults to
true
- defaults to
username and password must be set together when SMTP authentication is used. password supports the same secret-reference forms as other config secrets.
Provider Types
Supported provider types in the checked-in configs:
openai_compatgcp_vertexaws_bedrock
Provider Auth Modes
| Provider type | Auth field | Expected secret material |
|---|---|---|
openai_compat | auth.token | bearer-style token |
gcp_vertex | auth.mode: adc | ADC available in the runtime environment |
gcp_vertex | auth.mode: service_account | upstream Google Cloud service-account JSON through credentials_path or an equivalent mounted secret path |
aws_bedrock | auth.mode: bearer | Bedrock bearer token, often env.AWS_BEARER_TOKEN_BEDROCK |
Provider auth config controls how the gateway authenticates to upstream providers. It is separate from gateway API keys, which authenticate callers to the gateway.
openai_compat
Important fields:
idbase_urlpricing_provider_idauth.kindauth.token- optional
display.label - optional
display.icon_key
display.icon_key currently accepts the checked-in provider icon codes used by the admin UI:
openaiopenrouteranthropicawsvertexai
Validation rules that matter:
pricing_provider_idcannot be emptypricing_provider_idmust map to a supported internal pricing family
gcp_vertex
Important fields:
idproject_idlocationapi_hostauth.mode- optional
display.label - optional
display.icon_key
Routing and pricing caveats:
upstream_modelmust use<publisher>/<model_id>- pricing identity is inferred from the publisher prefix
- Anthropic-on-Vertex pricing is only supported for
location=global - provider-specific configuration examples live in Google Vertex AI
aws_bedrock
Important fields:
idregionendpoint_url- optional
- defaults to
https://bedrock-runtime.{region}.amazonaws.com
auth.modedefault_headerstimeouts.total_ms- optional
display.label - optional
display.icon_key
Runnable auth mode:
yaml
providers:
- id: bedrock-api-key
type: aws_bedrock
region: us-east-1
auth:
mode: bearer
token: env.AWS_BEARER_TOKEN_BEDROCKdefault_chain and static_credentials use IAM SigV4 signing for Bedrock Runtime requests. bearer remains available for bearer-token based Bedrock access where applicable.
Routing caveats:
upstream_modelshould be the Bedrock Runtime model identity passed to Bedrock APIs: a base model ID such asanthropic.claude-3-5-sonnet-20240620-v1:0, an inference profile ID such asus.anthropic.claude-3-5-sonnet-20240620-v1:0, or a supported Bedrock ARN./v1/chat/completionsrouting is provider/model-specific in this slice: Claude non-streaming requests useInvokeModelwith Anthropic Messages, while Bedrock Converse and ConverseStream are used for supported Bedrock-native chat flows.- Route
streammay be enabled for Bedrock models that support streaming throughConverseStream; keepresponsesandembeddingscapability flagsfalse. /v1/responsesand/v1/embeddingsare not implemented foraws_bedrock.- Validate documentation-only updates with
mise run docs-check.
Model Config
Configured gateway models are either:
- provider-backed models with
routes - alias-backed models with
alias_of
A model cannot be both.
Important fields:
iddescriptiontagsrankroutesalias_of
Route Config
Important fields:
providerupstream_modelpriorityweightenabledcapabilitiescompatibilityextra_headersextra_body
Capability flags default permissively. A route can constrain provider capability. It cannot expand provider truth.
Compatibility metadata is separate from capabilities. Capabilities decide whether a route may execute; compatibility describes explicit request and stream-shape transforms for the selected provider route.
Capability flags include API-family gates such as chat_completions, responses, and embeddings, plus feature gates such as stream, tools, vision, json_schema, and developer_role.
OpenAI-compatible route profile:
yaml
models:
- id: fast
routes:
- provider: openrouter
upstream_model: openai/gpt-4o-mini
compatibility:
openai_compat:
supports_store: false
max_tokens_field: max_tokens
developer_role: system
reasoning_effort: omit
supports_stream_usage: trueOpenAI-compatible profile defaults:
| Field | Default | Supported values |
|---|---|---|
supports_store | true | true, false |
max_tokens_field | max_completion_tokens | max_completion_tokens, max_tokens |
developer_role | developer | developer, system |
reasoning_effort | passthrough | passthrough, omit, reasoning_object |
supports_stream_usage | false | true, false |
The current openai_compat profile fields are Chat Completions transforms. /v1/responses is a separate supported API family and is not adapted by reusing Chat Completions compatibility shims.
Do not use extra_body for compatibility transforms. extra_body remains for additive provider-specific overrides, and the typed compatibility profile remains authoritative when a declared transform conflicts with an additive override.
Route Examples
OpenAI direct routes usually need no compatibility overrides:
yaml
models:
- id: openai-direct
routes:
- provider: openai-prod
upstream_model: gpt-5OpenAI-compatible aggregator routes should declare known Chat Completions quirks explicitly:
yaml
models:
- id: openrouter-fast
routes:
- provider: openrouter
upstream_model: openai/gpt-4o-mini
compatibility:
openai_compat:
supports_store: false
max_tokens_field: max_tokens
developer_role: system
reasoning_effort: omit
supports_stream_usage: trueVertex Google routes use the Vertex provider and a publisher-qualified upstream model:
yaml
models:
- id: gemini-fast
routes:
- provider: vertex-adc
upstream_model: google/gemini-2.0-flash
capabilities:
chat_completions: true
responses: false
embeddings: falseBedrock routes can execute Chat Completions through Claude native Messages, Converse, and ConverseStream depending on the upstream model and request shape. Keep Responses and embeddings disabled:
yaml
models:
- id: claude-bedrock
routes:
- provider: bedrock
upstream_model: us.anthropic.claude-3-5-sonnet-20240620-v1:0
capabilities:
chat_completions: true
responses: false
embeddings: false
stream: trueOpenAI-compatible embeddings-only routes should narrow route capability so chat and Responses requests fail early:
yaml
models:
- id: text-embedding
routes:
- provider: openai-prod
upstream_model: text-embedding-3-small
capabilities:
chat_completions: false
responses: false
embeddings: true
stream: falseValidation and Failure Boundaries
Config load catches several classes of failure up front:
- invalid or empty provider fields
- unsupported pricing-provider mappings
- invalid alias references
- invalid route or provider wiring
Later failures are usually runtime problems such as:
- request resolution failure
- missing providers
- capability mismatch
- exact-pricing gaps
Current Boundaries
- Declarative teams, password users, OIDC users, memberships, active budgets, and OIDC providers are part of the current seed contract.
- OIDC JIT defaults are provider configuration, not claim or group mapping.
- Existing password users are not auto-linked to SSO users by email.
What This Page Does Not Own
- startup behavior and first access:
- request routing and
/v1/*behavior: - cross-cutting request cause and effect:
- spend windows and budget policy:
- OIDC and SSO behavior:
