Problem you're trying to solve
ASSERT uses LiteLLM's openai/* provider for OpenAI-compatible endpoints. LiteLLM sends OPENAI_API_KEY as standard Bearer authentication, but some API-management gateways require the same credential in an additional provider-specific header such as api-key or Ocp-Apim-Subscription-Key.
Today ASSERT has no supported configuration for this header. Model configuration covers the model name and generation parameters, but not gateway authentication headers. As a result, a gateway can successfully expose /v1/models and /v1/chat/completions while ASSERT receives 401 Unauthorized because its request contains only Bearer authentication.
This affects more than one call site:
- pipeline Chat Completions and Responses calls in the core model client
assert-ai init
- ACS language-model generation
A caller cannot solve this once through eval_config.yaml or a CLI option, and embedding the secret directly in config would be unsafe.
Proposed solution or behavior
Add an opt-in way to send OPENAI_API_KEY under a configurable compatibility-header name. One possible environment contract is:
OPENAI_BASE_URL=https://gateway.example/openai/v1
OPENAI_API_KEY=<secret>
ASSERT_OPENAI_API_KEY_HEADER=api-key
Expected behavior:
- when the header-name setting is absent, preserve current behavior exactly
- when configured, add
{<configured-name>: OPENAI_API_KEY} to LiteLLM extra_headers
- apply it consistently to Chat Completions, Responses,
assert-ai init, and ACS calls
- scope automatic injection to OpenAI-compatible model routes so gateway credentials are not sent to Azure, Anthropic, or other providers
- let explicit per-call headers take precedence
- redact the configured header value from logs, traces, request payloads, and generated artifacts
- fail clearly if an invalid header configuration is provided
- document the setting in
.env.example and provider setup guidance
- add regression tests covering disabled-by-default behavior, provider scoping, header precedence, and each LiteLLM call path
The exact public name/API is open to maintainer preference; the important requirement is one safe, reusable configuration point for OpenAI-compatible gateways.
Alternatives considered
- Change the gateway to accept Bearer authentication: ideal when the gateway is under the ASSERT user's control, but unavailable for many enterprise or third-party gateways.
- Use the Azure provider route instead: only works when the gateway exposes Azure-native
/openai/deployments/{deployment} routes. Some gateways expose models exclusively through the OpenAI-compatible /v1 router.
- Patch LiteLLM from the embedding application: works as a local workaround but depends on ASSERT's private payload builders and has to be maintained by every integrator.
- Put headers or credentials directly in evaluation YAML: risks leaking secrets into configs and artifacts and duplicates configuration across stages.
- Run a separate LiteLLM proxy: adds an operational component solely to translate one authentication header.
Use case context
This applies to production, spec-driven evaluations using hosted models for systematization, test generation, user simulation, and judging. In a verified OpenAI-compatible gateway setup, model discovery, normal chat, and structured JSON generation all succeeded when the required api-key header was present; Bearer-only requests returned 401.
The evaluated target can still be a callable or traced agent. This request concerns the infrastructure models ASSERT itself uses to build and judge the evaluation.
Acknowledgements
Problem you're trying to solve
ASSERT uses LiteLLM's
openai/*provider for OpenAI-compatible endpoints. LiteLLM sendsOPENAI_API_KEYas standard Bearer authentication, but some API-management gateways require the same credential in an additional provider-specific header such asapi-keyorOcp-Apim-Subscription-Key.Today ASSERT has no supported configuration for this header. Model configuration covers the model name and generation parameters, but not gateway authentication headers. As a result, a gateway can successfully expose
/v1/modelsand/v1/chat/completionswhile ASSERT receives401 Unauthorizedbecause its request contains only Bearer authentication.This affects more than one call site:
assert-ai initA caller cannot solve this once through
eval_config.yamlor a CLI option, and embedding the secret directly in config would be unsafe.Proposed solution or behavior
Add an opt-in way to send
OPENAI_API_KEYunder a configurable compatibility-header name. One possible environment contract is:Expected behavior:
{<configured-name>: OPENAI_API_KEY}to LiteLLMextra_headersassert-ai init, and ACS calls.env.exampleand provider setup guidanceThe exact public name/API is open to maintainer preference; the important requirement is one safe, reusable configuration point for OpenAI-compatible gateways.
Alternatives considered
/openai/deployments/{deployment}routes. Some gateways expose models exclusively through the OpenAI-compatible/v1router.Use case context
This applies to production, spec-driven evaluations using hosted models for systematization, test generation, user simulation, and judging. In a verified OpenAI-compatible gateway setup, model discovery, normal chat, and structured JSON generation all succeeded when the required
api-keyheader was present; Bearer-only requests returned401.The evaluated target can still be a callable or traced agent. This request concerns the infrastructure models ASSERT itself uses to build and judge the evaluation.
Acknowledgements