Skip to Content

Model

A Model defines an AI language model endpoint that agents call. Each model names a provider (the backend client), a model identifier, and a provider-specific config block holding the base URL, credentials, and generation properties. Agents reference a model by name via modelRef, falling back to the model named default when none is set. For a task-oriented walkthrough see User Guide → Configure models; this page is the field-by-field reference.

Spec

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: default spec: # --- Required ---------------------------------------------------------- provider: openai # openai | azure | bedrock | anthropic model: value: gpt-4o # model identifier (ValueSource) config: # exactly one provider block below openai: baseUrl: value: "https://api.openai.com/v1" apiKey: valueFrom: secretKeyRef: name: default-model-token key: token # --- Common optional fields -------------------------------------------- type: completions # DEPRECATED selector; default 'completions' pollInterval: 1m # health-probe interval (default '1m')

Fields

FieldTypeRequiredDescription
spec.providerenum (openai, azure, bedrock, anthropic)yesSelects the backend client. This is the authoritative selector — the matching config.<provider> block must be present.
spec.modelValueSourceyesThe model identifier (e.g. gpt-4o, us.anthropic.claude-3-5-haiku-20241022-v1:0). Supports value or valueFrom (secretKeyRef, configMapKeyRef, serviceRef, queryParameterRef).
spec.configModelConfigyesProvider-specific configuration. Holds exactly one of openai, azure, bedrock, anthropic, matching spec.provider.
spec.typeenum (completions, openai, azure, bedrock, anthropic)noDeprecated. Default completions. Legacy provider values (openai, azure, bedrock) are migrated to spec.provider by the mutating webhook. Use spec.provider instead — spec.type will be removed in release 1.0.
spec.pollIntervaldurationnoHow often the controller probes the model for health. Defaults to 1m.

Provider config fields

spec.config carries one block keyed by provider. Every credential/URL field is a ValueSource (direct value or valueFrom a Secret, ConfigMap, service, or query parameter).

Provider blockFieldTypeRequiredDescription
config.openaibaseUrlValueSourceyesAPI endpoint URL.
apiKeyValueSourceyesAPI key. Store in a Secret.
headers[][]HeadernoCustom HTTP headers.
propertiesmap[string]ValueSourcenoGeneration parameters (temperature, max_tokens, …).
config.azurebaseUrlValueSourceyesAzure OpenAI resource URL.
authAzureAuthnoExactly one of apiKey, managedIdentity, workloadIdentity.
apiKeyValueSourcenoDeprecated — use auth.apiKey. Accepted when auth is unset.
apiVersionValueSourcenoAzure API version (e.g. 2024-12-01-preview).
headers[][]HeadernoCustom HTTP headers.
propertiesmap[string]ValueSourcenoGeneration parameters.
config.bedrockregionValueSourcenoAWS region.
baseUrlValueSourcenoOverride endpoint (defaults to the AWS Bedrock endpoint).
accessKeyIdValueSourcenoExplicit credential (defaults to the IAM role).
secretAccessKeyValueSourcenoExplicit credential.
sessionTokenValueSourcenoTemporary-credential / JWT token.
modelArnValueSourcenoCustom model ARN.
maxTokensint (1–100000)noMax response tokens.
temperaturestring (01)noSampling temperature, as a string.
propertiesmap[string]ValueSourcenoGeneration parameters.
config.anthropicbaseUrlValueSourceyesAnthropic API URL.
apiKeyValueSourceyesAPI key. Store in a Secret.
versionValueSourcenoAnthropic API version header.
headers[][]HeadernoCustom HTTP headers.
propertiesmap[string]ValueSourcenoGeneration parameters.

Providers

OpenAI

The openai provider supports any OpenAI-specification-compatible endpoint, including OpenAI itself and OpenAI-compatible gateways.

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: default spec: provider: openai type: completions # legacy; defaults to 'completions' model: value: gpt-4o config: openai: baseUrl: value: "https://api.openai.com/v1" # Store the key in a Secret rather than inline. apiKey: valueFrom: secretKeyRef: name: default-model-token key: token properties: temperature: value: "0.7" max_tokens: value: "4096" --- apiVersion: v1 kind: Secret metadata: name: default-model-token type: Opaque stringData: token: "your-api-key-here"

Create the API-key Secret directly with:

kubectl create secret generic default-model-token --from-literal=token="your-api-key-here"

Azure OpenAI

Azure models support three authentication methods via config.azure.auth: API Key (default), Managed Identity (AKS node identity), and Workload Identity (Kubernetes ServiceAccount federated to Azure). Set exactly one.

API Key (explicit or legacy):

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: gpt-4o-mini spec: provider: azure type: completions model: value: gpt-4o-mini config: azure: baseUrl: value: "https://your-resource.openai.azure.com" auth: apiKey: valueFrom: secretKeyRef: name: azure-openai-key key: token apiVersion: value: "2024-12-01-preview"

The top-level config.azure.apiKey field still works but is deprecated in favour of config.azure.auth.apiKey.

Managed Identity (AKS): Use when Ark runs on AKS and the cluster or node pool has a User-Assigned Managed Identity with access to the Azure OpenAI resource. No API key is stored on the cluster.

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: gpt-4o-managed-identity spec: provider: azure model: value: gpt-4o config: azure: baseUrl: value: "https://your-resource.openai.azure.com" apiVersion: value: "2024-02-15-preview" auth: managedIdentity: {} # Or with a user-assigned identity: # managedIdentity: # clientId: # value: "12345678-1234-1234-1234-123456789abc"

Workload Identity: Use when running on any Kubernetes cluster (including non-Azure) with Azure Workload Identity configured. The pod’s ServiceAccount is federated to an Azure Managed Identity. Both clientId and tenantId are required.

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: gpt-4o-workload-identity spec: provider: azure model: value: gpt-4o config: azure: baseUrl: value: "https://your-resource.openai.azure.com" apiVersion: value: "2024-02-15-preview" auth: workloadIdentity: clientId: value: "12345678-1234-1234-1234-123456789abc" tenantId: value: "87654321-4321-4321-4321-210987654321"

AWS Bedrock

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: claude-haiku spec: provider: bedrock type: completions model: value: "us.anthropic.claude-3-5-haiku-20241022-v1:0" config: bedrock: # AWS region (optional). region: value: "us-west-2" # Base URL (optional — only needed for a non-default endpoint). baseUrl: value: "https://aws-bedrock.prod.ai-gateway.quantumblack.com/your-project-id" # API key (bearer token) - alternative to IAM credentials. # When set, it takes precedence and IAM credentials are ignored. apiKey: valueFrom: secretKeyRef: name: bedrock-credentials key: bedrock-api-key # Explicit credentials (optional, defaults to IAM role) accessKeyId: valueFrom: secretKeyRef: name: aws-credentials key: access-key-id secretAccessKey: valueFrom: secretKeyRef: name: aws-credentials key: secret-access-key # Session token for temporary credentials or JWT tokens. sessionToken: valueFrom: secretKeyRef: name: aws-credentials key: session-token # Custom model ARN (optional). modelArn: value: "arn:aws:bedrock:..." properties: temperature: value: "0.7" max_tokens: value: "4096"

Bedrock supports two authentication methods:

  • API key (apiKey) — a Bedrock bearer token. The executor authenticates with Authorization: Bearer <key>, bypassing SigV4 signing.
  • IAM credentials (accessKeyId / secretAccessKey / sessionToken) — or, if all are omitted, the pod’s IAM role via the AWS default credential chain.

When both apiKey and IAM credentials are set, the API key takes precedence and the IAM credentials are ignored, even when IAM credentials are also present in the executor environment. The mutating webhook stamps a non-blocking ark.mckinsey.com/migration-warning/bedrock-auth annotation in this case. A configured apiKey that cannot be resolved (missing Secret or empty value) fails loudly rather than silently falling back to IAM.

Google Gemini and Anthropic Models

Both Google Gemini and Anthropic provide OpenAI-compatible endpoints, allowing you to use their models with the openai provider. The base URLs are:

  • https://generativelanguage.googleapis.com/v1beta/openai for Google Gemini
  • https://api.anthropic.com/v1 for Anthropic Claude

Most other providers also support OpenAI compatible base URLs - check their docs for details.

Anthropic

The anthropic provider talks to the Anthropic Messages API natively — you do not need an OpenAI-compatible endpoint. The completions executor converts between Ark’s internal message format and the Messages API (including tool use and system prompts), so you point it straight at Anthropic’s own API:

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: claude spec: provider: anthropic model: value: claude-3-5-sonnet-20241022 config: anthropic: baseUrl: value: "https://api.anthropic.com/v1" # the native Messages API endpoint apiKey: valueFrom: secretKeyRef: name: anthropic-key key: token version: value: "2023-06-01" # optional; sets the anthropic-version header

The optional version field sets the anthropic-version request header. This provider works with any Messages-API-compatible endpoint, including Anthropic direct and gateways that expose the Messages API.

Anthropic also publishes an OpenAI-compatible endpoint, so if you prefer you can reach it through the openai provider with baseUrl: https://api.anthropic.com/v1 instead — but the native anthropic provider is the recommended path for Claude.

Google Gemini

Google Gemini has no dedicated provider — reach it through the openai provider against Gemini’s OpenAI-compatible endpoint:

  • https://generativelanguage.googleapis.com/v1beta/openai — Google Gemini

Most other providers publish OpenAI-compatible base URLs too — check their docs.

Model properties

Every provider block supports a properties map for generation parameters. Values are passed through to the underlying chat-completion call.

spec: provider: openai model: value: gpt-4o config: openai: baseUrl: value: "https://api.openai.com/v1" apiKey: valueFrom: secretKeyRef: name: openai-secret key: token properties: temperature: value: "0.1" max_tokens: value: "1000"

Any OpenAI ChatCompletion parameter is accepted, including temperature, max_tokens, top_p, frequency_penalty, presence_penalty, stop, and seed.

Custom HTTP headers

The openai, azure, and anthropic provider blocks accept headers[] for advanced authentication and routing. Each header value is a direct value or loaded valueFrom a Secret or ConfigMap.

apiVersion: ark.mckinsey.com/v1alpha1 kind: Model metadata: name: gateway-model spec: provider: azure type: completions model: value: gpt-4o config: azure: baseUrl: value: "https://your-resource.openai.azure.com" auth: apiKey: valueFrom: secretKeyRef: name: azure-openai-key key: token apiVersion: value: "2024-12-01-preview" headers: # Direct value. - name: X-Client-ID value: value: "production-client" # From a Secret. - name: X-API-Gateway-Key value: valueFrom: secretKeyRef: name: gateway-credentials key: api-key # From a ConfigMap. - name: User-Agent value: valueFrom: configMapKeyRef: name: app-config key: user-agent

Status

status: resolvedAddress: "https://api.openai.com/v1" conditions: - type: ModelAvailable status: "True" reason: Available message: "Model is available and probed successfully" lastTransitionTime: "2026-01-15T10:30:00Z"

The controller probes each model every spec.pollInterval and records the result in the ModelAvailable condition.

Status fields

FieldDescription
status.resolvedAddressThe resolved base URL the controller reached during the health probe.
status.conditions[]Standard Kubernetes conditions. ModelAvailable reflects the health probe.

ModelAvailable states:

StatusReasonMeaning
TrueAvailableModel responded to the probe successfully.
FalseModelProbeFailedProbe failed (network, authentication, or configuration error) — details in message.
UnknownInitializingInitial state before the first probe completes.

kubectl get models prints:

ColumnSource
NAMEmetadata.name
TYPE.spec.type
PROVIDER.spec.provider
MODEL.spec.model.value
AVAILABLEModelAvailable condition status
AGEmetadata.creationTimestamp
kubectl get models NAME TYPE PROVIDER MODEL AVAILABLE AGE default completions azure gpt-4.1-mini True 5m claude-haiku completions bedrock claude-3-haiku False 3m

Use kubectl describe model <name> for the full condition message.

Migration: typeprovider

spec.provider is the current backend selector; spec.type is deprecated. For backward compatibility, when spec.provider is empty and spec.type holds a legacy provider value (openai, azure, or bedrock), the mutating webhook copies it into spec.provider, resets spec.type to completions, and stamps an ark.mckinsey.com/migration-warning-provider annotation. A model with neither spec.provider nor a migratable spec.type is rejected with provider is required. Set spec.provider explicitly and leave spec.type at its completions default (or omit it).

  • Agents — reference a model via spec.modelRef.
  • Query — target a model directly with target.type: model.
  • Secrets & authentication — storing API keys and credentials for model config.
Last updated on