Choosing a Credential Mode
Security Overview | mTLS | Bundle Signing | Credential Encryption | Credential Modes
This guide explains the ways Axemere Gateway can hold and deliver your AI provider API keys, and how to pick the right one for your deployment.
Table of Contents
- Quick Answer
- The Modes
- Comparison
- Setup Examples
- Credential Scope and Distribution
- Rotating a Credential
- Troubleshooting
Quick Answer
| I want... | Use |
|---|---|
| Simplest setup: add key in console and go | inline |
| My API key to never leave my own infrastructure | alias |
| Each of my users to use their own org key (via header) | byok |
| Claude CLI users to route through the gateway with their own subscription | oauth passthrough |
| Each developer to use their own API key via the gateway | byok_header passthrough |
The Modes
inline — Axemere manages your key
You paste your API key into the Axemere console. The control plane encrypts it with AES-256-GCM and stores it in the database. When the gateway processes a request, it receives the decrypted key over an mTLS-authenticated channel and uses it to authenticate the upstream call.
Your key is encrypted at rest. A database backup or SQL injection attack yields only ciphertext; the encryption key is never in the database. See Credential Encryption for details.
Zero-config on the gateway. No environment variables to set, no files to manage. Add the key in the console; the gateway starts routing immediately.
Tradeoff: Your API key exists in the Axemere control plane database (encrypted) and briefly in gateway memory during active requests. If your security policy requires that API keys never leave your infrastructure, use alias instead.
alias — Your key stays on your gateway host
You set your API key as an environment variable on the gateway host and register only the variable name with the control plane. The control plane never sees the key itself, only a pointer.
Console: name = OPENAI_API_KEY
Gateway host: export OPENAI_API_KEY=sk-...
At request time, the gateway reads os.Getenv("OPENAI_API_KEY") and uses the result. The control plane has no access to the secret value, ever.
Your key never leaves your infrastructure. Appropriate for organizations whose security policy prohibits sending API keys to external services.
Tradeoff: You must set the environment variable on every gateway host and restart (or trigger a reload) when the variable is updated. The zero-config console experience does not apply: adding a key in the console without setting the env var results in a 403 with a diagnostic message.
byok — You supply the key per-request (header)
No key is stored anywhere. Each API call includes the key in the request via the X-MVGC-BYOK-Secret header. The gateway applies policy and audit but does not store or inject credentials.
This is appropriate when:
- Each caller (user, tenant, application) has their own API key
- You want the gateway purely as a policy and audit layer
- You cannot store keys in any external system
Tradeoff: Every caller must supply their key on every request. Not compatible with transparent proxy mode or zero-config SDK setup.
oauth — Client uses their subscription token
The client sends their AI provider subscription OAuth token in the Authorization: Bearer header. The gateway forwards it unchanged to the provider. No key is stored on the gateway.
This is the correct mode for Claude CLI users who have a paid Claude subscription: the Claude CLI automatically sends its subscription token to ANTHROPIC_BASE_URL when ANTHROPIC_API_KEY is not set in the environment.
Cost: Estimated at market API rates using provider pricing data. These estimated costs count toward project budgets and alert thresholds the same way API key spend does. Your actual subscription charges with the provider are determined by your agreement with them directly.
Tradeoff: Cost figures are estimates at market API rates: they reflect what equivalent API calls would cost, not what the customer's subscription actually charges. Org policy enforces rate limits, budgets (against the estimated cost), and allow/deny rules.
Enabled per provider via the credential-oauth-{provider} addon. See Enabling OAuth passthrough for Claude CLI.
byok_header — Client uses their own API key (native header)
The client sends their own AI provider API key in the provider's native authentication header. The gateway forwards the key in that header to the upstream. No key is stored on the gateway.
| Provider | Header |
|---|---|
| Anthropic | Authorization: Bearer sk-ant-... |
| OpenAI | Authorization: Bearer sk-... |
| Gemini | x-goog-api-key: AIzaSy-... |
| Azure OpenAI | api-key: <key> |
Cost: Billed at the standard provider API rate. The gateway estimates token usage and enforces org budget limits.
Tradeoff: Every developer must supply their own API key on every request. The gateway audits all usage but cannot prevent a developer from calling the provider directly (bypassing the gateway).
Enabled per provider via the credential-byok-{provider} addon. See Enabling BYOK passthrough for a provider.
Combined Passthrough — when the provider can't tell OAuth from BYOK
oauth and byok_header are listed above as independent modes because for most providers they arrive on different signals and don't collide. But for providers where an OAuth subscription token and a BYOK API key are indistinguishable from the request alone (currently Anthropic and OpenAI, both of which send everything as Authorization: Bearer <value>), the gateway can't offer oauth and byok_header as two independently-toggleable addons for that provider. It exposes one instead: Combined Passthrough, enabled via the credential-passthrough-{provider} addon (mutually exclusive with credential-oauth-{provider} / credential-byok-{provider} for that provider; the gateway offers one or the other, never both).
With Combined Passthrough enabled, any non-empty Authorization: Bearer value the client sends takes priority over the org's stored credential (inline/alias) and is forwarded upstream verbatim; the gateway has no way to verify whether it's a real OAuth token, a real API key, or anything else.
Watch for SDK placeholder keys. Some SDKs require a non-empty API key env var even when you intend the gateway to inject your stored
inline/aliascredential, so setups commonly set it to a placeholder value like"placeholder"or"unused"(see Gateway Keys → Using a Key). If Combined Passthrough is enabled for that provider, the placeholder is treated as a real client-supplied credential: it's forwarded to the provider (which rejects it with a genuine 401); yourinline/aliascredential is silently never used, and nothing in the console or logs flags what happened. If you want the gateway to always use your stored credential for a provider, leave Combined Passthrough disabled for it.
Comparison
| inline | alias | byok | oauth | byok_header | |
|---|---|---|---|---|---|
| API key stored by Axemere | Yes (encrypted) | No | No | No | No |
| Setup required on gateway host | None | Set env var | None | Enable addon | Enable addon |
| Zero-config after console setup | Yes | No | No | No | No |
| Key leaves customer infrastructure | Yes (to Axemere CP) | No | No | No | No |
| Works with transparent proxy mode | Yes | Yes (if env var is set) | No | Yes | Yes |
| Key rotation | Update in console | Update env var | Per-request | Via provider | Per-request |
| Cost tracking | Provider rate | Provider rate | Provider rate | Estimated market rate | Provider rate |
| Recommended for managed gateways | Yes | — | — | — | — |
| Recommended for self-hosted | Yes (if CP is trusted) | Yes | — | Claude CLI users | Developer BYOK |
| Recommended for per-caller isolation | — | — | Yes | — | Yes |
Setup Examples
Setting up an inline credential
- In the Axemere console, go to Credentials → Add Credential
- Select your provider (e.g. OpenAI)
- Choose "Axemere manages your key" (inline mode)
- Paste your API key
- Click Save
The console will display your gateway's proxy URL immediately:
OPENAI_BASE_URL=https://<gateway>/proxy/openai
No changes needed on the gateway host.
Setting up an alias credential
-
On your gateway host, set the environment variable:
export OPENAI_API_KEY=sk-...For Kubernetes deployments, add it as a Secret and reference it in the Deployment env:
env: - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: provider-keys key: openai-api-key -
In the Axemere console, go to Credentials → Add Credential
-
Select your provider
-
Choose "Keep your key local" (alias mode)
-
Enter the environment variable name:
OPENAI_API_KEY -
Click Save
The gateway will call os.Getenv("OPENAI_API_KEY") at request time. If the variable is not set, requests will fail with a 403 and a diagnostic message telling you exactly which variable is missing.
Using byok in a request
Include X-MVGC-BYOK-Secret in your HTTP request headers:
curl https://<gateway>/v1/chat/completions \ -H "X-MVGC-Org-ID: org-123" \ -H "X-MVGC-Workload-ID: default" \ -H "X-MVGC-Target-Host: api.openai.com" \ -H "X-MVGC-BYOK-Secret: sk-..." \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[...]}'
No credential record is needed for byok; the gateway uses the supplied key directly.
Enabling OAuth passthrough for Claude CLI
OAuth passthrough is enabled per provider via the admin API. This example enables it for Anthropic so Claude CLI users can route through the gateway using their Claude subscription.
-
Enable the addon for your org:
curl -s -X POST http://localhost:7080/v1/orgs/ORG_ID/addons/credential-oauth-anthropic/enable \ -H "MVGC-Admin-Token: ${MVGC_ADMIN_TOKEN}"Or with the
mvgcCLI:mvgc addons enable --org-id ORG_ID credential-oauth-anthropic -
Share the gateway proxy URL and the
pclaudesetup with your users. See Claude CLI Setup for the user-facing instructions.
Enabling BYOK passthrough for a provider
This example enables BYOK passthrough for OpenAI so developers can supply their own OpenAI API key via the gateway.
-
Enable the addon for your org:
curl -s -X POST http://localhost:7080/v1/orgs/ORG_ID/addons/credential-byok-openai/enable \ -H "MVGC-Admin-Token: ${MVGC_ADMIN_TOKEN}" -
Developers include their key in the
Authorizationheader of their requests:curl https://gateway/proxy/openai/... \ -H "Authorization: Bearer sk-my-own-openai-key" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[...]}'For Gemini, the key goes in
x-goog-api-key. For Azure OpenAI, useapi-key.
Credential Scope and Distribution
Every credential has two independent dimensions: scope (which requests it resolves for) and distribution (which gateway nodes can access it). Understanding how they interact prevents silent failure modes.
Scope: which requests resolve this credential
| Scope | Behaviour |
|---|---|
| Org Default | Fallback for any request that doesn't match a more specific scope. One default per provider + mode combination. |
| Workload | Resolves only for requests from the specified workloads. Overrides the org default for those workloads. Requires Core Platform. |
| Project | Resolves only for requests attributed to the specified projects. Overrides the org default for those projects. Requires Core Platform. |
Scope determines credential selection: the control plane evaluates it before the request reaches the gateway node.
Distribution: which gateway nodes can use it
| Distribution | Behaviour |
|---|---|
| Org-wide | All registered gateway nodes in the org receive this credential. |
| Node-scoped | Only the nodes you explicitly assign can decrypt and use this credential. |
Distribution determines credential delivery: which nodes the control plane pushes the credential to.
Edge case: Org Default with Node-scoped distribution
This combination is valid but carries a significant risk: the org default credential exists and will be selected by the CP for any unscoped request, but only the assigned nodes can actually use it. Requests arriving on an unassigned node will fail to resolve a credential; there is no fallback.
When it makes sense: Staged rollout of a new key: you assign it to a canary node first, verify it works, then expand assignment. During the rollout window, unassigned nodes continue using whatever they had before (or fail if no prior default existed).
When it's a problem: If this is your only org default for a provider and you want all traffic to route through it, node-scoped distribution leaves unassigned nodes with no credential at all.
The Axemere console shows an amber warning when you attempt to create an org default credential with node-scoped distribution, prompting you to consider org-wide distribution if full coverage is the intent.
Rotating a Credential
inline: Update the key in the Axemere console. The change propagates to all gateways within the cache TTL (up to 60 seconds for self-hosted; near-instant for managed gateways via the streaming config channel).
alias: Update the environment variable on the gateway host. For long-running processes, either restart the gateway or trigger a config reload. If using Kubernetes, update the Secret and roll the Deployment.
byok: No rotation needed; each caller controls their own key.
Troubleshooting
403: alias credential — env var OPENAI_API_KEY is not set on this gateway
The credential is registered as mode:alias with secret_ref: OPENAI_API_KEY, but the variable is not set on the gateway host. Set it and restart (or reload) the gateway.
403: inline credential — stored secret is empty
The credential record exists but has no secret stored. Re-add the API key in the console by editing the credential.
403: No credential configured for openai
No credential exists for this provider in your org, or the policy auto-rules have not been generated yet. Add an API key in the console. If the issue persists after adding a key, check the gateway policy bundle staleness; the updated policy may not have propagated yet.
401 from upstream provider
If this occurs with mode:alias, the environment variable is set but contains an invalid or expired key. Verify the key value and update it if needed.
403: credential mode "oauth" requires a client-supplied auth header
The OAuth passthrough addon is enabled but the client's request arrived without an Authorization header. The most common cause is that ANTHROPIC_API_KEY is set in the environment: the Claude CLI will use that key instead of the subscription token, but it will not be forwarded in passthrough mode. Unset ANTHROPIC_API_KEY when using pclaude. See Claude CLI Setup.
OAuth passthrough is enabled but gateway still uses the CP credential
The policy rules select based on header presence and content. Verify the client is sending an Authorization header with the expected value. Check with mvgc addons credential-modes --org-id ORG_ID that the addon is enabled.
Stored inline/alias credential is being ignored, and the provider returns a genuine 401
Check whether Combined Passthrough is enabled for this provider (credential-passthrough-{provider} addon, shown as "Combined Passthrough" in the console). If enabled, any non-empty Authorization: Bearer header from the client, including SDK placeholder values such as "placeholder" or "unused", is forwarded upstream in place of your stored credential, with no console or log indication that this happened. Disable the addon if you want the gateway to always use the stored inline/alias key for this provider. See Combined Passthrough for the full mechanism.