Skip to content

fix(cli): persist Anthropic auth header format during setup - #1158

Merged
BrianNewsom merged 2 commits into
mainfrom
fix-anthropic-setup-auth/brnewsom
Aug 7, 2026
Merged

fix(cli): persist Anthropic auth header format during setup#1158
BrianNewsom merged 2 commits into
mainfrom
fix-anthropic-setup-auth/brnewsom

Conversation

@BrianNewsom

@BrianNewsom BrianNewsom commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

nemo setup currently stores Anthropic's X-Api-Key template in required_extra_headers, where it remains the literal string {{ auth_secret }} and Anthropic rejects every request. This change persists the existing provider definition's auth_header_format field on both create and update, so the inference gateway renders the secret at request time; default Bearer-auth providers are unchanged.

Changes

  • Pass the provider definition's auth_header_format through setup provider create and update calls.
  • Repair existing Anthropic providers by explicitly clearing legacy required_extra_headers when interactive or automatic setup is rerun.
  • Add create, interactive-update, auto-update, and raw-key non-disclosure regression coverage.
  • Regenerate the vendored NeMo Platform SDK source and tests.
  • Keep the fix scoped to setup: no Models or inference-gateway implementation changes.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with documentation updates
  • Documentation only
  • Contributor tooling or automation
  • CI, build, or test infrastructure

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Documentation updated for user-visible behavior
  • Documentation not applicable — justification: the supported Anthropic provider command and auth_header_format behavior are already documented; this fixes nemo setup to follow that contract.

Verification

  • Pull request title follows the repository's Conventional Commit format
  • Every commit includes an appropriate Signed-off-by: trailer
  • uv run pre-commit run -a passes, or any blocked checks are identified below
  • Targeted tests pass, or tests are marked not applicable above
  • No secrets, API keys, or credentials are included

Targeted validation on current head (242b66df17):

uv run --frozen pytest \
  packages/nemo_platform_ext/tests/cli/commands/test_setup.py -v
# 217 passed

uv run --frozen pytest \
  sdk/python/nemo-platform/tests/vendored/nemo_platform_ext/cli/commands/test_setup.py -v
# 217 passed

uv run ruff check \
  packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py \
  packages/nemo_platform_ext/tests/cli/commands/test_setup.py
# passed

uv run ruff format --check \
  packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py \
  packages/nemo_platform_ext/tests/cli/commands/test_setup.py
# passed

uv run --frozen ty check \
  packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py
# passed

uv run --frozen pre-commit run -a
# all hooks passed

make vendor-nemo-platform-ext
# completed; expected source and test copies regenerated

git diff --check
# passed

Live reproduction on origin/main before the fix

Prerequisites: a local Platform at http://localhost:8080 and a valid ANTHROPIC_API_KEY exported in the shell. I used an isolated workspace and removed other provider credential variables from the repro shell so automatic setup selected Anthropic.

export NMP_BASE_URL=http://localhost:8080
export REPRO_WORKSPACE=anthropic-auth-repro
unset NVIDIA_API_KEY OPENAI_API_KEY GEMINI_API_KEY
test -n "$ANTHROPIC_API_KEY"

uv run nemo setup --auto \
  --workspace "$REPRO_WORKSPACE" \
  --no-start-services \
  --no-install-skills \
  --no-deploy-agent

uv run nemo inference providers get anthropic \
  --workspace "$REPRO_WORKSPACE" \
  --output-format json \
  | jq '{auth_header_format, required_extra_headers, default_extra_headers}'

Observed provider state:

{
  "auth_header_format": null,
  "required_extra_headers": {"X-Api-Key": "{{ auth_secret }}"},
  "default_extra_headers": {"anthropic-version": "2023-06-01"}
}

A real Anthropic Messages request through the provider route then failed:

curl --fail-with-body --silent --show-error \
  -X POST \
  "${NMP_BASE_URL}/apis/inference-gateway/v2/workspaces/${REPRO_WORKSPACE}/provider/anthropic/-/v1/messages" \
  -H 'Accept-Encoding: identity' \
  -H 'Content-Type: application/json' \
  -d '{"model":"claude-sonnet-4-5-20250929","max_tokens":8,"messages":[{"role":"user","content":"Reply with OK."}]}'

Observed result: Platform HTTP 502 wrapping Anthropic HTTP 401 authentication_error: invalid x-api-key.

Live verification after the fix

Rerunning the same setup command updated the existing secret and provider. On a second clean Platform instance created from origin/main, the fixed CLI also created the provider successfully from scratch.

uv run nemo setup --auto \
  --workspace "$REPRO_WORKSPACE" \
  --no-start-services \
  --no-install-skills \
  --no-deploy-agent

uv run nemo inference providers get anthropic \
  --workspace "$REPRO_WORKSPACE" \
  --output-format json \
  | jq '{auth_header_format, required_extra_headers, status, served_models: (.served_models | length)}'

Observed provider state after reconciliation:

{
  "auth_header_format": "X-Api-Key: {{ auth_secret }}",
  "required_extra_headers": null,
  "status": "READY",
  "served_models": 10
}

The real Anthropic Messages request then succeeded:

curl --fail-with-body --silent --show-error \
  -X POST \
  "${NMP_BASE_URL}/apis/inference-gateway/v2/workspaces/${REPRO_WORKSPACE}/provider/anthropic/-/v1/messages" \
  -H 'Accept-Encoding: identity' \
  -H 'Content-Type: application/json' \
  -d '{"model":"claude-haiku-4-5-20251001","max_tokens":8,"messages":[{"role":"user","content":"Reply with OK."}]}' \
  | jq '{type, role, model, stop_reason, text: .content[0].text, error}'

Observed HTTP 200 response:

{
  "type": "message",
  "role": "assistant",
  "model": "claude-haiku-4-5-20251001",
  "stop_reason": "end_turn",
  "text": "OK.",
  "error": null
}

The real key was loaded locally from the existing environment and was never printed, logged, written to a tracked file, or included in this pull request. Setup sent the raw value only to the Secrets service; provider create/update received the secret name plus the inert X-Api-Key: {{ auth_secret }} template.

Summary by CodeRabbit

  • Bug Fixes
    • Improved provider setup and updates for Anthropic authentication.
    • Authentication header formats are now handled correctly during interactive and automatic registration.
    • API keys remain protected while secret bindings and default headers are preserved.
    • Provider registrations now maintain consistent authentication settings when created or updated.
    • Existing provider configurations are updated without exposing sensitive credentials.

Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
@github-actions github-actions Bot added the fix label Aug 7, 2026
@BrianNewsom
BrianNewsom marked this pull request as ready for review August 7, 2026 05:19
@BrianNewsom
BrianNewsom requested review from a team as code owners August 7, 2026 05:19
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Provider creation and update flows now send auth_header_format directly to the platform API. Registration paths pass the value through. Tests verify header handling, secret binding, default headers, and API-key redaction.

Changes

Provider authentication payload

Layer / File(s) Summary
Authentication template propagation
packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py
Provider creation and update flows pass auth_header_format directly to the platform API. Interactive and automatic registration include the value when updating providers.
Authentication payload validation
packages/nemo_platform_ext/tests/cli/commands/test_setup.py
Tests verify direct template persistence, omitted required_extra_headers, preserved secret bindings and default headers, and API-key redaction.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: persisting Anthropic auth header format during CLI setup.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-anthropic-setup-auth/brnewsom

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 31443/40067 78.5% 63.0%
Integration Tests 18305/38019 48.1% 20.8%

@tylersbray tylersbray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. All the verification is nice. Agent found this little bit of feedback:

Non-blocking: consider explicitly sending required_extra_headers=None on Anthropic provider update so repair intent does not depend on PUT defaulting omitted fields to null.

Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
@BrianNewsom

Copy link
Copy Markdown
Contributor Author

LGTM. All the verification is nice. Agent found this little bit of feedback:

Non-blocking: consider explicitly sending required_extra_headers=None on Anthropic provider update so repair intent does not depend on PUT defaulting omitted fields to null.

Good suggestion, updated this.

@BrianNewsom
BrianNewsom added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 81dc2b8 Aug 7, 2026
56 checks passed
@BrianNewsom
BrianNewsom deleted the fix-anthropic-setup-auth/brnewsom branch August 7, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants