Skip to content

fix(inference): add _enforce_credentials=False to passthrough AsyncOpenAI client - #6344

Merged
cdoern merged 1 commit into
ogx-ai:mainfrom
NickGagan:fix/passthrough-openai-credentials
Jul 27, 2026
Merged

fix(inference): add _enforce_credentials=False to passthrough AsyncOpenAI client#6344
cdoern merged 1 commit into
ogx-ai:mainfrom
NickGagan:fix/passthrough-openai-credentials

Conversation

@NickGagan

@NickGagan NickGagan commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Issue: #6343

What does this PR do?

Fixes a regression in the remote::passthrough inference provider that breaks all requests (model listing, inference, background refresh) on openai >= 2.34.0.

The passthrough provider hardcodes api_key="" when constructing its AsyncOpenAI client so that auth flows entirely through default_headers. This was valid when the project required openai>=2.30.0, but openai 2.34.0 added a constructor-level credentials enforcement check that raises Missing credentials when api_key is empty — before any headers are read or any request is made.

The regression was introduced in v1.1.0 when PR #6047 bumped the openai requirement from >=2.30.0 to >=2.41.0, silently crossing the 2.34.0 boundary where enforcement was introduced.

_enforce_credentials=False bypasses the constructor check without changing any auth behavior. It is available in all openai versions OGX currently requires (>=2.41.0).

The bug was invisible in the test suite because all tests that exercise _get_openai_client() mock AsyncOpenAI entirely, so the real SDK constructor — and its validation — never runs.

Impact without this fix:

  • GET /v1/models returns {"object":"list","data":[]} — exception caught silently, logged only at DEBUG
  • POST /v1/responses returns HTTP 500
  • Background model refresh fails silently — no models ever registered in the KV registry

Verified against quay.io/opendatahub/odh-ogx-core:latest (openai 2.46.0).

Test Plan

Start OGX with a passthrough provider configured against any OpenAI-compatible endpoint:

providers:
  inference:
  - provider_id: anthropic-passthrough
    provider_type: remote::passthrough
    config:
      base_url: https://api.anthropic.com
      api_key: "<ANTHROPIC_API_KEY>"
      refresh_models: true
registered_resources:
  models:
  - provider_id: anthropic-passthrough
    model_id: claude-haiku-4-5-20251001
    provider_model_id: claude-haiku-4-5-20251001
    model_type: llm

Before fix — POST /v1/responses returns 500:

curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'

Output:

{"detail":"An unexpected error occurred while generating the response."}
HTTP 500

Server log:

WARNING ogx.core.routing_tables.models:104 Model refresh failed
        error=Missing credentials. Please pass an `api_key`, `workload_identity`,
        `admin_api_key`, or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.

After fix — POST /v1/responses returns 200:

curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'

Output:

{
  "id": "resp_c0b3b7a8-476d-40c6-90bc-ae303378fa16",
  "object": "response",
  "model": "anthropic-passthrough/claude-haiku-4-5-20251001",
  "status": "completed",
  "output": [{"role": "assistant", "content": [{"type": "output_text", "text": "Hello!"}]}],
  "usage": {"input_tokens": 12, "output_tokens": 5, "total_tokens": 17}
}

Additional details:
passthrough-debug.txt

…enAI client

openai>=2.34.0 added a constructor-level credentials check that raises
'Missing credentials' when api_key is empty, before any request headers are
read. The passthrough provider uses api_key="" intentionally so that auth
flows entirely through default_headers, but this check fires before headers
are consulted.

_enforce_credentials=False bypasses the constructor check without changing
any auth behavior. It is available in all openai versions OGX requires
(>=2.41.0).

The regression was introduced in v1.1.0 when PR ogx-ai#6047 bumped the openai
requirement from >=2.30.0 to >=2.41.0, crossing the 2.34.0 boundary where
enforcement was introduced.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Nick Gagan <ngagan@redhat.com>
@skamenan7

Copy link
Copy Markdown
Collaborator

Thanks for fixing this @NickGagan . The change looks right, but can we add a regression test using the real AsyncOpenAI constructor? The current tests mock it, so this failure could come back without CI catching it.

@skamenan7 skamenan7 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment/nit.

Note for us, looks like we should also backport this to release-1.1.x

@cdoern

cdoern commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

@Mergifyio backport release-1.1.x release-1.2.x

@cdoern
cdoern added this pull request to the merge queue Jul 27, 2026
@mergify

mergify Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

backport release-1.1.x release-1.2.x

✅ Backports have been created

Details

Merged via the queue into ogx-ai:main with commit ebaaff8 Jul 27, 2026
58 checks passed
cdoern pushed a commit that referenced this pull request Jul 27, 2026
…enAI client (backport #6344) (#6365)

Issue: #6343

## What does this PR do?

Fixes a regression in the `remote::passthrough` inference provider that
breaks all requests (model listing, inference, background refresh) on
openai >= 2.34.0.

The passthrough provider hardcodes `api_key=""` when constructing its
`AsyncOpenAI` client so that auth flows entirely through
`default_headers`. This was valid when the project required
`openai>=2.30.0`, but openai 2.34.0 added a constructor-level
credentials enforcement check that raises `Missing credentials` when
`api_key` is empty — before any headers are read or any request is made.

The regression was introduced in v1.1.0 when [PR
#6047](#6047) bumped the openai
requirement from `>=2.30.0` to `>=2.41.0`, silently crossing the 2.34.0
boundary where enforcement was introduced.

`_enforce_credentials=False` bypasses the constructor check without
changing any auth behavior. It is available in all openai versions OGX
currently requires (>=2.41.0).

The bug was invisible in the test suite because all tests that exercise
`_get_openai_client()` [mock `AsyncOpenAI`
entirely](https://github.com/ogx-ai/ogx/blob/main/tests/unit/providers/inference/test_passthrough_forward_headers.py#L173),
so the real SDK constructor — and its validation — never runs.

**Impact without this fix:**
- `GET /v1/models` returns `{"object":"list","data":[]}` — exception
caught silently, logged only at DEBUG
- `POST /v1/responses` returns HTTP 500
- Background model refresh fails silently — no models ever registered in
the KV registry

Verified against `quay.io/opendatahub/odh-ogx-core:latest` (openai
2.46.0).

## Test Plan

Start OGX with a passthrough provider configured against any
OpenAI-compatible endpoint:

```yaml
providers:
  inference:
  - provider_id: anthropic-passthrough
    provider_type: remote::passthrough
    config:
      base_url: https://api.anthropic.com
      api_key: "<ANTHROPIC_API_KEY>"
      refresh_models: true
registered_resources:
  models:
  - provider_id: anthropic-passthrough
    model_id: claude-haiku-4-5-20251001
    provider_model_id: claude-haiku-4-5-20251001
    model_type: llm
```

**Before fix — POST /v1/responses returns 500:**

```bash
curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'
```

Output:
```
{"detail":"An unexpected error occurred while generating the response."}
HTTP 500
```

Server log:
```
WARNING ogx.core.routing_tables.models:104 Model refresh failed
        error=Missing credentials. Please pass an `api_key`, `workload_identity`,
        `admin_api_key`, or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.
```

**After fix — POST /v1/responses returns 200:**

```bash
curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'
```

Output:
```json
{
  "id": "resp_c0b3b7a8-476d-40c6-90bc-ae303378fa16",
  "object": "response",
  "model": "anthropic-passthrough/claude-haiku-4-5-20251001",
  "status": "completed",
  "output": [{"role": "assistant", "content": [{"type": "output_text", "text": "Hello!"}]}],
  "usage": {"input_tokens": 12, "output_tokens": 5, "total_tokens": 17}
}
```

Additional details: 

[passthrough-debug.txt](https://github.com/user-attachments/files/30361254/passthrough-debug.txt)

<hr>This is an automatic backport of pull request #6344 done by
[Mergify](https://mergify.com).

Signed-off-by: Nick Gagan <ngagan@redhat.com>
Co-authored-by: Nick Gagan <40474241+NickGagan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
cdoern pushed a commit that referenced this pull request Jul 27, 2026
…enAI client (backport #6344) (#6364)

Issue: #6343

## What does this PR do?

Fixes a regression in the `remote::passthrough` inference provider that
breaks all requests (model listing, inference, background refresh) on
openai >= 2.34.0.

The passthrough provider hardcodes `api_key=""` when constructing its
`AsyncOpenAI` client so that auth flows entirely through
`default_headers`. This was valid when the project required
`openai>=2.30.0`, but openai 2.34.0 added a constructor-level
credentials enforcement check that raises `Missing credentials` when
`api_key` is empty — before any headers are read or any request is made.

The regression was introduced in v1.1.0 when [PR
#6047](#6047) bumped the openai
requirement from `>=2.30.0` to `>=2.41.0`, silently crossing the 2.34.0
boundary where enforcement was introduced.

`_enforce_credentials=False` bypasses the constructor check without
changing any auth behavior. It is available in all openai versions OGX
currently requires (>=2.41.0).

The bug was invisible in the test suite because all tests that exercise
`_get_openai_client()` [mock `AsyncOpenAI`
entirely](https://github.com/ogx-ai/ogx/blob/main/tests/unit/providers/inference/test_passthrough_forward_headers.py#L173),
so the real SDK constructor — and its validation — never runs.

**Impact without this fix:**
- `GET /v1/models` returns `{"object":"list","data":[]}` — exception
caught silently, logged only at DEBUG
- `POST /v1/responses` returns HTTP 500
- Background model refresh fails silently — no models ever registered in
the KV registry

Verified against `quay.io/opendatahub/odh-ogx-core:latest` (openai
2.46.0).

## Test Plan

Start OGX with a passthrough provider configured against any
OpenAI-compatible endpoint:

```yaml
providers:
  inference:
  - provider_id: anthropic-passthrough
    provider_type: remote::passthrough
    config:
      base_url: https://api.anthropic.com
      api_key: "<ANTHROPIC_API_KEY>"
      refresh_models: true
registered_resources:
  models:
  - provider_id: anthropic-passthrough
    model_id: claude-haiku-4-5-20251001
    provider_model_id: claude-haiku-4-5-20251001
    model_type: llm
```

**Before fix — POST /v1/responses returns 500:**

```bash
curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'
```

Output:
```
{"detail":"An unexpected error occurred while generating the response."}
HTTP 500
```

Server log:
```
WARNING ogx.core.routing_tables.models:104 Model refresh failed
        error=Missing credentials. Please pass an `api_key`, `workload_identity`,
        `admin_api_key`, or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.
```

**After fix — POST /v1/responses returns 200:**

```bash
curl -s -X POST http://localhost:8323/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"model":"anthropic-passthrough/claude-haiku-4-5-20251001","input":"Say hello","stream":false}'
```

Output:
```json
{
  "id": "resp_c0b3b7a8-476d-40c6-90bc-ae303378fa16",
  "object": "response",
  "model": "anthropic-passthrough/claude-haiku-4-5-20251001",
  "status": "completed",
  "output": [{"role": "assistant", "content": [{"type": "output_text", "text": "Hello!"}]}],
  "usage": {"input_tokens": 12, "output_tokens": 5, "total_tokens": 17}
}
```

Additional details: 

[passthrough-debug.txt](https://github.com/user-attachments/files/30361254/passthrough-debug.txt)

<hr>This is an automatic backport of pull request #6344 done by
[Mergify](https://mergify.com).

Signed-off-by: Nick Gagan <ngagan@redhat.com>
Co-authored-by: Nick Gagan <40474241+NickGagan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants