Skip to main content

Provider proxy

This step is optional. You only need it to run built-in coding agents, which are type: agent Tasks running Codex, Claude Code, GitHub Copilot CLI, or OpenCode. Install Orka first, then come back here.

Fastest path

Have an OpenAI API key? Jump to With provider API keys, then Connect the gateway. Have an OpenAI Codex or GitHub Copilot subscription instead? Use With a Codex subscription or With a GitHub Copilot subscription. Either way it is one gateway install, one values file, and one helm upgrade.

AI-worker tasks, type: ai, do not use a gateway. They read your Provider resources and their API-key Secrets directly, and they work as soon as Orka is installed.

Coding agents are different. They are third-party CLIs, so Orka never hands them a provider API key. Instead, they talk to a model gateway that you run and that holds the real credentials:

coding agent → session proxy → Orka auth proxy → your gateway → model provider

Orka's auth proxy authenticates each runtime request and forwards it to your gateway. Coding agents receive only a session token and permission to use their configured model. The gateway supplies its own provider credentials.

Choose a model gateway

Any gateway that serves the APIs your agents need will work. Codex uses the OpenAI Responses API, Claude Code uses the Anthropic Messages API, and OpenCode uses Chat Completions. Vekil is the gateway Orka's own tests use, and the example below installs it. agentgateway is another option.

Whatever you choose, configure its providers and models, and verify a model request succeeds through it before connecting Orka.

Example: Vekil on the same cluster

Vekil is a small reverse proxy that fronts GitHub Copilot, OpenAI, Azure OpenAI, Anthropic, and other providers behind one endpoint. It ships as a container image, ghcr.io/sozercan/vekil, listening on port 1337. Run it as a Deployment and Service named vekil in a vekil-system namespace, following its getting started and configuration docs, and give it credentials in one of the ways below. Each is a Vekil configuration; Vekil's provider routing and provider API keys pages have the details and more providers.

With provider API keys

Vekil reads provider keys from environment variables that you back with Kubernetes Secrets, referenced from a providers file with api_key_env. Never put a key in the file itself. This example exposes one OpenAI model; keep the model IDs you plan to use in Orka.

providers.yaml
providers:
- id: openai
type: openai-compatible
default: true
base_url: https://api.openai.com/v1
api_key_env: OPENAI_API_KEY
models:
- public_id: gpt-6-astra
deployment: gpt-6-astra
endpoints:
- /responses
- /chat/completions

For Azure OpenAI, use type: azure-openai with your resource's base URL and deployment names:

providers:
- id: azure-openai
type: azure-openai
default: true
base_url: https://<resource>.cognitiveservices.azure.com/openai/v1
api_key_env: AZURE_OPENAI_API_KEY
models:
- public_id: gpt-6-astra
deployment: <your-deployment-name>
endpoints:
- /responses

Mount the file as Vekil's --providers-config and set OPENAI_API_KEY (or the name you chose) from a Secret in the Vekil Deployment.

With an OpenAI Codex subscription

Vekil can use the ChatGPT login that the Codex CLI stores after codex login. Copy that file into a Secret and mount it into the Vekil Deployment at the Codex home path Vekil documents:

codex login
kubectl -n vekil-system create secret generic codex-auth \
--from-file=auth.json="$HOME/.codex/auth.json"
providers.yaml
providers:
- id: openai-codex
type: openai-codex
default: true

When the stored login expires, run codex login again and recreate the Secret.

With a GitHub Copilot subscription

Without a providers file, Vekil uses GitHub Copilot as its only upstream. Set COPILOT_GITHUB_TOKEN in the Vekil Deployment from a Secret holding a GitHub token for a user with Copilot access. Without a token, Vekil starts a device-code login and prints the code and URL in its Pod logs:

kubectl -n vekil-system logs deploy/vekil

Verify Vekil

Do not continue until readiness passes and the model you plan to use appears in the model list. A gateway that is up but cannot reach its provider makes every agent Task fail with an authentication error that looks like an Orka problem.

kubectl -n vekil-system port-forward svc/vekil 1337:1337 &
curl http://127.0.0.1:1337/readyz
curl http://127.0.0.1:1337/v1/models
kill %1

Allow Orka to reach Vekil

If your cluster enforces NetworkPolicy and the vekil-system namespace restricts ingress, allow traffic from Orka's auth proxy:

kubectl -n vekil-system apply -f - <<'YAML'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-orka-provider-proxy
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: vekil
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: orka-system
podSelector:
matchLabels:
orka.ai/network-role: provider-auth-proxy
ports: [{protocol: TCP, port: 1337}]
YAML

Then continue to Connect the gateway.

Connect the gateway

The Helm chart leaves providerProxy.enabled=false until you configure it. Save your connection settings in a values file, for example model-access.yaml:

model-access.yaml
providerProxy:
enabled: true
upstreamBaseURL: http://vekil.vekil-system.svc:1337

That is all the chart needs when the gateway is a Service in your cluster. At install time it reads the Service named in the URL and writes the NetworkPolicy rule that lets Orka's proxy reach that Service's Pods on their listening port, and nothing else. DNS access is included.

For a gateway outside the cluster, a Service whose target port is a name rather than a number, or an offline render such as helm template, spell the rule out instead. The egress port is the gateway Pod's listening port, which can differ from its Service port:

providerProxy:
enabled: true
upstreamBaseURL: http://vekil.vekil-system.svc:1337
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vekil-system
podSelector:
matchLabels:
app.kubernetes.io/name: vekil
ports:
- protocol: TCP
port: 1337

The chart does not create resources in the gateway's namespace or change its ingress policy, so allow ingress from Orka's namespace and Pods labeled orka.ai/network-role: provider-auth-proxy yourself, as shown for Vekil above.

Apply the values to your release. The installed chart version keeps the upgrade on the same release, and --reuse-values keeps your existing Secret and image settings:

CHART_VERSION="$(helm get metadata orka -n orka-system -o yaml | awk '/^version:/ {print $2}')"
helm upgrade orka orka/orka --version "$CHART_VERSION" --namespace orka-system \
--reuse-values --values model-access.yaml --wait

For a source installation, run from the same checkout and use its generated chart:

helm upgrade orka ./manifest_staging/charts/orka --namespace orka-system \
--reuse-values --values model-access.yaml --wait

Check that the proxy is ready:

kubectl -n orka-system get deploy -l app.kubernetes.io/component=provider-auth-proxy

Now run a coding agent. The Agent's model.name must be a model ID your gateway lists.

Built-in coding agents cannot start without this connection. Creating a Provider resource for AI-worker tasks does not configure the coding-agent gateway.

Rotating the proxy token

The proxy reloads its mounted Secret every five seconds. To rotate without dropping requests, keep the old token as previous-token and set previous-token-valid-until to an absolute RFC3339 deadline. The overlap defaults to ten minutes and cannot exceed 24 hours.

  • When updating the proxy first, publish the new current token and old previous token, wait for reload, then roll the controller and runtime pools.
  • When updating the controller first, pre-stage the new token as previous while current stays old. Verify it through the proxy, then swap the tokens and roll.

Remove the old token once every workload reports the new generation. If a token file becomes unreadable or invalid, readiness and authenticated forwarding stop until the files are valid again.

Troubleshooting

SymptomCheck
Chart rejects upstreamBaseURLUse an HTTP(S) URL without credentials, a query, or a fragment.
Chart says the upstream Service was not foundInstall the gateway before enabling the proxy, or set providerProxy.egress explicitly; offline renders cannot look Services up.
Chart asks for providerProxy.egressThe upstream is not an in-cluster <service>.<namespace>.svc address, or its Service uses a named target port. Write the egress rule by hand.
Agent Task fails with an authentication errorCheck the gateway's readiness endpoint and provider credentials first. It fails independently of Orka.
Model calls time outCheck gateway readiness, egress rules, and gateway ingress policy.
Model calls return 404Check that the model ID is listed by the gateway and that the upstream URL has no extra path.
Requests fail after token rotationCheck the overlap token and its expiry.

See Troubleshooting for other installation and runtime errors.